第一次博客作业
2023-05-23
一:前言
前三次作业主要内容为菜单计价程序的代码实现,代码难度由简到难。第一次作业主要目的是熟悉java的代码书写以及功能,面向对象并未体现。第二次作业则开始设计一个简单的菜单计价小程序,并实现一部分功能的完善。第三次作业是在第二次作业的基础上进行代码功能的优化,难度逐渐叠加。
二:设计与分析
第一次作业:
知识点相对不多,也不需要用什么对象和类。利用过程即可。题量也不多,就九个而已。总体难度偏简单。
第二次作业:从这里就要开始使用类和对象来写代码啦
三:踩坑心得
1.1:提醒:输入数据上限不得超过纪录,下限不得小于等于0;
1.2:提醒:注意换算单位;
1.4:提醒:一定要心细;
1.6:注意:输入学号不是8位或者学院编号不是01、02、03、20其中之一,属于非法输入;
1.7:提示:nextGuess和lastGuess的差值小于0.00001时认为两者几乎相同;
1.8:注意:结束符-1之后的0\1字符忽略不计。
2.1:菜单计价程序-1:
一定要从第一个菜单开始就用class类来设计;
题面给了价格计算要四舍五入,简单的强制类型转换不能满足要求。改用Math. round;
第一次接触java类的概念。在增加菜品和订单的时候,返回值应是被new 实例化的对象。否则非零返回。
2.2:菜单计价程序-2:
增加了许多细节,利用题目给的提示要一一用代码实现出来;
最后一个测试点,将信息集中处理改成了输入即处理即可通过。但不明白测试点具体内容;
删除掉的记录并没真正意义上的删除,只是做了一个flag作为标识变量,在计算价格的时候排除掉而已;
多条删除记录时,考虑了是否有删除错误的情况,但是只打印了一次delete error,导致许多测试点不能正常通过。
查找的菜单没有以最后一个菜品作为价格参考。
2.3:需要根据蔡勒公式求星期几;
2.4:首先自己先用数学分析好题目再来代码实现。
3.1:菜单计价程序-3:
主类过于冗余,判断在输出的信息,应该提取在多个方法中。
定义的gettotalprice();注释掉了,使用了一个单独变量作为价格总和。面向过程的代码,复用率低。
日期的判断采用的提取字符串。可用Java自带的日期类减少代码量和复杂度。
程序时间复杂度高。过测试点过的很极限。
桌类的定义没有很好的与前几个类组合一起,方法的定义很长。
3.2 要了解HashSet的用法;
3.3学会set.contains()的用法;
3.4知道如何对字符串进行分割;
3.5重点来啦“对成员变量进行包装(JavaBean),构造方法”以及坑:print()中的“:”和“,”为均为中文冒号和逗号。
3.7所要求的技巧性很强,学会使用LocalDate类。
四:主要困难以及改进建议
第一次题目集"学号识别"题目要学一下substring方法将字符串分隔。
2.3蔡勒公式:
public static int week(int y,int m,int d)//根据蔡勒公式求星期几 { int num; if(m == 1 || m == 2){ m += 12;y--;} int a = y/100; int b = y%100; num = (a/4) - 2*a + b + (b/4) + (13*(m+1)/5) + d - 1; return num%7; }
2.4走格子重点:
1 int[] number = new int[m];//m为多少,就需要算几个数据的走法(存入一个数组中) 2 int[] ways = new int[1000];//每一个数组对应的走法存入另一个数组中; 3 ways[1] = 1; 4 ways[2] = 2; 5 ways[3] = 4; 6 ways[4] = 8; 7 for(i=0;i<m;i++){ 8 number[i] = input.nextInt(); 9 if(number[i]<5){ 10 System.out.println(ways[number[i]]); 11 } 12 else{ 13 for(j=upper_bound+1;j<=number[i];j++){ 14 ways[j]=ways[j-1]+ways[j-2]+ways[j-3]+ways[j-4]; 15 } 16 upper_bound=number[i]; 17 System.out.println(ways[number[i]]); 18 }
3.2有重复数据:
1 Scanner sc=new Scanner(System.in); 2 int n= sc.nextInt(); 3 sc.nextLine(); 4 String[] strings=sc.nextLine().split(" "); 5 HashSet<String> set=new HashSet<>(); 6 for (int i = 0; i < n; i++) { 7 set.add(strings[i]); 8 } 9 if (set.size()==n) System.out.println("NO"); 10 else System.out.println("YES");
3.3去掉重复的数据:
1 for(int i=0;i<n;i++){ 2 I=input.nextInt(); 3 if(!set.contains(I)) 4 { 5 a[count++]=I; 6 set.add(I); 7 } 8 }
3.4单词统计与排序:


3.5面向对象编程(封装性):
1 class Student 2 { 3 private String sid; 4 public Student(String sid, String name, int age, String major) { 5 this.sid = sid; 6 this.name = name; 7 this.age = age; 8 this.major = major; 9 } 10 11 public String getSid() { 12 return sid; 13 } 14 15 16 public void setSid(String sid) { 17 this.sid = sid; 18 } 19 }
3.7判断两个日期的先后,计算间隔天数、周数:
1 import java.time.format.DateTimeFormatter; 2 import java.time.temporal.ChronoUnit; 3 import java.util.*; 4 import java.time.*; 5 public class Main { 6 public static void main(String[] args){ 7 String data1,data2; 8 9 Scanner input=new Scanner(System.in); 10 data1=input.nextLine(); 11 DateTimeFormatter times = DateTimeFormatter.ofPattern("yyyy-M-d"); 12 LocalDate dates = LocalDate.parse(data1,times); 13 14 data2=input.nextLine(); 15 DateTimeFormatter times2 = DateTimeFormatter.ofPattern("yyyy-M-d"); 16 LocalDate dates2 = LocalDate.parse(data2,times2); 17 18 long days = ChronoUnit.DAYS.between(dates, dates2); 19 long week= days/7; 20 if(week<0){ 21 days=-days; 22 week=-week; 23 System.out.println("第一个日期比第二个日期更晚"); 24 } 25 else System.out.println("第一个日期比第二个日期更早"); 26 System.out.println("两个日期间隔"+days+"天"); 27 System.out.println("两个日期间隔"+week+"周"); 28 } 29 }
菜单报价系列:
菜单计价程序-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”,**是不能识别的菜名
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner scanner = new Scanner(System.in); 6 int Price=0; 7 while(true) { 8 String dish = scanner.next(); 9 if (dish.equals("end")) 10 break; 11 int portion = scanner.nextInt(); 12 int flag=0; 13 if (dish.equals("西红柿炒蛋")) { 14 flag = 1; 15 switch (portion) { 16 case 1: 17 Price += 15; 18 continue; 19 case 2: 20 Price += 23; 21 continue; 22 case 3: 23 Price += 30; 24 continue; 25 default: 26 continue; 27 } 28 } 29 if (dish.equals("清炒土豆丝")) { 30 flag = 1; 31 switch (portion) { 32 case 1: 33 Price += 12; 34 continue; 35 case 2: 36 Price += 18; 37 continue; 38 case 3: 39 Price += 24; 40 continue; 41 } 42 } 43 if (dish.equals("麻婆豆腐")) { 44 flag = 1; 45 switch (portion) { 46 case 1: 47 Price += 12; 48 continue; 49 case 2: 50 Price += 18; 51 continue; 52 case 3: 53 Price += 24; 54 continue; 55 } 56 } 57 if (dish.equals("油淋生菜")) { 58 flag = 1; 59 switch (portion) { 60 case 1: 61 Price += 9; 62 continue; 63 case 2: 64 Price += 14; 65 continue; 66 case 3: 67 Price += 18; 68 continue; 69 } 70 } 71 if (flag == 0) { 72 System.out.println(dish + " does not exist"); 73 } 74 } 75 System.out.println(Price); 76 } 77 }
菜单计价程序-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”
最后输出订单上所有菜品的总价(整数数值),
本次题目不考虑其他错误情况,如:菜单订单顺序颠倒、不符合格式的输入、序号重复等。
1 import java.util.Scanner; 2 3 public class Main{ 4 public static void main(String[] args){ 5 Scanner input=new Scanner(System.in); 6 String []name=new String[500]; //菜单储存 7 int []price=new int[500]; //价格储存 8 String Dish; //读入菜名 9 int Price,i=0; //读入价格 10 String type; //点菜的序号,菜品的种类(i); 11 while(true){ 12 int re=1; //判断是否菜品重复输入 13 Dish=input.next(); 14 if(Dish.equals("1")){type="1";break;} //开始点菜 15 if(Dish.equals("end")){type="0";break;} //只有菜单没有订单 16 Price=input.nextInt(); 17 for(int k=0;k<i;k++) 18 if(Dish.equals(name[k])){price[k]=Price;re=0;break;} //检查菜品是否重复出现 19 20 if(re==1){ //菜品无重复 21 name[i]=Dish; 22 price[i]=Price; 23 i++; 24 } 25 } 26 int count=0,Sum=0,Max=0; //cnt,每个菜品点单的价格,sum,点菜价格总和,max订单数量 27 int []recording=new int[100]; //记录每次点菜的价格 28 int re=0,flag3=1,flag2=0; //flag2,flag3判断订单时连续删除还是删除后继续点单,re点菜数 29 String h=""; 30 if(type.equals("1")) //开始点菜 31 while(!type.equals("end")){ 32 count=0; 33 int flag=0; //判断输入订单是否存在 34 String dish=input.next(); 35 36 if(dish.equals("delete")){ 37 if(flag2==1&&flag3==0) 38 type=h; 39 int p=Integer.parseInt(type); //字符转数字 40 41 if(p<1||p>Max||recording[p-1]==0)System.out.println("delete error;"); //删除错误 42 if(p>=1&&p<=Max&&recording[p-1]!=0){ 43 Sum-=recording[p-1]; 44 recording[p-1]=0; //删除后清除订单记录的价格 45 } 46 h=input.next();flag3=0; 47 if(h.equals("end"))break; 48 if(!h.equals("end")) {flag2=1;type=h;continue;} 49 } 50 else flag3=1; //判断是否连续删除 51 52 int size1=input.nextInt(); //点菜的份额 53 int b=input.nextInt(); //点菜的份数 54 55 for(int j=0;j<i;j++){ 56 if(dish.equals(name[j])){ //是否订单菜存在 57 flag=1; 58 if(size1==1)count+=price[j]; 59 if(size1==2){ 60 if(price[j]%2==1) 61 count+=price[j]*1.5+1; 62 else count+=price[j]*1.5; 63 } 64 if(size1==3)count+=2*price[j]; 65 } 66 67 } 68 69 if(flag==0) { 70 recording[re++]=0; 71 System.out.println(dish+" does not exist"); 72 Max++; 73 } 74 75 if(flag==1) 76 { 77 count*=b;Sum+=count; 78 recording[re++]=count; 79 System.out.println(type+" "+dish+" "+count); 80 Max++; 81 } 82 type=input.next(); 83 } 84 85 if(!type.equals("0")) 86 System.out.println(Sum); 87 else System.out.println("0"); 88 } 89 }
菜单计价程序-3:
1 import java.util.Calendar; 2 import java.util.Scanner; 3 public class Main { 4 public static void main(String[] args) { 5 Scanner sc = new Scanner(System.in); 6 Menu mu = new Menu(); 7 Table[] tablemes = new Table[10]; 8 int j = 0;//菜单数 9 int l = 0;//订单数 10 int k = 0;//代点菜数 11 Dish tt; 12 //int sum = 0; 13 int cntTable = 0;//桌号 14 int count; 15 String[] temp; 16 int a1,a2,a3,a4,a5; 17 18 while (true) { 19 String st = sc.nextLine(); 20 temp = st.split(" "); 21 if(st.equals("end")) 22 break; 23 count = temp.length; 24 if (count == 2) {//一个空格 25 //String[] temp1 = st.split(" "); 26 if (temp[1].equals("delete")) {//第二个为delete 27 a1 = Integer.parseInt(temp[0]); 28 int c = tablemes[cntTable].odt.delARecordByOrderNum(a1); 29 tablemes[cntTable].sum-=c; 30 } else {//菜单添加 31 a2 = Integer.parseInt(temp[1]); 32 mu.dishs[j] = mu.addDish(temp[0], a2); 33 j++; 34 } 35 //continue; 36 } 37 else if (count == 4) {//三个空格 38 //String[] temp2 = st.split(" "); 39 if (temp[0].equals("table")) {//桌号 40 cntTable++;//跳过0; 41 l = 0; 42 tablemes[cntTable] = new Table(); 43 //tablemes[cntTable].tableDtime = st; 44 tablemes[cntTable].AheadProcess(st); 45 46 System.out.println("table " + cntTable + ": "); 47 } else {//增加订单的情况; 48 a3 =Integer.parseInt(temp[0]); 49 a4 = Integer.parseInt(temp[2]); 50 a5=Integer.parseInt(temp[3]); 51 tablemes[cntTable].odt.addARecord(a3, temp[1],a4 , a5); 52 tt = mu.searthDish(temp[1]); 53 if (tt != null) { 54 tablemes[cntTable].odt.records[l].d = tt; 55 int a = tablemes[cntTable].odt.records[l].getPrice(); 56 System.out.println(tablemes[cntTable].odt.records[l].orderNum + " " + tt.name + " " +a ); 57 tablemes[cntTable].sum +=a; 58 } 59 l++; 60 } 61 //continue; 62 } 63 64 else if (count == 5) {//代点菜 65 //String[] temp3 = st.split(" "); 66 a1 = Integer.parseInt(temp[1]); 67 a2 = Integer.parseInt(temp[3]); 68 a3 = Integer.parseInt(temp[4]); 69 tablemes[cntTable].odt.addARecord( a1, temp[2], a2, a3); 70 tt = mu.searthDish(temp[2]); 71 if (tt != null) { 72 tablemes[cntTable].odt.records[l].d.unit_price = tt.unit_price; 73 int b = tablemes[cntTable].odt.records[l].getPrice(); 74 System.out.println(temp[1] + " table " + tablemes[cntTable].tableNum + " pay for table " + temp[0] + " " + b); 75 tablemes[cntTable].sum += b; 76 } 77 l++; 78 } 79 //st = sc.nextLine(); 80 81 } 82 for (int i = 1; i < cntTable + 1; i++) { 83 tablemes[i].Gettottalprice(); 84 } 85 } 86 }
五:心得
第一次题目集总体还是不难的,好好写就行;
第二次总体难度上升,也开始了菜单计价,还是比较繁琐滴。
第三次菜单太难了,顶不住。其他题目倒还能做(一定要细心)。
六:题目集
①:7-1 身体质量指数(BMI)测算;7-1 身体质量指数(BMI)测算;7-3 奇数求和;7-4 房产税费计算2022;7-5游戏角色选择;7-6学号识别;7-7 判断三角形类型;7-8巴比伦法求平方根近似值;7-9 二进制数值提取。
②:7-1 菜单计价程序-1;7-2 菜单计价程序-2;7-3 jmu-java-日期类的基本使用;7-4 小明走格子。
③:7-1 菜单计价程序-3;7-2 有重复的数据;7-3 去掉重复的数据;7-4 单词统计与排序;7-5 面向对象编程(封装性);7-6 GPS测绘中度分秒转换;7-7 判断两个日期的先后,计算间隔天数、周数。
SourceMonitor的生成报表内容:





浙公网安备 33010602011771号