大作业blog

一、前言

  1. 知识点:printf和println,next和nextLine,length和length()等的区别
    substring、equals、charAt、Arrays.sort、set,list等的用法
    快输、接口(Collections.sort)、日期类LocalDate等的使用
  2. 题量:逐渐增大,但通过自主学习大部分还可以解决。
  3. 难度:逐渐上涨,越来越崩.......

二、设计与分析

  • 菜单题统一放到最后面

第一次作业

7-1 身体质量指数(BMI)测算

体重是反映和衡量一个人健康状况的重要标志之一,过胖和过瘦都不利于健康,BMI(身体质量指数)计算方法:体重(以千克为单位)除以身高(以米为单位)的平方。中国成人正常的BMI应在18.5-24之间,如果小于18.5为体重不足,如果大于等于24为超重,大于等于28为肥胖。请编写程序,测算身体状态。

输入格式:

两个数值:体重(以千克为单位),身高(以米为单位),数值间以空格分隔。例如:65.5 1.75。
注意:体重的世界纪录是727公斤,身高的世界纪录是2.72米。输入数据上限不得超过纪录,下限不得小于等于0;

输出格式:

输入数值超出范围 :输出“input out of range”。例如:-2 3或者125 5。
BMI小于18.5 :输出“thin”。
BMI大于等于18.5小于24 :输出“fit”。
BMI大于等于24小于28 :输出“overweight”。
BMII大于等于28 :输出“fat”。

输入样例0:

在这里给出一组输入。例如:

-2  8

输出样例0:

在这里给出相应的输出。例如:

input out of range

输入样例1:

在这里给出一组输入。例如:

70 1.75

输出样例1:

在这里给出相应的输出。例如:

fit

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
        double w=scan.nextDouble();
        double h=scan.nextDouble();
        double b=w/h/h;
        if((w>727||w<0)||(h>2.72||h<0))
             System.out.println("input out of range");
        else
        {
        if(b<18.5)
            System.out.println("thin");
        if(b>=18.5&&b<24)
            System.out.println("fit");
        if(b>=24&&b<28)
            System.out.println("overweight");
        if(b>=28)
            System.out.println("fat");
        }
    }
}

分析:这段代码接受用户输入的身高和体重,计算BMI指数并输出相应的体型评价。

首先,代码使用Java标准库中的Scanner类来获取用户输入。它要求用户先输入体重(以千克为单位),然后再输入身高(以米为单位)。

接下来,代码计算BMI指数(即体重除以身高的平方),并将其保存在变量b中。根据BMI指数的不同范围,代码输出不同的体型评价。

在代码中,有一个条件判断语句,如果用户输入的身高或体重超出了指定的范围,则输出"input out of range"。这个条件判断语句使用了逻辑运算符"||"(或),表示只要其中一个条件成立,整个表达式就为真。

最后,代码使用System.out.println()方法输出相应的体型评价。

心得:对Java语法有了初步认识,明白了输入输出如何使用。

7-2 长度质量计量单位换算

长度、质量的计量有多重不同的计算体系,有标准的国际单位制:千克与米,也有各个国家自己的计量方法如:磅、英寸;1磅等于0.45359237千克,1英寸等于0.0254米,请编写程序实现国际单位制与英制之间的换算。

输入格式:

两个浮点数,以空格分隔,第一个是质量(以千克为单位)、第二个是长度(以米为单位)。例如:0.45359237 0.0254。

输出格式:

两个浮点数,以空格分隔,第一个是质量(以磅为单位)、第二个是长度(以英寸为单位)。例如:1.0 1.0。

输入样例:

在这里给出一组输入。例如:

0.45359237 0.0254

输出样例:

在这里给出相应的输出。例如:

1.0 1.0

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
        double w=scan.nextDouble();
        double h=scan.nextDouble();
        double a=w/0.45359237;
        double b=h/0.0254;
         System.out.printf((float)a+" "+(float)b);
    }

分析:首先,代码使用Java标准库中的Scanner类来获取用户输入。它要求用户先输入体重(以千克为单位),然后再输入身高(以米为单位)。

接下来,代码将输入的体重和身高分别除以相应的转换系数,得到它们在英制单位下的值,然后将它们分别保存在变量a和b中。

最后,代码使用System.out.printf()方法将变量a和b输出到。

心得:对System.out.printf()方法有了初步认识。

7-3 奇数求和

计算一个数列中所有奇数的和。

输入格式:

十个整数,以空格分隔。例如:1 2 3 4 5 6 7 8 9 0。

输出格式:

输入数列中所有奇数之和。例如:25。

输入样例:

在这里给出一组输入。例如:

1 2 3 4 5 6 7 8 9 0

输出样例:

在这里给出相应的输出。例如:

25

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        int sum=0;
        Scanner scan=new Scanner(System.in);
        for(int i=0;i<10;i++)
        {
            int n=scan.nextInt();
            if(n%2!=0)
                sum+=n;
        }
        System.out.println(sum);
    }
}

分析:这段Java代码用于接受用户输入的十个整数,并计算其中的奇数之和。

首先,代码定义了一个变量sum,用于存储奇数之和。接下来,代码使用Java标准库中的Scanner类来获取用户输入。

然后,代码使用for循环来读取用户输入的十个整数,将它们保存在变量n中。如果n是奇数(即n%2!=0),则将它加入到sum中。

最后,代码使用System.out.println()方法输出sum的值,即所有奇数的和。

7-4 房产税费计算2022

房屋交易在日常生活中非常常见的事情,房屋交易时要额外支付各种税费,按2022年房产交易新政策的规定买房人应缴纳税费包括:

1、契税:首次购房评估额90平(含)内1%、90平-144平(含)内1.5%,超过144平或非首 次3%,买方缴纳。

2、印花税:房款的0.05%。

3、交易费:3元/平方米。

4、测绘费:1.36元/平方米。

5、权属登记费及取证费:一般情况是在200元内。

输入格式:

四个数据,以空格分隔:
1、第几次购房(整数)
2、房款(整数/单位万元)
3、评估价(整数/单位万元)
4、房屋面积(浮点数/单位平方米)。
例如:1 100 100 90。

输出格式:

契税、印花税、交易费、测绘费(以元为单位),以空格分隔。例如:10000.0 500.0 270.0 122.4

输入样例:

在这里给出一组输入。例如:

1 100 100 90

输出样例:

在这里给出相应的输出。例如:

10000.0 500.0 270.0 122.4

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
            double qi=0;
            int c=scan.nextInt();
            int fk=scan.nextInt()*10000;
            int pg=scan.nextInt()*10000;
            double mj=scan.nextDouble();
            if(c==1)
            {
                if(mj>0&&mj<=90)
                    qi=pg*0.01;
                if(mj>90&&mj<=144)
                    qi=pg*0.015;
                if(mj>144)
                    qi=pg*0.03;
            }
            else
                   qi=pg*0.03;
            double yh=0.0005*fk;
            double jy=3*mj;
            double hc=1.36*mj;
        System.out.println((float)qi+" "+(float)yh+" "+(float)jy+" "+(float)hc);
    }
}

分析: 程序用于计算房屋交易时需要缴纳的契税、印花税、交易费、测绘费等税费,根据输入的购房信息和面积进行计算,并将结果以空格分隔的形式输出。

程序的主体部分在 main 函数中,首先创建了一个 Scanner 对象,用于从标准输入中读取数据。然后读入四个整数和一个浮点数,分别表示购房次数、房款、评估价和房屋面积。

根据购房次数和评估价的大小,计算契税,否则按非首次购房的标准计算。印花税、交易费和测绘费的计算分别采用了固定的比例和单价。最后将四个税费结果输出。

心得:首先还是注意要赋初始,然后要注意*10000。

7-5 游戏角色选择

一款网游中包括4个种族:人类、精灵、兽人、暗精灵,每个种族包含三种角色:战士、法师、射手。玩家新建人物时需要选择种族和角色。请编写角色选择程序。

输入格式:

两个整数:游戏种族、角色的选项,以空格分隔。例如:1 2。
种族选项设定为:1、人类 2、精灵 3、兽人 4、暗精灵
角色选项设定为:1、战士 2、法师 3、射手

输出格式:

所选择的种族、角色的名称,以空格分隔。例如:人类 法师
若输入数值超出选项范围,输出“Wrong Format”

输入样例1:

在这里给出一组输入。例如:

1 2

输出样例1:

在这里给出相应的输出。例如:

人类 法师

输入样例2:

在这里给出一组输入。例如:

1 6

输出样例2:

在这里给出相应的输出。例如:

Wrong Format

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
        int x=scan.nextInt();
        int y=scan.nextInt();
        String a="0",b="0";
        if(x<=0||x>4||y<=0||y>3)
            System.out.println("Wrong Format");
        else
        {
        if(x==1)
        a="人类";
        if(x==2)
        a="精灵";
        if(x==3)
        a="兽人";
        if(x==4)
        a="暗精灵";
        if(y==1)
        b="战士";
        if(y==2)
        b="法师";
        if(y==3)
        b="射手";
        System.out.println(a+" "+b);
        }
    }
}

分析:这段代码实现了一个简单的游戏角色选择功能。用户需要输入两个整数,分别代表选择的种族和职业,程序根据输入的数字输出对应的角色种族和职业名称。

首先,代码使用 Scanner 类从标准输入中读取用户输入的两个整数。然后,程序对输入进行检查,如果输入的数字不在规定范围内,输出错误信息"Wrong Format",否则根据输入的数字选择对应的种族和职业名称并输出。

具体实现方式是使用 if-else 条件语句,根据输入的数字对应地给两个字符串变量 a 和 b 赋值,然后输出这两个变量的值。需要注意的是,当输入的数字为 1、2、3、4 时,分别对应 "人类"、"精灵"、"兽人"、"暗精灵",而当输入的数字为 1、2、3 时,分别对应 "战士"、"法师"、"射手"。

心得:定义变量要赋初值,选择语句是两个等号。

7-6 学号识别

学校的学号由8位数字组成,前两位是入学年份(省略了20);第3、4位是学院编号,01代表材料学院,02代表机械学院,03代表外语学院,20代表软件学院;第5、6位是学院内部班级编号,最后两位是班级内部学号。如:18011103,入学年份是2018年,材料学院,11班,03号

输入格式:

8位数字组成的学号。例如:18011103
注意:输入学号不是8位或者学院编号不是01、02、03、20其中之一,属于非法输入

输出格式:

学号每一项的完整说明。例如:
入学年份:2018年
学院:材料学院
班级:11
学号:03

注意:如非法输入,输出“Wrong Format"

输入样例:

在这里给出一组输入。例如:

18011103

输出样例:

在这里给出相应的输出。例如:

入学年份:2018年
学院:材料学院
班级:11
学号:03

输入样例1:

在这里给出一组输入。例如:

18013

输出样例1:

在这里给出相应的输出。例如:

Wrong Format

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
        String xx=scan.next();
        String nf,xy,bj,xh;
        if(xx.length()!=8)
        {
            System.out.println("Wrong Format");
            return;
        }
        nf=xx.substring(0,2);
        xy=xx.substring(2,4);
        bj=xx.substring(4,6);
        xh=xx.substring(6,8);
        if(xx.length()!=8)
        {
            System.out.println("Wrong Format");
            return;
        }
         if(xy.equals("01"))
             xy="材料学院";
         else if(xy.equals("02"))
             xy="机械学院";
         else if(xy.equals("03"))
             xy="外语学院";
         else if(xy.equals("20"))
             xy="软件学院";
        else 
        {
            System.out.println("Wrong Format");
            return;
        }
            System.out.println("入学年份:20"+nf+"年\n学院:"+xy+"\n"+"班级:"+bj+"\n"+"学号:"+xh);
    }
}

分析:该代码用于读入一个8位字符串,解析其中的信息,并按特定格式输出。代码中使用了Scanner类来实现读入操作。

程序首先读入一个8位字符串,如果其长度不为8,则输出“Wrong Format”并结束程序。接下来,程序将字符串中的前两位解析为入学年份(nf),接下来的两位解析为学院(xy),再接下来的两位解析为班级(bj),最后两位解析为学号(xh)。

程序使用了Java的字符串处理函数substring()来从字符串中提取子串。具体而言,代码使用了4个字符串变量来保存提取出的4个子串,即`nf、xy、bj和xh。根据xy的取值不同,程序将其转换为相应的学院名称。最后,程序按照特定格式输出解析出的信息。

心得:知道了length和length()的区别,substring、equals的用法。

7-8 巴比伦法求平方根近似值

巴比伦法求n的近似值可以用以下公式:
nextGuess = (lastGuess+n/lastGuess)/2
程序初始运行时lastGuess可赋予一个最初的猜测值。当由公式求得的nextGuess和lastGuess相差较大时,把nextGuess的值赋给lastGuess,继续以上过程,直至nextGuess和lastGuess几乎相同,此时lastGuess或者nextGuess就是平方根的近似值。
本题要求:nextGuess和lastGuess的差值小于0.00001时认为两者几乎相同

输入格式:

1、两个浮点数,以空格分隔,第一个是n,第二个是lastGuess最初的猜测值。例如:2 1。
2、若输入的两个数中包含负数或者lastGuess初始输入为0,认定为非法输入

输出格式:

1、输出n的平方根近似值:lastGuess。例如:1.4142157
2、非法输入时输出:"Wrong Format"

输入样例:

在这里给出一组输入。例如:

2 1

输出样例:

在这里给出相应的输出。例如:

1.4142157

输入样例1:

在这里给出一组输入1。例如:

2 -1

输出样例:

在这里给出相应的输出。例如:

Wrong Format

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[]args)
    {
        Scanner scan=new Scanner(System.in);
        float n=scan.nextFloat();
        float lastGuess=scan.nextFloat();
        float nextGuess=0;
        if(n<0||lastGuess<=0)
            System.out.println("Wrong Format");
        else
        {
            nextGuess=(lastGuess+n/lastGuess)/2;
            while(Math.abs(nextGuess-lastGuess)>=0.00001)
            {
                lastGuess=nextGuess;
                nextGuess=(lastGuess+n/lastGuess)/2;
            }
            System.out.println(lastGuess);
        }
    }
}

分析:这段代码实现了求解一个数的平方根的功能。具体实现过程如下:

通过Scanner类从控制台读入两个浮点数n和lastGuess,其中n表示要求解平方根的数,lastGuess是一个初始的猜测值。
对于特殊情况,如n小于0或者lastGuess小于等于0,输出“Wrong Format”表示格式不正确。
如果n和lastGuess都合法,就计算出下一个猜测值nextGuess,根据求平方根的公式:nextGuess=(lastGuess+n/lastGuess)/2
进入while循环,每次迭代更新lastGuess和nextGuess,直到两者之差小于0.00001为止。
循环结束后输出lastGuess,即为求得的平方根。
心得:定义变量最好都要初始化,看好输出再用float还是double。

7-9 二进制数值提取

在一个字符串中提取出其中的二进制数值序列,。

输入格式:

一个由0、1构成的序列,以-1为结束符,非0、1字符视为正常输入,但忽略不计,未包含结束符的序列视为非法输入。例如:abc00aj014421-1

输出格式:

将输入的序列去掉非0、1字符以及结尾符的数据内容,
注:结束符-1之后的0\1字符忽略不计。
例如:00011。

输入样例:

在这里给出一组输入。例如:

abc00aj014421-1

输出样例:

在这里给出相应的输出。例如:

00011

输入样例1:

在这里给出一组输入。例如:

a0571-1k001y

输出样例1:

在这里给出相应的输出。例如:

01

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[]args)
    {
        Scanner scan=new Scanner(System.in);
        String num=scan.nextLine();
        String s="";
        for(int i=0;i<num.length();i++)
        {
            if(num.charAt(i)=='0'||num.charAt(i)=='1')
                s+=num.charAt(i);//不要两层if语句
             if(num.charAt(i)=='-'&&num.charAt(i+1)=='1')
             {
                 System.out.println(s);
                 return;//!!
             }
        }
        System.out.println("Wrong Format");
    }
}

分析:这段代码是一个字符串处理程序,输入一个字符串num,包含0、1和-1,输出字符串中的所有0和1,直到遇到-1停止。如果输入格式不正确,输出"Wrong Format"。

这里主要使用了字符串操作和流程控制语句。

首先使用Scanner类读入一个字符串num。

然后,定义一个字符串s,用于存储num中的0和1。

接着,通过for循环遍历num中的每个字符,如果字符是0或1,则将其添加到s中,否则,如果字符是-,并且其后面的字符是1,那么输出s并结束程序。

最后,如果程序执行到了这里,说明输入格式不正确,输出"Wrong Format"。

心得:next和nextLine是不一样的,有空格就用后者;赋初值;.charAt()在for循环中非常重要,最开始的时候写顺手了就写了两层if,但两个条件其实并不是包含关系,最后当只想有一个输出的话一定要加上return;

7-7 判断三角形类型

输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。

输入样例1:

在这里给出一组输入。例如:

50 50 50.0

输出样例1:

在这里给出相应的输出。例如:

Equilateral triangle

输入样例2:

在这里给出一组输入。例如:

60.2 60.2 80.56

输出样例2:

在这里给出相应的输出。例如:

Isosceles triangle

输入样例3:

在这里给出一组输入。例如:

0.5 20.5 80

输出样例3:

在这里给出相应的输出。例如:

Wrong Format

源码如下:

import java.util.Scanner;
public class Main
{
    public static void main(String[] args)
    {
        Scanner scan=new Scanner(System.in);
        double x=scan.nextDouble();
        double y=scan.nextDouble();
        double z=scan.nextDouble();
        if(x<1||x>200||y<1||y>200||z<1||z>200)
        {
            System.out.println("Wrong Format");
            return;
        }
        if(x+y<=z||x+z<=y||y+z<=x)
        {
            System.out.println("Not a triangle");
            return;
        }
            if(x*x+y*y-z*z<0.01||x*x+z*z-y*y<0.01||y*y+z*z-x*x<0.01)//
            {
                if(x==y||x==z||y==z)
                System.out.println("Isosceles right-angled triangle");
                else
                System.out.println("Right-angled triangle");
            }
            else if(x==y||x==z||y==z)
            {
                if(x==y&&y==z)
                System.out.println("Equilateral triangle");
                else
                System.out.println("Isosceles triangle");
            }
            else
                System.out.println("General triangle");
    }
}

分析:这段代码是一个用于判断三角形类型的程序,首先通过Scanner获取三角形三条边的长度,并对输入的边长进行范围检查,如果不在1-200的范围内则输出"Wrong Format"并退出程序。接下来的代码块对三条边长进行三角形合法性的检查,如果不满足三角形的定义则输出"Not a triangle"并退出程序。

接下来的代码块通过判断勾股定理和三角形边长的关系来判断三角形的类型,输出相应的结果,如果三边都相等则输出"Equilateral triangle",如果有两边相等则输出"Isosceles triangle",如果没有边相等则输出"General triangle"。如果三角形是等腰直角三角形则输出"Isosceles right-angled triangle",如果是一般的直角三角形则输出"Right-angled triangle"。

心得:无理数是除不尽的,与浮点数有区别,所以勾股定理会有误差,所以要小于0.01。

if(x*x+y*y-z*z<0.01||x*x+z*z-y*y<0.01||y*y+z*z-x*x<0.01)

第二次作业

7-4 小明走格子

从A点到B点有n个格子,小明现在要从A点到B点,小明吃了些东西,补充了一下体力,他可以一步迈一个格子,也可以一步迈两个格子,也可以一步迈3个格子,也可以一步迈4个格子。请编写程序计算小明从A点到B点一共有多少种走法。

grid2.jpg

输入格式:

输入包含多组数据,第一行为一个整数m,m不超过10000,表示输入数据组数。接下来m行,每行为一个整数n(保证对应的输出结果小于231),表示从A点到B点的格子数。

输出格式:

输出为m个整数,表示对于每组数据小明从A点到B点的走法数。

输入样例:

2
5
3

输出样例:

15
4

源码如下:

import java.io.*;
public class Main
{
    public static void main(String[] args) throws IOException
    {
        StreamTokenizer scan = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        scan.nextToken();
        int m=(int)scan.nval;
        int i,j;
        int [] a=new int[1001000];
        int [] s=new int[200000];
        for(i=0;i<m;i++)
        {
            scan.nextToken();
            a[i]=(int)scan.nval;
        }
        s[0]=1; s[1]=1; s[2]=2;s[3]=4; s[4]=8;
        for(i=0;i<m;i++)
        {
            if(a[i]<5)
            {
                pw.println(s[a[i]]);
                pw.flush();
            }
            else
            {
                for(j=5;j<=a[i];j++)
	            s[j]=s[j-1]+s[j-2]+s[j-3]+s[j-4];
                pw.println(s[a[i]]);
                pw.flush();
            }
        }
    }
}

分析:这段代码是一个计算斐波那契数列变形的算法,它使用了动态规划的思想来计算小明从A点到B点一共有多少种走法。其中,s[i]表示从A点到第i个格子一共有多少种走法。当i小于等于4时,可以直接使用数组s的预先计算值,即1, 1, 2, 4, 8;当i大于4时,可以使用递推公式s[i] = s[i-1] + s[i-2] + s[i-3] + s[i-4]来计算s[i]的值。

需要注意的是,程序使用了一些 Java I/O 类库中的类和方法,例如 StreamTokenizer、PrintWriter、BufferedReader、InputStreamReader、BufferedWriter 和 OutputStreamWriter 等。这些类和方法的作用是对输入输出流进行封装,使得程序能够更方便地进行输入输出操作。

心得:这道题公式很好找,但重点还是在快输上,当时还是不知道快输这个概念,在CSDN搜了半天也就这一个还能用,就暗自和他许定终身,现在用起来能节约不少运行时间。

第三次作业

7-2 有重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。

输入格式:

你的程序首先会读到一个正整数n,n∈[1,100000],然后是n个整数。

输出格式:

如果这些整数中存在重复的,就输出:

YES

否则,就输出:

NO

输入样例:

5
1 2 3 1 4

输出样例:

YES

代码如下:

import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
public class Main
{
    public static void main(String[] args) throws IOException
    {
        StreamTokenizer scan = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        scan.nextToken();
        int n=(int)scan.nval;
        int[] nums = new int[n];
        for (int i = 0; i < n; i++)
        {
            scan.nextToken();
            nums[i] = (int)scan.nval;
        }
        Arrays.sort(nums);
        boolean hasDuplicate = false;
        for (int i = 1; i < n; i++) 
        {
            if (nums[i] == nums[i - 1]) 
            {
                hasDuplicate = true;
                break;
            }
        }
        if (hasDuplicate)
        {
            pw.print("YES");pw.flush();
        } 
        else 
        {
            pw.print("NO");pw.flush();
        }
    }
}

分析:这是一个 Java 程序,其主要功能是从标准输入读取一组整数,然后判断这组整数中是否存在重复元素。如果存在,则程序输出 "YES",否则输出 "NO"。

代码的具体实现方式是:首先使用 StreamTokenizer 对标准输入进行解析,读取一个整数 n 表示输入数据的个数,然后依次读取 n 个整数并存储到一个数组 nums 中。接下来使用 Arrays.sort 方法对 nums 数组进行从小到大排序,然后依次遍历 nums 数组中的元素,如果存在连续两个元素相等,则说明存在重复元素,将 hasDuplicate 标志位设为 true。最后根据 hasDuplicate 的值输出相应的结果。

需要注意的是,程序使用了一些 Java I/O 类库中的类和方法,例如 StreamTokenizer、PrintWriter、BufferedReader、InputStreamReader、BufferedWriter 和 OutputStreamWriter 等。这些类和方法的作用是对输入输出流进行封装,使得程序能够更方便地进行输入输出操作。

心得:这道题就很离谱,我第一次用set写,最后比较长度,最后一个测试点一直过不去,有人说用快输,用了也没过,但是第二题,没用快输,照样很顺利通过了,第一题写了好几遍用了好多方法才过,我也不知道为什么。这道题首先使用了快输,用我这个的人还是很少的,但毕竟是我学会的第一个快输,用起来也没什么问题,就用到了现在,输入输出各两条语句其实挺不好记的,但到时候复制粘贴一下就行。进行排序也是为了节约一下时间,怕超时

7-3 去掉重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,去掉所有重复的数字。最后按照输入顺序输出没有重复数字的数据。所有重复的数字只保留第一次出现的那份。

输入格式:

你的程序首先会读到一个正整数 n,1≤n≤100000。
然后是 n 个整数,这些整数的范围是 [1, 100000]。

输出格式:

在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格。

输入样例:

5
1 2 2 1 4

输出样例:

1 2 4

源码如下:

import java.util.Scanner;
import java.util.*;
public class Main
{
	public static void main(String[] args)
	{
		Scanner scan=new Scanner(System.in);
		Set<String> list = new LinkedHashSet<>();
        int flag=0;
        int n=scan.nextInt();
        String [] s=new String[100000];
        for(int i=0;i<n;i++)
        {
        	s[i]=scan.next();
        	list.add(s[i]);
        	
        }
        for(String num : list)
        {
        	if(flag==0)
        	{
        		System.out.print(num);//prinln自动换行
        		flag=1;
        	}
        	else
        	{
        		System.out.print(" "+num);
        	}
        }
    }
}

分析:程序主要功能是从标准输入读取一组字符串,然后去重并输出去重后的字符串列表。程序的具体实现方式是:

首先使用 Scanner 对标准输入进行解析,读取一个整数 n 表示输入数据的个数,然后依次读取 n 个字符串并存储到一个字符串数组 s 中。接下来使用 LinkedHashSet 对 s 数组进行去重操作,并将去重后的字符串存储到一个 list 集合中。

最后遍历 list 集合中的元素,逐个输出字符串并加上空格分隔符,同时使用一个 flag 标志位来判断当前是否是第一个字符串,如果是则不加空格分隔符。这样就能够输出去重后的字符串列表。

需要注意的是,程序中使用了一些 Java 集合类库中的类和方法,例如 Set、LinkedHashSet 等。这些类和方法的作用是对元素进行去重等操作,使得程序能够更方便地进行数据处理。

心得:简单了解了set的用法,知道set中不会有重复数据,LinkedHashSetHashSet 的子类,但暂时还没体现出什么区别,也知道直接输出列表会有框,所以要先遍历。

7-4 单词统计与排序

从键盘录入一段英文文本(句子之间的标点符号只包括“,”或“.”,单词之间、单词与标点之间都以" "分割。
要求:按照每个单词的长度高到低输出各个单词(重复单词只输出一次),如果单词长度相同,则按照单词的首字母顺序(不区分大小写,首字母相同的比较第二个字母,以此类推)升序输出。

输入格式:

一段英文文本。

输出格式:

按照题目要求输出的各个单词(每个单词一行)。

输入样例:

Hello, I am a student from China.

输出样例:

student
China
Hello
from
am
a
I

源码如下:

import java.util.*;
public class Main 
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        String[] words = input.split("[\\s,.]+");
        Set<String> uniqueWords = new HashSet<>(Arrays.asList(words));
        List<String> wordList = new ArrayList<>(uniqueWords);
        Collections.sort(wordList, new Comparator<String>() 
        {
            public int compare(String s1, String s2) 
            {
                int cmp = s2.length() - s1.length();
                if (cmp != 0) 
                {
                    return cmp;
                } 
                else
                {
                    return s1.compareToIgnoreCase(s2);
                }
            }
        });

        for (String word : wordList) 
        {
            System.out.println(word);
        }
    }
}

分析:程序主要功能是从标准输入读取一行字符串,然后对字符串中的单词进行去重、按照单词长度从大到小排序并输出排序后的单词列表。

程序的具体实现方式是:

首先使用 Scanner 对标准输入进行解析,读取一行字符串 input。接下来使用正则表达式 "[\s,.]+" 对 input 字符串进行分割,得到一个字符串数组 words,其中包含了所有的单词。然后使用 HashSet 对 words 数组进行去重操作,将去重后的单词存储到一个uniqueWords集合中。

接着使用 ArrayList 构造函数 ArrayList()uniqueWords 集合转换为一个列表 wordList,然后使用 Collections.sort 方法对 wordList 列表进行排序。排序时首先按照单词长度从大到小排序,如果长度相同则按照字典序进行排序。

最后遍历 wordList 列表中的元素,逐个输出单词即可。

心得:这道题很难,但让我简单了解到了接口和正则表达式这两个概念。

[\\s,.]+这个东西很有意思,关于正则表达式的知识点太多,就简单拿这段代码讲,\s表示匹配任意空白字符(但元字符要进行转义,所以多一个),"."表示的就是匹配这个符号,+表示匹配多次。[]表示匹配里面任意一个字符,再用split存到数组。

Arrays.asList是将数组转化为列表,set的特点就是无序且不可重复。

Set<String> uniqueWords = new HashSet<>(Arrays.asList(words));这段语句就实现了将words转化为列表并存到set类型的uniquewords,实现了去重。

List<String> wordList = new ArrayList<>(uniqueWords);uniqueWords里面赋的给list。

接口的主要形式是:

 Collections.sort(wordList, new Comparator<String>() 
        {
            public int compare(String s1, String s2) //类型可以不一样 
            {
                
            }
        });

7-5 面向对象编程(封装性)

Student类具体要求如下:
私有成员变量:学号(sid,String类型),姓名(name,String类型),年龄(age,int类型),专业(major,String类型) 。
提供无参构造和有参构造方法。(注意:有参构造方法中需要对年龄大小进行判定)
普通成员方法:print(),输出格式为“学号:6020203100,姓名:王宝强,年龄:21,专业:计算机科学与技术”。
普通成员方法:提供setXxx和getXxx方法。(注意:setAge()方法中需要对年龄进行判定)
注意:
年龄age不大于0,则不进行赋值。
print()中的“:”和“,”为均为中文冒号和逗号。

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

/* 请在这里填写答案 */

输入格式:

输出格式:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程

输入样例:

在这里给出一组输入。例如:

6020203110 王宝强 21 计算机科学与技术
6020203119 张三丰 23 软件工程

输出样例:

在这里给出相应的输出。例如:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程

源码如下:

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

/* 请在这里填写答案 */

class Student
{
	private String setSid;
	private String setName;
	private int setAge;
	private String setMajor;
	Student()
	{
		
	}
		void setSid(String setSid)
		{
			this.setSid=setSid;
		}
		void setName(String setName)
		{
			this.setName=setName;
		}
		void setAge(int setAge)
		{
			if(setAge>0)
			this.setAge=setAge;
		}
		String setMajor(String setMajor)
		{
			return setMajor;
		}
	Student(String setSid,String setName,int setAge,String setMajor)
	{
		this.setSid=setSid;
		this.setName=setName;
		this.setAge=setAge;
		this.setMajor=setMajor;
		
	}
	void print()
	{
		System.out.println("学号:"+setSid+",姓名:"+setName+",年龄:"+setAge+",专业:"+setMajor);
	}
}

分析:这段Java代码主要是实现了一个简单的学生信息管理系统。程序要求从命令行中输入两个学生的信息,包括学号、姓名、年龄和专业,然后创建两个学生对象,并输出它们的信息。

第一个类是Student类,用于表示一个学生。它包含了四个属性:学号、姓名、年龄和专业。此外,它还定义了一个构造函数,用于初始化这些属性,并定义了一个print()方法,用于输出学生的信息。

第二个类是Main类,它是程序的入口点。它首先通过命令行输入两个学生的信息,然后分别用无参构造函数和有参构造函数创建两个学生对象,并通过调用print()方法输出它们的信息。

心得:当时都说这题简单,我写半天,结果发现没把有参的放外面去了,还是基础不太扎实。

7-6 GPS测绘中度分秒转换

在测绘中,获取经度和纬度信息的时候,可以是度分秒格式,也可以是小数点格式。例如一个北纬的纬度信息,30°41′52.37″ ,可以转换为 30.697881。

规则:
(1)度和分都是整数,秒可以含有小数。将用户输入的第一个整数,加上第二个整数除以60,再加上第三个浮点数除以3600,就是最终结果。

(2)在输出结果时,保留6位小数。

(3)题目假定用户输入的数据,一定是合法的数据。

输入格式:

三个数值,数之间用空格分开。

输出格式:

见输出样例。

输入样例:

两个整数后,跟上一个小数。数据之间用空格分开。三个数分别代表度、分、秒。

30 41 52.37

输出样例:

输出经纬度信息的小数点格式,保留6位小数。
注意等号的前后有且仅有一个空格,建议复制下面输出到你的代码中,再进行修改。

30°41′52.37″ = 30.697881

源码如下:

import java.util.Scanner;
public class Main
{
	public static void main(String[] args)
	{
       Scanner scan =new Scanner(System.in);
        int x=scan.nextInt();
        int y=scan.nextInt();
        double z=scan.nextDouble();
        double n=x+y*1.0/60+z/3600;
        String s = String.format("%.6f", n);
        //Java中没有lf
        System.out.println(x+"°"+y+"′"+z+"″"+" = "+s);
    }
}

分析:首先使用 Scanner 类从标准输入读入角度的度、分、秒三个部分,分别用整型变量 x、y 和双精度浮点型变量 z 表示.

再将分和秒转换为度数的单位,即将分转换为度的 1/60,将秒转换为度的 1/3600。这里需要注意,将分和秒转换为度数的单位时,需要使用浮点数进行计算,否则会出现精度误差。
最后将度、分、秒转换为十进制度数,并保留六位小数输出。这里使用 String.format() 方法将 变量保留六位小数,然后将结果输出。

心得:这道题的主要问题是无法输出保留6位小数的结果,平常方法用printf输出,但这样的话如果写%.6f,别的数(x,y,z),也要对精度进行确定(用%**进行表示),就会造成精度损失,所以采用

String s = String.format("%.6f", n);这段代码,把n转化为6位小数的字符串,再进行输出。

注:java中没有%lf。

7-7 判断两个日期的先后,计算间隔天数、周数

从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。

预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

输入格式:

输入两行,每行输入一个日期,日期格式如:2022-06-18

输出格式:

第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周

输入样例1:

2000-02-18
2000-03-15

输出样例1:

第一个日期比第二个日期更早
两个日期间隔26天
两个日期间隔3周

输入样例2:

2022-6-18
2022-6-1

输出样例2:

第一个日期比第二个日期更晚
两个日期间隔17天
两个日期间隔2周

源码如下:

import java.util.Scanner;
import java.time.LocalDate;
import java.time.*; 
import java.time.temporal.ChronoUnit;
import java.time.temporal.*;
import java.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;

public class Main
{
	public static void main(String[] args)
	{
        int flag=0;
       Scanner scan =new Scanner(System.in);
       String a= scan.nextLine();
       String b= scan.nextLine();
       String []s1=a.split("-");
       String []s2=b.split("-");
       int year1=Integer.parseInt(s1[0], 10);
       int month1=Integer.parseInt(s1[1], 10);
       int day1=Integer.parseInt(s1[2], 10);
       int year2=Integer.parseInt(s2[0], 10);
       int month2=Integer.parseInt(s2[1], 10);
       int day2=Integer.parseInt(s2[2], 10);
	   LocalDate l1=LocalDate.of(year1,month1,day1);
	   LocalDate l2=LocalDate.of(year2,month2,day2);
       boolean status = l1.isAfter(l2);
	   if(status==true)
	   {
           
		   System.out.println("第一个日期比第二个日期更晚");
	   }
	   else
	   {
           flag=1;
		   System.out.println("第一个日期比第二个日期更早");
	   }
	   //long days= ChronoUnit.DAYS.between(l1,l2 );
	   long days = l1.until(l2, ChronoUnit.DAYS);
	   long weeks=days/7;
        if(flag==1)
        {
            System.out.println("两个日期间隔"+days+"天");
	        System.out.println("两个日期间隔"+weeks+"周");
        }
	   else
       {
           days=days*-1;
           weeks=weeks*-1;
           System.out.println("两个日期间隔"+days+"天");
	        System.out.println("两个日期间隔"+weeks+"周");
       }
	   
    }
}

分析:通过Scanner类从用户输入读取两个日期,然后将这两个日期转换为LocalDate类型。

接下来,使用isAfter()方法比较这两个日期的先后顺序,如果第一个日期比第二个日期更晚,则输出“第一个日期比第二个日期更晚”,否则输出“第一个日期比第二个日期更早”。

然后使用ChronoUnit.DAYS.between()方法计算这两个日期之间的天数,再将天数除以7得到周数。

如果第一个日期比第二个日期更早,那么输出的天数和周数需要乘以-1,即变成负数。最后将计算结果输出。

心得:在写这道题的时候,没有看到旁边的预备知识,导致浪费了很多时间。

int year1=Integer.parseInt(s1[0], 10);这段代码用Integer.parseInt()将原来s1由字符串转变为整形,后面的10代表十进制。

LocalDate l1=LocalDate.of(year1,month1,day1); 这段代码是将年、月、日通过LocalDate.of() 赋给l1。

boolean status = l1.isAfter(l2);这段代码的意思是如果l1晚于l2,status就为true,否则为false。

long days = l1.until(l2, ChronoUnit.DAYS);

long days= ChronoUnit.DAYS.between(l1,l2 );

这两段代码都可以用于计算相差的天数。

菜单

7-1 菜单计价程序-1

某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9

设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}

点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}

订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}

输入格式:

每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。

输出格式:

订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 2
西红柿炒蛋 3
end

输出样例:

在这里给出相应的输出。例如:

48

输入样例1:

订单中包含不存在的菜品记录。例如:

麻婆豆腐 2
炒脆肚 2
西红柿炒蛋 3
end

输出样例1:

在这里给出相应的输出。例如:

炒脆肚 does not exist
48

源码如下:

import java.util.Scanner;
public class Main 
{
    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        while (true) 
        {
            String input = scan.nextLine();
            if (input.equals("end")) 
            {
                break;
            }
            String[] parts = input.split(" ");
            String dishName = parts[0];
            int portion = Integer.parseInt(parts[1]);
            order.addARecord(dishName, portion);
        }
        int totalPrice = order.getTotalPrice();
            System.out.println(totalPrice);
        }
}
class Dish 
{
    String name;
    int unit_price;
    public Dish(String name, int unit_price)  //public直接加类名表示什么
    {
        this.name = name;
        this.unit_price = unit_price;
    }
    public int getPrice(int portion)
    {
        double price = 0;
        switch (portion) 
        {
            case 1:
                price = unit_price;
                break;
            case 2:
                price = unit_price*1.5;
                break;
            case 3:
                price = unit_price*2;
                break;
            default:
                break;
        }
        return (int) Math.round(price);
    }
}
class Menu 
{
    Dish[] dishes;
    public Menu() 
    {
        dishes = new Dish[4];
        dishes[0] = new Dish("西红柿炒蛋", 15);
        dishes[1] = new Dish("清炒土豆丝", 12);
        dishes[2] = new Dish("麻婆豆腐", 12);
        dishes[3] = new Dish("油淋生菜", 9);
    }
    public Dish searchDish(String dishName) 
    {
        for (Dish dish : dishes)
        {
            if (dish.name.equals(dishName))
            {
                return dish;
            }
        }
        return null;
    }
}
class Record 
{
    Dish dish;
    int portion;
    public Record(Dish dish, int portion)
    {
        this.dish = dish;
        this.portion = portion;
    }
    public int getPrice()
    {
        return dish.getPrice(portion);
    }
}
class Order 
{
    Record[] records= new Record[0];
    public void addARecord(String dishName,int portion) 
    {
        Menu menu = new Menu();
        Dish dish = menu.searchDish(dishName);
        if (dish == null) 
        {
            System.out.println(dishName + " does not exist");
        }
        else
        {
        	Record record = new Record(dish, portion);
            Record[] newRecords = new Record[records.length + 1];
            for (int i = 0; i < records.length; i++) {
                newRecords[i] = records[i];
            }
            newRecords[records.length] = record;
            records = newRecords;
        }
    }
    public int getTotalPrice() 
    {
        int totalPrice = 0;
        for (Record record : records)
        {
            totalPrice += record.getPrice();
        }
        return totalPrice;
    }
}

分析:这段代码是一个简单的餐厅点餐系统,包括菜单(Menu)、菜(Dish)、订单(Order)、记录(Record)等类。主要的流程是在Main类的main方法中读入顾客的点餐信息,添加到订单(Order)中。然后计算订单中所有记录的价格总和并输出。

  1. Main类:包含main方法,主要的作用是读入顾客的点餐信息,添加到订单(Order)中,最后输出总价。这里使用Scanner读入,输入的格式是"菜名 数量",例如"西红柿炒蛋 2"表示点了2份西红柿炒蛋。当输入"end"时,退出循环。
  2. Dish类:表示一道菜,包含菜名和单价。getPrice方法根据点的份数(portion)计算出总价,并使用Math.round方法四舍五入为整数。
  3. Menu类:表示一个菜单,包含多个菜(Dish)。searchDish方法根据菜名查找相应的菜,若找到则返回菜肴,否则返回null。
  4. Record类:表示一条订单记录,包含一个菜和点的份数。
  5. Order类:表示一个订单,包含多个订单记录(Record)。addARecord方法根据菜名和份数添加一条订单记录,并将其存储在一个Record数组中。getTotalPrice方法计算所有订单记录的价格总和。

心得:这是第一道菜单题,也是我唯一一个拿了满分的菜单题,这道菜单题就像给我打开了新世界的大门,让还不会走的我在摸索了好几天之后会跑了起来,写这道题时是真的煎熬,当时对类的概念本就不清晰,根本无从下手,身边很多人都打算用面向过程的方法来写,但是我当时想了想,这毕竟是一个菜单系列,这题面向过程,那之后的题该怎么办?当时真的熬了好几天,才把类与类之间关联起来,这代码第一提交没过,但是第二次就满分!当时真的很开心,有一种成就感。

知识点大概在前面都说过,就简单讲讲吧。

int portion = Integer.parseInt(parts[1]);

这段代码是将字符串转化为整形数。

Dish(String name, int unit_price) 
    {
        this.name = name;
        this.unit_price = unit_price;
    }

我想这段代码是我写菜单题的一个很大的收获,就是学会了this关键字的用法,就是在定义dish的属性时要this一下。

Dish dishes[0] = new Dish("西红柿炒蛋", 15);

当Dish的属性时(String name, int unit_price)时,就可以这么用

(int) Math.round(price);

这是四舍五入

for (Dish dish : dishes)

foreach循环也很简单,就是(类型 随便起个名字 : 数组名字)

Record[] records= new Record[0];
Record record = new Record(dish, portion);
Record[] newRecords = new Record[records.length + 1];
for (int i = 0; i < records.length; i++) 
{
      newRecords[i] = records[i];
}
newRecords[records.length] = record;
records = newRecords;

这段代码也很有意思,数组的初始长度是0,for循环不会执行,会直接将新的record存到数组第一个位置,之后再有订单,就会执行for循环,再把新的record存到最后一个位置。

7-2 菜单计价程序-2

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:点菜记录和删除信息。每一类信息都可包含一条或多条记录,每条记录一行。
点菜记录包含:序号、菜名、份额、份数。
份额可选项包括:1、2、3,分别代表小、中、大份。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。

Dish {    
   String name;//菜品名称    
   int unit_price;    //单价    
   int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)    }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {
   Dish[] dishs ;//菜品数组,保存所有菜品信息
   Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
   Dish addDish(String dishName,int unit_price)//添加一道菜品信息
}

点菜记录类:保存订单上的一道菜品记录

Record {
   int orderNum;//序号\
   Dish d;//菜品\
   int portion;//份额(1/2/3代表小/中/大份)\
   int getPrice()//计价,计算本条记录的价格\
}

订单类:保存用户点的所有菜的信息。

Order {
   Record[] records;//保存订单上每一道的记录
   int getTotalPrice()//计算订单的总价
   Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。
   delARecordByOrderNum(int orderNum)//根据序号删除一条记录
   findRecordByNum(int orderNum)//根据序号查找一条记录
}

输入格式:

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:
序号+英文空格+菜名+英文空格+份额+英文空格+份数
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

最后一条记录以“end”结束。

输出格式:

按顺序输出每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。
如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后输出订单上所有菜品的总价(整数数值),

本次题目不考虑其他错误情况,如:菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的下一次作业中会做要求。

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end

输出样例:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
63

输入样例1:

订单中包含删除记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例1:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
27

输入样例2:

订单中包含不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
end

输出样例2:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
63

输入样例3:

订单中包含删除信息以及不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 delete
7 delete
end

输出样例3:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
27

输入样例4:

订单中包含删除信息以及不存在的菜品记录。例如:

麻婆豆腐 12
油淋生菜 9
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
end

输出样例4:

在这里给出相应的输出。例如:

1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
63

源码如下:

import java.util.Scanner;
public class Main 
{
	public static void main(String[] args)
	{		
		Scanner scan = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        //String m=new String();
        String[] m=new String[1];
        while(true)
        {
        	String a = scan.nextLine();
        	String[] part = a.split(" ");
        	if (part[0].equals("1"))
            {
        		m[0]=a;       //存放 1 菜名 份额 份数
                break;
            }
        	else
        	{
        	String name = part[0];
        	int money = Integer.parseInt(part[1]);
        	menu.addDish(name, money);//不要乱输入双引号
        	}
        }
        String[] partss = m[0].split(" ");
        int orderNum1 = Integer.parseInt(partss[0]);
        String dishName1 = partss[1];
        int portion1 = Integer.parseInt(partss[2]);
        int num1 = Integer.parseInt(partss[3]);
        order.addARecord(orderNum1, dishName1, portion1, num1,menu);
        while (true) 
        {
        	
            String input = scan.nextLine();
            if (input.equals("end"))       
            {
                break;
            }
            String[] parts = input.split(" ");
            if((parts[1].equals("delete"))==false)          //
            {
            	int orderNum = Integer.parseInt(parts[0]);
                String dishName = parts[1];
                int portion = Integer.parseInt(parts[2]);
                int num = Integer.parseInt(parts[3]);
                order.addARecord(orderNum, dishName, portion, num,menu);
            }
            else
            {
            	int ordernum=Integer.parseInt(parts[0]);
            	order.delARecordByOrderNum(ordernum);
            }
        }
        	menu.out();//菜单是OK的
        	order.outputRecord();
            int totalPrice = order.getTotalPrice();
            System.out.println(totalPrice);
        }
}
class Dish 
{
    String name;
    int unit_price;
    public Dish(String name, int unit_price)
    {
        this.name = name;
        this.unit_price = unit_price;
    }
    int getPrice(int portion)
    {
        double price = 0;
        switch (portion) 
        {
            case 1:
                price = unit_price;
                break;
            case 2:
                price = unit_price*1.5;
                break;
            case 3:
                price = unit_price*2;
                break;
            default:
                break;
        }
        return (int) Math.round(price);
    }
}
class Menu 
{
    Dish[] dishes = new Dish[0];//
    void addDish(String dishName,int unit_price)
    {
    	//this.dishName = dishName;
        //this.unit_price = unit_price;
    	Dish dish = new Dish(dishName, unit_price);//" "//好像是输入了dishName
    	Dish[] newdishes = new Dish[dishes.length+1];
    	for(int i=0;i<dishes.length;i++)
    	{
    		newdishes[i]=dishes[i];
    	}
    	newdishes[dishes.length] =dish;
    	dishes=newdishes;
    	//return dishes;
    	//for (Dish dishs : dishes)
    	//System.out.println(dishs);
    }
    
    void out()
    {
    	for (Dish dishs : dishes)
        	System.out.println(dishs.name);
    }
    
    //String searchDish(String dishName)
    public Dish searchDish(String dishName) 
    {
        for (Dish dish : dishes)
        {
            if (dish.name.equals(dishName))
            {
            	//System.out.println(dish);
            	//return dish.name;
                return dish;
            }
        }
        return null;
    }
}
class Record 
{
	int orderNum;
	//String dishName;
    Dish dish;
    int portion;
    int num;
    Record(int orderNum,Dish dish,int portion,int num)//第二个是包括菜名和价格
    {
    	this.orderNum = orderNum;
        this.dish = dish;
        //this.dishName=dishName;
        this.portion = portion;
        this.num = num;
    }
    int getPrice()
    {
        return dish.getPrice(portion)*num;
    }
}
class Order 
{
    Record[] records = new Record[0];
    void addARecord(int orderNum, String dishName,int portion,int num,Menu menu) 
    {
        Dish dish = menu.searchDish(dishName);//dish不是菜名
        if (dish == null) //肯定是空的
        {
            System.out.println(dishName + " does not exist");// 
        }
        else
        {
        	Record record = new Record(orderNum,dish,portion,num);//dish
            Record[] newRecords = new Record[records.length + 1];
            for (int i = 0; i < records.length; i++)
            {
                newRecords[i] = records[i];
            }
            newRecords[records.length] = record;
            records = newRecords;
        }
    }
     void outputRecord()
    {
    	for (Record record : records)
    	{
    		System.out.println(record.orderNum+" "+record.dish.name+" "+ record.getPrice()); 
    	}
    }
    Record findRecordByNum(int orderNum)
    {
    	for (Record re : records)
        {
            if (re.orderNum==orderNum)
            {
                return re;
            }
        }
        return null;
    }
    void delARecordByOrderNum(int orderNum)
    {
    	Record re = findRecordByNum(orderNum);
    	if(re==null)
    	{
    		System.out.println("delete error;");
    	}
    	else
    	{
    		int j=0;
            Record[] newre = new Record[records.length + 1];
            for (int i = 0; i < records.length; i++) 
            {
            	if(records[i].equals(findRecordByNum(orderNum)))
            		continue;
                newre[j++] = records[i];
            }
            records = newre;
    	}
    }
    int getTotalPrice() 
    {
        int totalPrice = 0;
        for (Record record : records)
        {
            totalPrice += record.getPrice();
        }
        return totalPrice;
    }
}

心得:这道题我不想分析了,因为这道题写得我真的想哭,就谈一谈体会吧,这道题是以第一题为基础写出来的,刚写完的时候我很满意,心想肯定能一遍过,因为这道题照第一题差的并不多,但是现实是残忍的,周末和周一周二四天,我每时每刻几乎都想这道题,晚上也都很晚睡,我找了很久的错误,但思维受限于第一题,我一直认为是我主方法写错了,想了半天,试了半天,发现我在判断part[0].equals("1")后part[0]就没有了,这个也不难改,就是重新把addARecord那一堆东西再写一遍就行,但结果还不对,输出来的东西是空,当时真的找了好久,主方法其实也很简单,不能有什么问题,我在menu里面把dish输出一点问题没有,啊啊啊啊,当时要疯掉了,磨磨唧唧了好一会儿,我也不知道咋想的,就在order里面输出一回,结果突然发现数组长度为0,好奇怪,这感觉莫名其妙的,我就找了几个学习好的同学问,也没有什么合理的解释,直到问到班长,他告诉我我在order中重新创建了一个menu,因为当时addARecord()这个语句中没加(Menu menu),而是为了调用menu.searchDish这个语句写了个 Menu menu = new Menu();导致我调用的menu是空的,里面什么也没有,说实话当时我人都傻了,我第一题也是这么写的,就一点问题也没有,这明显是我的知识盲区,我问他咋整,他说没啥好法儿,只能再在order里面方法外面再写个有东西的menu,讲的我有点蒙,写了半天没写出来,他跟我说那你就用面向过程写吧,能写多少分是多少分,我开始写,写了半天,写到时间快要截止,当时我突然想到,这样写有意义吗,我学的面向对象,却要用面向过程写,我有点点高傲,突然有一点不屑,但也没有释怀,在周二晚上11点的时候,我感觉已经没有必要写了,再写就算有分也没有意义了,我静静的看着倒计时逐渐归为0,第二题还是一分没拿,因为一直在写第二题,第三题也没有时间改,导致第三题一分也没拿。当时真的抑郁了,一下子照别人差了55分,当时在课堂上还疑惑,如果把pta的成绩计入期末成绩,这不得人人都100?现在想想真的可笑。等到课堂上老师讲这道题,我发现我差的就一点点,不用创建menu,只要把addARecord()里面加上Menu menu这个属性就行,当时我人就有点绷不住了,辛辛苦苦费了这么多功夫,就差一步啊,人麻了,当时就感觉不想学java了。

7-1 菜单计价程序-3

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish[] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号\

Dish d;//菜品\

int portion;//份额(1/2/3代表小/中/大份)\

int getPrice()//计价,计算本条记录的价格\

}

订单类:保存用户点的所有菜的信息。

Order {

Record[] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“** does not exist”,**是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 12/2/3
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end

输出样例:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 38

输入样例1:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 17/0/0
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例1:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 22

输入样例2:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 16/59/59
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end

输出样例2:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1 out of opening hours

输入样例3:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/5 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
7 delete
end

输出样例3:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
table 1 out of opening hours
table 2: 63

输入样例4:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/3 19/5/12
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 4 麻婆豆腐 1 1
7 delete
end

输出样例4:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
4 table 2 pay for table 1 12
delete error;
table 1: 63
table 2: 75
package demo;
import java.util.*;
import java.math.*;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.*; 
import java.time.temporal.ChronoUnit;
import java.time.temporal.*;
import java.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
public class Main
{
	public static void main(String[] args) 
	{
	    
	}

}
class Dish 
{
    String name;
    int unit_price;

    Dish(String name, int unit_price) 
    {
        this.name = name;
        this.unit_price = unit_price;
    }

    int getPrice(int portion)
    {
        double price = 0;
        switch (portion) 
        {
            case 1:
                price = unit_price;
                break;
            case 2:
                price = unit_price*1.5;
                break;
            case 3:
                price = unit_price*2;
                break;
            default:
                break;
        }
        return (int) Math.round(price);
    }
}

class Menu 
{
    Map<String, Dish> dishMap = new HashMap<>();

    Dish searchDish(String dishName) 
    {
        return dishMap.get(dishName);
    }

    Dish addDish(String dishName, int unit_price)
    {
        Dish dish = new Dish(dishName, unit_price);
        dishMap.put(dishName, dish);
        return dish;
    }
}

class Record 
{
    int orderNum;
    Dish dish;
    int portion;

    Record(int orderNum, Dish dish, int portion) 
    {
        this.orderNum = orderNum;
        this.dish = dish;
        this.portion = portion;
    }

    int getPrice()
    {
        return dish.getPrice(portion);
    }
}

class Order 
{
    List<Record> records = new ArrayList<>();
    int getTotalPrice() 
    {
        int totalPrice = 0;
        for (Record r : records) 
        {
            totalPrice += r.getPrice();
        }
        return totalPrice;
    }

    Record addARecord(int orderNum, String dishName, int portion, int num, Menu menu) 
    {
        Dish dish = menu.searchDish(dishName);
        if (dish == null) 
        {
            dish = menu.addDish(dishName, num);
        }
        Record record = new Record(orderNum, dish, portion);
        records.add(record);
        return record;
    }

    boolean delARecordByOrderNum(int orderNum) 
    {
        for (int i = 0; i < records.size(); i++) 
        {
            if (records.get(i).orderNum == orderNum) 
            {
                records.remove(i);
                return true;
            }
        }
        return false;
    }

    Record findRecordByNum(int orderNum) 
    {
        for (Record r : records) 
        {
            if (r.orderNum == orderNum) 
            {
                return r;
            }
        }
        return null;
    }
}
class Table
{
    private int tableNum;
    private List<Order> orders;

    private static final double WEEKDAY_LUNCH_DISCOUNT = 0.6;
    private static final double WEEKDAY_DINNER_DISCOUNT = 0.8;
    private static final double WEEKEND_DISCOUNT = 1.0;

    private static final LocalTime WEEKDAY_LUNCH_START = LocalTime.of(10, 30);
    private static final LocalTime WEEKDAY_LUNCH_END = LocalTime.of(14, 30);
    private static final LocalTime WEEKDAY_DINNER_START = LocalTime.of(17, 0);
    private static final LocalTime WEEKDAY_DINNER_END = LocalTime.of(20, 30);
    private static final LocalTime WEEKEND_START = LocalTime.of(9, 30);
    private static final LocalTime WEEKEND_END = LocalTime.of(21, 0);

    private boolean isOpen(LocalDateTime orderTime) 
    {
        DayOfWeek dayOfWeek = orderTime.getDayOfWeek();
        LocalTime time = orderTime.toLocalTime();

        if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) 
        {
            return time.isAfter(WEEKEND_START) && time.isBefore(WEEKEND_END);
        } 
        else 
        {
            if (time.isBefore(WEEKDAY_LUNCH_START) || time.isAfter(WEEKDAY_DINNER_END))
            {
                return false;
            } 
            else if (time.isBefore(WEEKDAY_LUNCH_END))
            {
                return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
            }
            else if (time.isBefore(WEEKDAY_DINNER_START)) 
            {
                return true;
            } 
            else 
            {
                return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
            }
        }
    }
    private double getDiscount(LocalDateTime orderTime) 
    {
        DayOfWeek dayOfWeek = orderTime.getDayOfWeek();
        LocalTime time = orderTime.toLocalTime();

        if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY)
        {
            return WEEKEND_DISCOUNT;
        }
        else 
        {
            if (time.isBefore(WEEKDAY_LUNCH_START) || time.isAfter(WEEKDAY_DINNER_END))
            {
                return 0.0;
            } 
            else if (time.isBefore(WEEKDAY_LUNCH_END)) 
            {
                return WEEKDAY_LUNCH_DISCOUNT;
            } 
            else if (time.isBefore(WEEKDAY_DINNER_START))
            {
                return 1.0;
            }
            else
            {
            	return WEEKDAY_DINNER_DISCOUNT;
            }
        }
    }
}

心得:当时写这题心态有点问题,就是有点不想写了,首先是上周亏了那么多分,然后就是这玩太折磨人了,写完pta我整个人都有点精神萎靡,但我还是想试一试,因为当时学了set和list之类的方法,老师也用的是map和向量,就想数组的确不是很方便,就优化了一下,把menu和order的改了改,后来写table类,这让我对这方面的知识又熟悉了一些,但当时我纠结了好久,这个代点单到底咋写,到底放哪,我本是打算放到table类里面,但是想了半天也不知道该怎么实现,后来又想还是放主方法里面吧,然后主方法写了好长,写了100多行也没写出来,这个判断那个判断什么的(事后跟别人交流才知道他们写出来的都是判断长度而不是内容),再加上我其实不太爱和别人交流、也不太爱问别人怎么写,就导致我一写不出来就很那有进展,写到了周末厌倦了,烦了,就没写了,现在想想,应该多问问,多交流交流的。(这题代码没有主方法,table类可能也有问题)

三、踩坑心得

我踩得最大的坑就是心态这关,因为菜单2的失利菜单3几乎就不想写了,其实现在看来很不应该,本来就亏55分就好了,结果这下子快亏100分了,以后的菜单题,还是得多花时间想,多花时间写,我要是再写不出来,我一定要问老师.....以前感觉写代码时自己的时,而且老师看这么多行代码也费事,我的注释也不是特别全,但这都是分啊啊啊,我哭死,下次要再写不出来绝对问老师(我要是到时候突然胆子小了,怂了,您就当我口嗨吧....)。然后就是一些小点,主要是语法上的一些细节问题,比return;忘写了,或者数组长度不够导致非零返回(虽说往往扩大数组后就变成答案错误),不太会区分float和doubleprintln和printf等,最后是细心的问题,从一开始的格式错误,再到题目故意埋的陷阱,比如输出时的强制转换(float转换),总结出来的心得就是做题时一定要细心,仔细看好题目的要求,是要几位小数,或者有什么固定格式。

四、主要困难以及改进建议

先说小题,小题真的让我知道了好多新的东西,快输,接口,列表等等,但这些其实没有学过,还有一些语法是我们从未了解但的的确确存在的,比如,split、字符串转整形、整形转字符串什么的,现在或许很清楚,但当时真的不知道,这也没办法,语法本来就博大精深,以后肯定还会有更多新的我们从未了解的语法等着我们,这首先就需要我们平时多积累,多从网上读读别人的代码,多长长见识,其次就是在我们写pta的时候要天马行空的想象,多思考会不会有更简单的方法,有想法就去CSDN查,尽量多学一点新知识。

菜单题的话,心态是重点,肯拼时间是难点,一道题写几个小时没写出来就先缓一缓,心态别裂开,但缓一缓是指写别的题,要是休息的话估计就写不完了,一个测试点不过就一直输数据,输个几个小时的,肯定能找到问题,要是一道菜单题你写两天就不写了,这肯定没有什么收获。

五、总结

这三次作业让我对面向对象的认识更加深刻,了解了类的使用、如何关联和封装等。也让我学会了一些java中的语法,比如快输,列表,接口等,一些小的知识点比如正则表达式等也逐渐掌握,而且经历几次失利我也逐渐更想把接下来的题写好。需要学习的地方还有很多,但主要还是靠老师布置作业然后去CSDN学习和在超星系统看视频。总之接下来我会努力完成作业,争取拿高分。

posted @ 2023-04-01 18:19  Degdor  阅读(111)  评论(0)    收藏  举报