前言
文章标题右边有目录导航,可以快速索引阅读。
此博客为java作业集4-5次和期中考试题目的总结,
设计与分析
第四次题目集
7-1 菜单计价程序-4
题目太长了不再复制。
我的类图:

我的代码:
import java.time.YearMonth; import java.util.Calendar; import java.util.Objects; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Menu menu = new Menu(); Table[] table = new Table[57];//桌号1-55; int j = 0;//菜单数 int l = 0;//订单数 //代点菜数 //遍历桌 int cntTab = 0;//桌号 String[] temp;//字符串存储 int tempordernum = 0;//临时存上一个有效序号 String input; String regex = "[\\u4e00-\\u9fa5]* \\d*";//非特色菜菜谱 String regex1 = "[\\u4e00-\\u9fa5]* \\d* T";//特色菜谱 String regex2 = "\\d (delete)";//删除情况 String regex3 = "(table) ([1-4][0-9]*|5[0-5]*) \\d{4}/\\d+/\\d{1,2} ([0-1]?[0-9]|2[0-3])/([0-5][0-9])/([0-5][0-9])";//添桌子的情况 String regex4 = "([1-9]|[1-9][0-9]*) [\\u4e00-\\u9fa5]+ \\d+ \\d+";//点菜记录的添加; String regex5 = "([1-4][0-9]*|5[0-5]*|[1-9]) \\d [\\u4e00-\\u9fa5]+ [123] (1[0-5]|[1-9])";//代点菜 while (true) { int count;//空格数量; input = sc.nextLine();//获取输入,每行 if(input.equals("end")) break; if(input.equals("")) { System.out.println("wrong format"); continue; } temp = input.split(" ");//分割 /* * 判断输入的类型*/ count = temp.length; if(count==2){//非特色菜菜谱,或者删除菜; if(input.matches(regex2)){//删除的情况桌子有效才删除 if (table[cntTab] == null) throw new AssertionError(); if(table[cntTab].inputIsvalid){ table[cntTab].order.delARecordByOrderNum(Integer.parseInt(temp[0]));//删除 } }else if(input.matches(regex)){//非特色菜谱添加 if (cntTab == 0) { menu.dishes[j] = new Dish(); //menu.dishes[j] = menu.addDish(temp[0], Integer.parseInt(temp[1])); j++; } else if(table[cntTab].inputIsvalid){ System.out.println("invalid dish"); } }else { System.out.println("wrong format"); } }else if(count==3){//特色菜菜谱 if(input.matches(regex1)) { if(cntTab!=0) { if(table[cntTab].inputIsvalid) System.out.println("invalid dish"); else continue; } menu.dishes[j] = new Dish(); //menu.dishes[j] = menu.addDish(temp[0], Integer.parseInt(temp[1])); menu.dishes[j].isSpecial = true;//是特色菜 j++; }else System.out.println("wrong format"); } //桌子的添加,点菜记录的添加, else if(temp[0].equals("table")||input.contains("/")) { cntTab++; table[cntTab] = new Table(); if(temp[0].equals("table")){ if(input.matches(regex3)) table[cntTab].AheadProcess(input); table[cntTab].inputIsvalid=true; if (input.matches(regex3)) { if(table[cntTab].inputIsvalid&&!table[cntTab].DateisValid()){//检查日期 System.out.println(table[cntTab].tableNum+" date error"); table[cntTab].inputIsvalid=false; continue; } if(table[cntTab].inputIsvalid&&!table[cntTab].Daterande()){ table[cntTab].inputIsvalid=false; continue; } for(int i =1;i<cntTab;i++){ if (table[i].inputIsvalid && table[cntTab].CheckSameTime(table[i])) {//同一时间段 table[cntTab].istoSum = true; } else { l = 0; } tempordernum = 0; } if(table[cntTab].discnt>0) System.out.println("table " + table[cntTab].tableNum + ": "); else { System.out.println("table " + table[cntTab].tableNum + " out of opening hours"); table[cntTab].inputIsvalid = false; } continue; } else {//第一个是table但不合法 table[cntTab].inputIsvalid = false; if(!temp[1].equals("")&&temp[1].charAt(0)>='1'&&temp[1].charAt(0)<='9'&&!temp[1].contains("/")){ if(Integer.parseInt(temp[1])<1||Integer.parseInt(temp[1])>55){ System.out.println(Integer.parseInt(temp[1])+" table num out of range"); continue; } } } } System.out.println("wrong format"); table[cntTab].inputIsvalid = false; if(!temp[0].equals("table")) table[cntTab].istoSum = true; }else if(count==4){ if(input.matches(regex4)&&(Objects.requireNonNull(table[cntTab]).inputIsvalid||table[cntTab].istoSum)){//点菜记录 Dish tem; int aheadcntTab = cntTab-1; if(!table[cntTab].istoSum) {//不需要合并 table[cntTab].order.records[l] = new Record(); table[cntTab].order.records[l] = table[cntTab].order.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3])); if(l-1>=0){//判断记录序号是否递增 tempordernum = getTempordernum(table, l, temp, tempordernum, cntTab); }else {//特殊情况 if(table[cntTab].order.records[l].Checkahead()) tempordernum = table[cntTab].order.records[l].orderNum; } if((tem = menu.searchDish(temp[1]))!=null){ float temdiscnt;//临时储存折扣 table[cntTab].order.records[l].d = tem; temdiscnt = table[cntTab].order.records[l].Checkportion(table[cntTab].discnt); if(temdiscnt!=1F) table[cntTab].rediscnt = temdiscnt;//最终折扣 if(table[cntTab].order.records[l].exist==1&&table[cntTab].order.records[l].noNeed) { if(table[cntTab].rediscnt!=1) { table[cntTab].sum += Math.round(table[cntTab].order.records[l].getPrice() * table[cntTab].rediscnt); table[cntTab].rediscnt=1.0F; } else table[cntTab].sum += Math.round(table[cntTab].order.records[l].getPrice() * table[cntTab].discnt); } } if(!table[cntTab].istoSum){//如果份额名字未重复; l++; } } else{//需要合并计算 table[aheadcntTab].order.records[l] = new Record(); table[aheadcntTab].order.records[l] = table[aheadcntTab].order.addARecord(Integer.parseInt(temp[0]), temp[1], Integer.parseInt(temp[2]), Integer.parseInt(temp[3])); if(l-1>=0){//判断记录序号是否递增 tempordernum = getTempordernum(table, l, temp, tempordernum, aheadcntTab); } if((tem = menu.searchDish(temp[1]))!=null){ float temdiscnt;//临时储存折扣 table[aheadcntTab].order.records[l].d = tem; temdiscnt = table[aheadcntTab].order.records[l].Checkportion(table[aheadcntTab].discnt);//计算折扣 if(temdiscnt==0.7F)//如果需要调整 table[aheadcntTab].rediscnt = temdiscnt;//最终折扣//更改折扣 if(table[aheadcntTab].order.records[l].exist==1) {//必须存在 if(table[aheadcntTab].rediscnt!=1) { table[aheadcntTab].sum += Math.round(table[aheadcntTab].order.records[l].getPrice() * table[aheadcntTab].rediscnt); table[aheadcntTab].rediscnt=1.0F; } else table[aheadcntTab].sum += Math.round(table[aheadcntTab].order.records[l].getPrice() * table[cntTab].discnt)-1; } } l++; } }else { if(table[cntTab]==null) { System.out.println("wrong format"); continue; } if(table[cntTab]!=null&&table[cntTab].inputIsvalid) System.out.println("wrong format"); } } else if(count==5&& Objects.requireNonNull(table[cntTab]).inputIsvalid){//代点菜 int temSum = 0; if(input.matches(regex5)){ int AnothNum = Integer.parseInt(temp[0]); table[cntTab].order.records[l] = table[cntTab].order.takeorderfor(table[cntTab].tableNum,table,AnothNum,Integer.parseInt(temp[1]),temp[2],Integer.parseInt(temp[3]),Integer.parseInt(temp[4])); Dish tem; if((tem = menu.searchDish(temp[2]))!=null&&table[cntTab].order.records[l]!=null){ table[cntTab].order.records[l].isTaked = true;//给别人diade float temdiscnt;//临时储存折扣 table[cntTab].order.records[l].d = tem; temdiscnt = table[cntTab].order.records[l].Checkportion(table[cntTab].discnt); if(temdiscnt!=1F) table[cntTab].rediscnt = temdiscnt;//最终折扣 if(table[cntTab].order.records[l].exist==1&&table[cntTab].order.records[l].noNeed) { if(table[cntTab].rediscnt!=1) { table[cntTab].sum += Math.round((temSum=table[cntTab].order.records[l].getPrice()) * table[cntTab].rediscnt); table[cntTab].rediscnt=1.0F; } else table[cntTab].sum += Math.round((temSum =table[cntTab].order.records[l].getPrice()) * table[cntTab].discnt); } System.out.println(temp[1] + " table " + table[cntTab].tableNum + " pay for table " + temp[0] + " " + temSum); } if(table[cntTab].order.records[l]!=null) l++; }else System.out.println("wrong format"); }else{ assert table[cntTab] != null; if(table[cntTab].inputIsvalid) System.out.println("wrong format"); } } for(int i=1;i<=cntTab;i++){ if(table[i].inputIsvalid&&!table[i].istoSum) table[i].GetTotalPrice(); } } private static int getTempordernum(Table[] tablemes, int l, String[] temp, int tempordernum, int aheadcntTab) { if(Integer.parseInt(temp[0])<=tempordernum) { System.out.println("record serial number sequence error"); tablemes[aheadcntTab].order.records[l].exist=0; }else if(tablemes[aheadcntTab].order.records[l]!=null&&tablemes[aheadcntTab].order.records[l].noNeed) tempordernum = tablemes[aheadcntTab].order.records[l].orderNum; return tempordernum; } } class Dish { String name; // 菜品名称 boolean isSpecial = false; // 是不是特色菜 int unit_price; // 单价 boolean exist = true; int getPrice(int portion) { int price0; switch (portion) { case 1: price0 = unit_price; break; case 2: price0 = Math.round((float) (unit_price * 1.5)); break; case 3: price0 = unit_price * 2; break; default: throw new IllegalArgumentException("Invalid portion: " + portion); } return price0; } // 构造方法 public Dish() { } } class Menu { Dish[] dishes = new Dish[10]; int count = 0; Dish searchDish(String dishName) { for (int i = 0; i < count; i++) { Dish dish = dishes[i]; if (dishName.equals(dish.name) && dish.exist) { return dish; } } System.out.println(dishName + " does not exist"); return null; } /* Dish addDish(String dishName, int unitPrice) { if (unitPrice < 1 || unitPrice > 300) { System.out.println(dishName + " price out of range " + unitPrice); return null; } Dish dish = new Dish(); dish.name = dishName; dish.unit_price = unitPrice; dishes[count++] = dish; return dish; } */ } class Record { int orderNum; Dish d = new Dish(); int num = 0; int portion; boolean noNeed = true; int exist = 1; float realDiscount = 1; boolean isTaked = false; int getPrice() { return Math.round(d.getPrice(portion) * num); } float Checkportion(float discount) { if (portion < 1 || portion > 3) { System.out.println(orderNum + " portion out of range " + portion); exist = 0; noNeed = false; } else if (num < 1 || num > 15) { System.out.println(orderNum + " num out of range " + num); exist = 0; noNeed = false; } else { if (d.isSpecial && (discount == 0.8F || discount == 0.6F)) { realDiscount = 0.7F; } if (exist == 1 && !isTaked) { System.out.println(orderNum + " " + d.name + " " + getPrice()); } } return realDiscount; } boolean Checkahead() { return num >= 1 && num <= 15 && portion >= 1 && portion <= 3; } } class Order { Record[] records = new Record[100]; private int count = 0; public int getTotalPrice() { int sum = 0; for (int i = 0; i < count; i++) { Record record = records[i]; if (record != null && record.exist == 1) { sum += record.getPrice(); } } return sum; } public Record addARecord(int orderNum, String dishName, int portion, int num) { int index = -1; for (int i = 0; i < count; i++) { Record record = records[i]; if (record != null && record.d.name.equals(dishName) && record.portion == portion) { index = i; break; } } if (index == -1) { Record record = new Record(); record.d.name = dishName; record.orderNum = orderNum; record.portion = portion; record.num = num; records[count++] = record; return record; } else { return records[index]; } } public Record takeorderfor(int mynum, Table[] tables, int anotherNum, int orderNum, String dishName, int portion, int num) { boolean flag = false; for (Table table : tables) { if (table != null && table.tableNum != mynum && table.tableNum == anotherNum) { flag = true; break; } } if (flag) { return addARecord(orderNum, dishName, portion, num); } else { System.out.println("Table number: " + anotherNum + " does not exist"); return null; } } public void delARecordByOrderNum(int orderNum) { if (orderNum > count || orderNum <= 0) { System.out.println("Delete error"); return; } Record record = records[orderNum - 1]; if (record.exist == 0) { System.out.println("Deduplication " + orderNum); return; } record.exist = 0; } } class Table { int tableNum; boolean inputIsvalid = false; boolean istoSum = false; String tableDtime; int year, month, day, week, hh, mm, ss; int sum = 0; int primesum = 0; Order order = new Order(); float discnt = -1; float rediscnt = 1; void GetTotalPrice() { if (discnt > 0) { primesum = order.getTotalPrice(); if (primesum == 0) sum = 0; System.out.println("table " + tableNum + ": " + primesum + " " + sum); } } void AheadProcess(String tableDtime) { this.tableDtime = tableDtime; processTime(); discount(); } void processTime() { String[] temp = tableDtime.split(" "); tableNum = Integer.parseInt(temp[1]); String[] temp1 = temp[2].split("/"); String[] temp2 = temp[3].split("/"); year = Integer.parseInt(temp1[0]); month = Integer.parseInt(temp1[1]); day = Integer.parseInt(temp1[2]); Calendar c = Calendar.getInstance(); c.set(year, (month - 1), day); week = c.get(Calendar.DAY_OF_WEEK); if (week == 1) week = 7; else week--; hh = Integer.parseInt(temp2[0]); mm = Integer.parseInt(temp2[1]); ss = Integer.parseInt(temp2[2]); } boolean DateisValid() { if (year < 1000) return false; if (month < 1 || month > 12) return false; YearMonth mytime = YearMonth.of(year, month); return mytime.isValidDay(day); } boolean Daterande() { boolean flag = true; if (year < 2022 || year > 2023) { flag = false; } if (!flag) { System.out.println("not a valid time period"); inputIsvalid = false; } return flag; } void discount() { if (week >= 1 && week <= 5) { if (hh >= 17 && hh < 20 || (hh == 20 && mm < 30)) { discnt = 0.8F; } else if ((hh >= 11 && hh <= 13) || (hh == 10 && mm >= 30) || (hh == 14 && mm < 30)) { discnt = 0.6F; } else { discnt = 1.0F; } } else { if (hh >= 10 && hh <= 20 || (hh == 9 && mm >= 30) || (hh == 21 && mm < 30)) { discnt = 1.0F; } else { discnt = 1.0F; } } } boolean CheckSameTime(Table table) { if (tableNum != table.tableNum) return false; if (week == table.week && week >= 1 && week <= 5) { return discnt == table.discnt; } else if (week == table.week && (week == 6 || week == 7)) { int subtime = hh * 3600 + mm * 60 + ss - table.hh * 3600 - table.mm * 60 -ss; return Math.abs(subtime) < 3600; } return false; } }
我的分析:
这次题目难度提升了很多,我只得了很少的分数,代码并没有很大的参考价值。我在写的过程中忘记添加注释,应该在代码中添加详细的注释,解释代码的功能和工作原理,以便读者更好地理解代码的逻辑。也没有很好地模块化代码,将代码分割成更小、更具可读性的功能模块。其次应该要将每个模块的功能限制在一个特定的任务上,这样可以提高代码的可读性和可维护性。使用有意义的变量和方法名称,确保变量和方法的名称能够清晰地描述其用途。避免使用简单的字母和数字作为名称。还可以简化正则表达式,简化代码中的正则表达式,使其更易于理解和维护。可以使用预定义的常量来表示正则表达式,这样可以提高代码的可读性。还要尽量避免硬编码,避免在代码中直接使用硬编码的数字和字符串。可以将这些值保存在常量中,并使用常量来表示它们,这样可以提高代码的可扩展性和可维护性。
第五次题目集
7-1 菜单计价程序-5
本题在菜单计价程序-3的基础上增加了部分内容,增加的内容用加粗字体标识。
注意不是菜单计价程序-4,本题和菜单计价程序-4同属菜单计价程序-3的两个不同迭代分支。
我的类图:

我的代码:
import java.util.Calendar; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Order[] order = new Order[10]; Menu menu = new Menu(); String[] count; int flag; int j = 0; int end = 0;//当遇到end结束时 String[] list = new String[10];//记录不同菜系判断口味度需要, 川菜的 String[] list1 = new String[10];//记录不同菜系判断口味度需要, 晋菜的 String[] list2 = new String[10];//记录不同菜系判断口味度需要, 浙菜的 int[] num = new int[20]; /* 记录每道菜菜系的不同 * 用0代表普通菜 * 用1代表川菜 * 用2代表晋菜 * 用3代表浙菜 */ int[] number = new int[20];//计算有效点单 int[] table_num = new int[10];//记录桌号的数组 int flag1 = 0;//记录有效菜单的个数 int flag2 = 0;//当点特色菜的的时候 int flag3 = 0;//记录符合特价菜时间的折扣的标记点 /* * flag3 = 1代表是特价菜7折,代表是普通6折 * flag3 = 2代表是特价菜7折,代表是普通8折 * flag3 = 0代表是周末全价 * */ double[] sum = new double[10];//算单桌打折后总价 double[] beforesum = new double[10];//算单桌打折前总价 double[] spicy = new double[20];//辣口味度计算 double[] acidity = new double[20];//酸口味度计算 double[] sweetness = new double[20];//甜口味度计算 String[] show_spicy = {"不辣","微辣","稍辣","辣","很辣","爆辣"}; String[] show_acidity = {"不酸","微酸","稍酸","酸","很酸"}; String[] show_sweetness = {"不甜","微甜","稍甜","甜"}; int[] fenshu_spicy = new int[10];//计算辣菜的份数 int[] fenshu_acidity = new int[10];//计算酸菜的份数 int[] fenshu_sweetness = new int[10];//计算甜菜的份数 String[] name = new String[10];//记录客户名字 String[] telephone = new String[10];//记录客户电话 int k = 0;//桌子数 while (true) { String str = sc.nextLine(); count = str.split(" "); flag = count.length; if (count[0].equals("end") && flag == 1) { end = 1; } if (count[0].equals("table") && flag == 7) { if (j > 0) { k++; //计算最终的口味度,除以总份数 } j++; sum[j-1] = 0; order[j-1] = new Order(); number[j-1] = 0; } //用来判断是不是订单和菜单混合的标记点 if (j > 0) { // if (flag == 2) { //删除菜品记录 // if (count[1].equals("delete")) { // order[j-1].delARecordByOrderNum(Integer.parseInt(count[0])); // } else { // System.out.println("invalid dish"); // // } // } if (flag == 7) { //桌子信息的输入 if (count[0].equals("table")) { int len = count[3].length();//计算客户姓名的长度 int len1 = count[4].length();//计算客户电话的长度 int b = 0;//是否桌子信息正确 if (count[1].charAt(0) == '0' || !(count[1].charAt(0) >= '1' && count[1].charAt(0) <= '5')) { System.out.println("wrong format"); b = 1; } //桌号正常 if (len > 10) { //客户姓名不能超过10位 System.out.println("wrong format"); b = 1; } if (len1 != 11) { //客户电话不能超过11位 boolean tel; tel = count[4].matches("(181|180|189|133|135|136)\\d{8}"); if (!tel) { System.out.println("wrong format"); b = 1; } } if(b == 1){ return; } name[j - 1] = count[3]; telephone[j - 1] = count[4]; table_num[j-1] = Integer.parseInt(count[1]); String[] arr = count[5].split("/");//将年分割开来 String[] arr1 = count[6].split("/");//将时间分割开来 int year = Integer.parseInt(arr[0]); int month = Integer.parseInt(arr[1]); int day = Integer.parseInt(arr[2]);//将日期分开 int hh = Integer.parseInt(arr1[0]); int mm = Integer.parseInt(arr1[1]); int ss = Integer.parseInt(arr1[2]);//将时间分开 if (arr1[1].length() > 2 || arr1[2].length() > 2) { System.out.println("wrong format"); return; } int c = 0;//判断营业时间正确的标记点 if (month > 12 || day > 31 || year < 1000 || year > 9999) { c = 2; } else { if (year < 2022 || year > 2023) { c = 3; } else { Calendar cal = Calendar.getInstance(); cal.set(year, month - 1, day - 1); if ((cal.get(Calendar.DAY_OF_WEEK) == 7) || (cal.get(Calendar.DAY_OF_WEEK) == 6)) { if ((hh >= 10 && hh <= 20) || (hh == 9 && mm >= 30) || (hh == 21 && mm <= 29) || (hh == 21 && mm == 30 && ss == 0)) { c = 1; flag3 = 0; } //周末全价时间判断 } else { if (hh >= 17 && hh <= 19) { flag3 = 2; c = 1; } if (hh == 20 && mm <= 29) { flag3 = 2; c = 1; } if (hh == 20 && mm == 30 && ss == 0) { flag3 = 2; c = 1; } if ((hh >= 11 && hh <= 13) || (hh == 10 && mm >= 30) || (hh == 14 && mm <= 29) || (hh == 14 && mm == 30 && ss == 0)) { flag3 = 1; c = 1; } } if (c == 0) { System.out.println("table " + table_num[j - 1] + " out of opening hours"); return; } System.out.println("table " + table_num[j - 1] + ": ");//输出桌号信息 } } //符合时间范围 if (c == 2) { System.out.println(Integer.parseInt(count[1]) + " date error"); } if (c == 3) { System.out.println("not a valid time period"); } } } if (flag == 4 || flag == 5 || flag == 6) { //点菜的记录 if (flag == 4) { for (int i = 0; i < flag1; i++) { if (count[1].equals(menu.dishs[i].name)) { flag2 = 1; break; } } //判断这个菜是否再菜单中有 if (flag2 == 1) { //当存在 order[j - 1].addARecord(Integer.parseInt(count[0]), count[1], Integer.parseInt(count[2]), Integer.parseInt(count[3]), menu); System.out.println(Integer.parseInt(count[0]) + " " + count[1] + " " + order[j - 1].records[number[j - 1]].getPrice()); //输出单笔 if (flag3 == 1) { sum[j - 1] = Math.round(sum[j - 1]) + 0.6 * order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 0) { sum[j - 1] = Math.round(sum[j - 1]) + order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 2) { sum[j - 1] = Math.round(sum[j - 1]) + 0.8 * order[j - 1].records[number[j - 1]].getPrice(); } number[j - 1]++; beforesum[j - 1] = order[j - 1].getTotalPrice(); } }//点普通菜的记录 if(flag == 5) { //当点特色菜的的时候 int suitable_s = 1;//判断辣口味度是否合适 int suitable_a = 1;//判断酸口味度是否合适 int suitable_w = 1;//判断甜口味度是否合适 for (int i = 0; i < flag1; i++) { if (count[1].equals(menu.dishs[i].name)) { flag2 = 1; break; } } for (String s : list) {//从辣中判断 if (count[1].equals(s)) { if ((Integer.parseInt(count[2]) < 0) || (Integer.parseInt(count[2]) > 5)) { System.out.println("spicy num out of range :" + Integer.parseInt(count[2])); suitable_s = 0; } else { fenshu_spicy[j - 1] += Integer.parseInt(count[4]); //list_s[number[j - 1]] = Integer.parseInt(count[2]); spicy[k] += (Integer.parseInt(count[2]) * Integer.parseInt(count[4])); }//记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } }//判断这个菜是否再菜单中有 for (String s : list1) {//从酸中判断 if (count[1].equals(s)) { if ((Integer.parseInt(count[2]) < 0) || (Integer.parseInt(count[2]) > 4)) { System.out.println("acidity num out of range :" + Integer.parseInt(count[2])); suitable_a = 0; }else { fenshu_acidity[j - 1] += Integer.parseInt(count[4]); //list_a[number[j - 1]] = Integer.parseInt(count[2]); acidity[k] += (Integer.parseInt(count[2]) * Integer.parseInt(count[4])); } //记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } }//判断这个菜是否再菜单中有 for (String s : list2) {//从甜中判断 if (count[1].equals(s)) { if ((Integer.parseInt(count[2]) < 0) || (Integer.parseInt(count[2]) > 3)) { System.out.println("sweetness num out of range :" + Integer.parseInt(count[2])); suitable_w = 0; } else { fenshu_sweetness[j - 1] += Integer.parseInt(count[4]); //list_w[number[j - 1]] = Integer.parseInt(count[2]); sweetness[k] += (Integer.parseInt(count[2]) * Integer.parseInt(count[4])); //记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } } }//判断这个菜是否再菜单中有 if (flag2 == 1 && suitable_a == 1 && suitable_s == 1 && suitable_w == 1) { //当存在 order[j - 1].addARecord(Integer.parseInt(count[0]), count[1], Integer.parseInt(count[3]), Integer.parseInt(count[4]), menu); System.out.println(Integer.parseInt(count[0]) + " " + count[1] + " " + order[j - 1].records[number[j - 1]].getPrice()); //输出单笔 if (flag3 == 1) { sum[j - 1] = Math.round(sum[j - 1]) + 0.7 * order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 0) { sum[j - 1] = Math.round(sum[j - 1]) + order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 2) { sum[j - 1] = Math.round(sum[j - 1]) + 0.7 * order[j - 1].records[number[j - 1]].getPrice(); } number[j - 1]++; beforesum[j - 1] = order[j - 1].getTotalPrice(); } } if(flag == 6){ int suitable_s = 1;//判断辣口味度是否合适 int suitable_a = 1;//判断酸口味度是否合适 int suitable_w = 1;//判断甜口味度是否合适 for (int i = 0; i < flag1; i++) { if (count[2].equals(menu.dishs[i].name)) { flag2 = 1; break; } } for (String s : list) {//从辣中判断 if (count[2].equals(s)) { if ((Integer.parseInt(count[3]) < 0) || (Integer.parseInt(count[3]) > 5)) { System.out.println("spicy num out of range :" + Integer.parseInt(count[3])); suitable_s = 0; } else { fenshu_spicy[Integer.parseInt(count[0]) - 1] += Integer.parseInt(count[5]); //list_s[number[j - 1]] = Integer.parseInt(count[2]); spicy[Integer.parseInt(count[0]) - 1] += (Integer.parseInt(count[3]) * Integer.parseInt(count[5])); }//记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } }//判断这个菜是否再菜单中有 for (String s : list1) {//从酸中判断 if (count[2].equals(s)) { if ((Integer.parseInt(count[3]) < 0) || (Integer.parseInt(count[3]) > 4)) { System.out.println("acidity num out of range :" + Integer.parseInt(count[3])); suitable_a = 0; }else { fenshu_acidity[Integer.parseInt(count[0]) - 1] += Integer.parseInt(count[5]); //list_a[number[j - 1]] = Integer.parseInt(count[2]); acidity[Integer.parseInt(count[0]) - 1] += (Integer.parseInt(count[3]) * Integer.parseInt(count[5])); } //记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } }//判断这个菜是否再菜单中有 for (String s : list2) {//从甜中判断 if (count[2].equals(s)) { if ((Integer.parseInt(count[3]) < 0) || (Integer.parseInt(count[3]) > 3)) { System.out.println("sweetness num out of range :" + Integer.parseInt(count[3])); suitable_w = 0; } else { fenshu_sweetness[Integer.parseInt(count[0]) - 1] += Integer.parseInt(count[5]); //list_w[number[j - 1]] = Integer.parseInt(count[2]); sweetness[Integer.parseInt(count[0]) - 1] += (Integer.parseInt(count[3]) * Integer.parseInt(count[5])); //记录对应菜系的口味度,放在不同的数组里,以用来计算最终口味度 } } }//判断这个菜是否再菜单中有 if (flag2 == 1 && suitable_a == 1 && suitable_s == 1 && suitable_w == 1) { //当存在 order[j - 1].addARecord(Integer.parseInt(count[1]), count[2], Integer.parseInt(count[4]), Integer.parseInt(count[5]), menu); System.out.println(Integer.parseInt(count[1]) + " " + "table" + " " + j + " pay for table " + Integer.parseInt(count[0]) + " " + order[j - 1].records[number[j - 1]].getPrice()); //输出单笔 if (flag3 == 1) { sum[j - 1] = Math.round(sum[j - 1]) + 0.7 * order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 0) { sum[j - 1] = Math.round(sum[j - 1]) + order[j - 1].records[number[j - 1]].getPrice(); } if (flag3 == 2) { sum[j - 1] = Math.round(sum[j - 1]) + 0.7 * order[j - 1].records[number[j - 1]].getPrice(); } number[j - 1]++; beforesum[j - 1] = order[j - 1].getTotalPrice(); } } if (flag2 == 0) { //当菜名不存在时 System.out.println(count[1] + " does not exist"); } flag2 = 0; } int delete = -1; if(flag == 2 && count[1].equals("delete")) {//删除的记录 for (int i = 0; i < number[j - 1]; i++) { if (Integer.parseInt(count[0]) == order[j - 1].records[i].orderNum) { delete = 0; beforesum[j - 1] -= order[j - 1].records[i].getPrice(); int real_s = 1; int real_a = 1; int real_w = 1; for (String s : list) {//从辣中判断 if (count[1].equals(s)) { real_s = 0; break; } } for (String s : list1) {//从酸中判断 if (count[1].equals(s)){ real_a = 0; break; } } for (String s : list2) {//从甜中判断 if (count[1].equals(s)){ real_w = 0; break; } } if ( real_s == 1 && real_a == 1 && real_w == 1){ if (flag3 == 1) { sum[j - 1] = Math.round(sum[j - 1]) - 0.6 * order[j - 1].records[i].getPrice(); } if (flag3 == 0) { sum[j - 1] = Math.round(sum[j - 1]) - order[j - 1].records[i].getPrice(); } if (flag3 == 2) { sum[j - 1] = Math.round(sum[j - 1]) - 0.8 * order[j - 1].records[i].getPrice(); } }else { if (flag3 == 1) { sum[j - 1] = Math.round(sum[j - 1]) - 0.7 * order[j - 1].records[i].getPrice(); } if (flag3 == 0) { sum[j - 1] = Math.round(sum[j - 1]) - order[j - 1].records[i].getPrice(); } if (flag3 == 2) { sum[j - 1] = Math.round(sum[j - 1]) - 0.7 * order[j - 1].records[i].getPrice(); } } break; } } if(delete == -1) { System.out.println("delete error"); } delete = -1; } } else { //菜品录入 if (flag == 2) { int f2 = 0;//用来判断是否菜品价格为整数 int len1 = count[1].length(); for (int i = 0; i < len1; i++) { if (!Character.isDigit(count[1].charAt(i))) { System.out.println("wrong format"); f2 = 1; break; } } if (f2 == 0) { if (Integer.parseInt(count[1]) > 300 || Integer.parseInt(count[1]) < 0) { System.out.println(count[0] + " price out of range " + Integer.parseInt(count[1])); } else { menu.addDish(count[0], Integer.parseInt(count[1])); num[flag1] = 0; //如果是普通菜就赋值0,代表 flag1++; } } } if(flag == 3){ System.out.println("wrong format"); } if (flag == 4) { //特价菜的菜单录入 if (count[3].equals("T")) { menu.addDish(count[0], Integer.parseInt(count[2])); if (count[1].equals("川菜")) { list[flag1] = count[0];//如果是川菜就赋值,代表川菜 num[flag1] = 1; flag1++; } if (count[1].equals("晋菜")) { list1[flag1] = count[0];//如果是晋菜就赋值,代表晋菜 num[flag1] = 2; flag1++; } if (count[1].equals("浙菜")) { list2[flag1] = count[0];//如果是浙菜就赋值,代表浙菜 num[flag1] = 3; flag1++; }//记录不同菜系判断口味度需要 } } } if(end == 1){ k++; break; } } //最终的输出 for(int i = 0; i < k ; i++) { //依次输出每一桌 spicy[i] = Math.round(spicy[i] / fenshu_spicy[i]); acidity[i] = Math.round(acidity[i] / fenshu_acidity[i]); sweetness[i] = Math.round(sweetness[i] / fenshu_sweetness[i]); //每个桌子结束后,计算口味度 if(fenshu_spicy[i] != 0 && fenshu_acidity[i] == 0 && fenshu_sweetness[i] == 0) {//只有川菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 川菜 " + fenshu_spicy[i] + " " + show_spicy[(int) spicy[i]]); } if(fenshu_spicy[i] == 0 && fenshu_acidity[i] != 0 && fenshu_sweetness[i] == 0) {//只有晋菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 晋菜 " + fenshu_acidity[i] + " " + show_acidity[(int) acidity[i]]); } if(fenshu_spicy[i] == 0 && fenshu_acidity[i] == 0 && fenshu_sweetness[i] != 0) {//只有浙菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 浙菜 " + fenshu_sweetness[i] + " " + show_sweetness[(int) sweetness[i]]); } if(fenshu_spicy[i] != 0 && fenshu_acidity[i] != 0 && fenshu_sweetness[i] == 0) { //没有浙菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 川菜 " + fenshu_spicy[i] + " " + show_spicy[(int) spicy[i]] + " 晋菜 " + fenshu_acidity[i] + " " + show_acidity[(int) acidity[i]]); } if(fenshu_spicy[i] != 0 && fenshu_acidity[i] == 0 && fenshu_sweetness[i] != 0) {//没有晋菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 川菜 " + fenshu_spicy[i] + " " + show_spicy[(int) spicy[i]] + " 浙菜 " + fenshu_sweetness[i] + " " + show_sweetness[(int) sweetness[i]]); } if(fenshu_spicy[i] == 0 && fenshu_acidity[i] != 0 && fenshu_sweetness[i] != 0) {//没有川菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 晋菜 " + fenshu_acidity[i] + " " + show_acidity[(int) acidity[i]] + " 浙菜 " + fenshu_sweetness[i] + " " + show_sweetness[(int) sweetness[i]]); } if(fenshu_spicy[i] != 0 && fenshu_acidity[i] != 0 && fenshu_sweetness[i] != 0) {//都有 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " 川菜 " + fenshu_spicy[i] + " " + show_spicy[(int) spicy[i]] + " 晋菜 " + fenshu_acidity[i] + " " + show_acidity[(int) acidity[i]] + " 浙菜 " + fenshu_sweetness[i] + " " + show_sweetness[(int) sweetness[i]]); } if(fenshu_spicy[i] == 0 && fenshu_acidity[i] == 0 && fenshu_sweetness[i] == 0) {//没有川菜 System.out.println("table " + table_num[i] + ": " + Math.round(beforesum[i]) + " " + Math.round(sum[i]) + " "); } } if(j == 1) { System.out.println(name[0] + " " + telephone[0] + " " + Math.round(sum[j - 1])); } else { for (int i = 1; i < j; i++) { if (name[i].equals(name[i - 1])) { sum[i] += sum[i - 1]; sum[i - 1] = 0; } } int change_name = 0; String name1;//中介类 String tele1;//中介类 double sum1;//中介类 for (int i = 1; i < j; i++) { if (!name[i].equals(name[i - 1])) { int m; int l1 = name[i].length(); int l2 = name[i - 1].length(); m = Math.min(l1, l2); for (int n = 0; n < m; n++) { if (name[i - 1].charAt(n) > name[i].charAt(n)) { change_name = i; break; } } if(change_name == i) { name1 = name[i - 1]; name[i - 1] = name[i]; name[i] = name1; tele1 = telephone[i - 1]; telephone[i - 1] = telephone[i]; telephone[i] = tele1; sum1 = sum[i - 1]; sum[i - 1] = sum[i]; sum[i] = sum1; } change_name = 0; } } for (int i = 0; i < j; i++) { if (sum[i] != 0) { System.out.println(name[i] + " " + telephone[i] + " " + Math.round(sum[i])); } } } } }
我的分析:
在一些地方可能存在一些错误处理不充分的情况。例如在Menu类的searchDish方法中,如果没有找到对应的菜品,返回的是null。在调用这个方法的地方,最好对返回值进行判空处理,以避免可能的空指针异常。在Menu类中,使用了一个固定大小的菜品数组来保存菜单信息。这种设计可能限制了菜品数量的扩展性。建议考虑使用动态数据结构,如ArrayList,以便更好地支持菜单的增加和删除操作。在Order类中,计算订单总价的方法(getTotalPrice())使用了一个for循环来遍历订单的每一条记录,并累加价格。这段逻辑是正确的,但可以根据需求进行扩展,比如考虑添加折扣等功能。异常处理: 在Order类的deleteARecordByOrderNum方法中,删除记录的逻辑存在一些问题。当找到匹配的订单并删除之后,没有进行状态更新或任何处理。建议将操作成功与否的信息进行返回。此外,处理时应考虑删除非法的序号的情况,可能需要添加异常处理。
期中考试试题
7-1 测验1-圆类设计
创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积
输入格式:
输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况
输出格式:
输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度)
我的类图:

我的代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Circle circle = new Circle(); double r = sc.nextDouble(); double area; if (r > 0) { circle.setR(r); area = circle.setArea(); System.out.println(String.format("%.2f", area)); } else { System.out.println("Wrong Format"); } } } class Circle { private double r; Circle() { } public double setArea() { double area = Math.PI * r * r; return area; } public double getR() { return r; } public void setR(double r) { this.r = r; } }
测试点参考:

我的分析:
错误处理:当前代码对半径的输入进行了基本的错误判断,如果半径小于等于0,则输出"Wrong Format"。然而,可能还需要进一步验证用户输入的类型是否正确,以防止出现异常或错误的输入。例如,可以使用try-catch块来捕获用户输入非数字的情况。输入验证:如果需要更复杂的输入验证,例如只允许输入数值范围在一定范围内的情况,可以在setR方法中添加验证逻辑,确保输入值满足特定条件。方法命名:在Circle类中,setArea方法的命名可能会引起困惑,因为它并没有设置任何值,而是计算并返回圆的面积。考虑将其命名为calculateArea或getArea,以更准确地反映其功能。注释和文档:在代码中,添加注释以解释类和方法的目的、参数和返回值的含义,以使代码更易读和理解。此外,可以添加文档来详细描述类和方法的使用方法和注意事项。
7-2 测验2-类结构设计
设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:

输入格式:
分别输入两个坐标点的坐标值x1,y1,x2,y2。
输出格式:
输出该矩形的面积值(保留两位小数)。
我的类图:

我的代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Rectangle rectangle = new Rectangle(); double x1, x2, y1, y2; x1 = sc.nextDouble(); rectangle.setX(x1); y1 = sc.nextDouble(); rectangle.setY(y1); x2 = sc.nextDouble(); rectangle.setX(x2); y2 = sc.nextDouble(); rectangle.setY(y2); double length = rectangle.getLength(x1, x2); double height = rectangle.getHeight(y1, y2); double area = rectangle.getArea(); System.out.println(String.format("%.2f",area)); } } class Rectangle extends Point { private Point topLeftPoint; private Point lowerRightPoint; private double length; private double height; private double area; public Rectangle() { } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength(double x1, double x2) { length = x1 - x2; return (length < 0) ? -length : length; } public double getHeight(double y1, double y2) { height = y1 - y2; return (height < 0) ? -height : height; } public double getArea() { area = length * height; return (area < 0) ? -area : area; } } class Point { public double x; public double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } }
测试点参考:

我的分析:
这题代码我并没有用题目建议的类来写,但最后答案确实是对的,我省去了一些麻烦的步骤,用的是较简单的方法,但是代码中也会存在很多问题。代码中对输入的坐标值没有进行有效性验证。在输入坐标值之后,可以对其进行验证,以确保输入值的合法性。在Rectangle类中,计算矩形长度和高度的方法(getLength和getHeight)使用了绝对值函数来确保结果为正数。这样的设计可以避免负数结果的出现。 在Rectangle类中,length、height和area等变量没有使用private修饰,并且可以直接访问。建议将这些变量设置为私有,并通过对应的getter和setter方法进行操作,以封装数据并提供更好的控制。 在Point类中,提供了两个构造方法,但在Rectangle类的默认构造方法中没有使用这些构造方法。建议在默认构造方法中使用提供的构造方法来创建topLeftPoint和lowerRightPoint对象。代码中没有定义toString方法来提供对象的字符串表示。建议在Point和Rectangle类中实现toString方法,方便调试和打印对象信息。
7-3 测验3-继承与多态
将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:

试编程完成如上类图设计,主方法源码如下(可直接拷贝使用):
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
switch(choice) {
case 1://Circle
double radiums = input.nextDouble();
Shape circle = new Circle(radiums);
printArea(circle);
break;
case 2://Rectangle
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
Point leftTopPoint = new Point(x1,y1);
Point lowerRightPoint = new Point(x2,y2);
Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
printArea(rectangle);
break;
}
}
其中,printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。
输入格式:
输入类型选择(1或2,不考虑无效输入)
对应图形的参数(圆或矩形)
输出格式:
图形的面积(保留两位小数)
我的类图:

我的代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); int choice = sc.nextInt(); switch(choice) { case 1://Circle double radium = sc.nextDouble(); Shape circle = new Circle(radium); if(radium>0) { double area1 = circle.getArea(); System.out.println(String.format("%.2f", area1)); } else{ System.out.println("Wrong Format"); } break; case 2://Rectangle double x1 = sc.nextDouble(); double y1 = sc.nextDouble(); double x2 = sc.nextDouble(); double y2 = sc.nextDouble(); Point leftTopPoint = new Point(x1,y1); Point lowerRightPoint = new Point(x2,y2); Rectangle rectangle = new Rectangle(leftTopPoint, lowerRightPoint) { }; double length = rectangle.getLength(x1, x2); double height = rectangle.getHeight(y1, y2); double area2=rectangle.getArea(); System.out.println(String.format("%.2f",area2)); break; } } } abstract class Shape{ public double area; abstract void Shape(); double getArea(){ return area; } } abstract class Rectangle extends Shape { private Point topLeftPoint; private Point lowerRightPoint; private double length; private double height; private double area; void Shape(){ } public Rectangle() { } public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public Point getTopLeftPoint() { return topLeftPoint; } public void setTopLeftPoint(Point topLeftPoint) { this.topLeftPoint = topLeftPoint; } public Point getLowerRightPoint() { return lowerRightPoint; } public void setLowerRightPoint(Point lowerRightPoint) { this.lowerRightPoint = lowerRightPoint; } public double getLength(double x1, double x2) { length = x1 - x2; return (length < 0) ? -length : length; } public double getHeight(double y1, double y2) { height = y1 - y2; return (height < 0) ? -height : height; } public double getArea() { area = length * height; return (area < 0) ? -area : area; } } class Circle extends Shape{ private double radiums; void Shape(){ } public Circle() { } public Circle(double radiums) { this.radiums = radiums; } public double getRadiums() { return radiums; } public void setRadiums(double radiums) { this.radiums = radiums; } public double getArea(){ double area=3.141592657*radiums*radiums; return area; } } class Point { public double x; public double y; public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } }
我的分析:
这题因为第二题也没有按照标准写法,所以第三题也没办法按照标准的写了,只能继续沿着自己的思路写下去,还好写的也没有非常曲折,最后测试点还是顺利通过了。代码也仍然存在一些问题:缺少错误处理,代码中没有对用户的输入进行验证和错误处理。用户可能会输入无效的数据,例如非数字字符或负数。应该添加输入验证逻辑,以确保输入的数据类型正确且合法。以及代码中缺少注释来解释类和方法的目的、参数和返回值的含义。建议通过注释来提供必要的解释,以提高代码的可读性和可维护性。此外,可以添加文档来详细描述类和方法的使用方法和注意事项。
7-4 测验4-抽象类与接口
在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
提示:题目中Shape类要实现Comparable接口。
其中,Main类源码如下(可直接拷贝使用):
public class Main {
public static void main(String\[\] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
ArrayList<Shape> list = new ArrayList<>();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://Circle
double radiums = input.nextDouble();
Shape circle = new Circle(radiums);
list.add(circle);
break;
case 2://Rectangle
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
Point leftTopPoint = new Point(x1,y1);
Point lowerRightPoint = new Point(x2,y2);
Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
list.add(rectangle);
break;
}
choice = input.nextInt();
}
list.sort(Comparator.naturalOrder());//正向排序
for(int i = 0; i < list.size(); i++) {
System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
}
}
}
输入格式:
输入图形类型(1:圆形;2:矩形;0:结束输入)
输入图形所需参数
输出格式:
按升序排序输出列表中各图形的面积(保留两位小数),各图形面积之间用空格分隔。
我的类图:

我的代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); ArrayList<Shape> shapeList = new ArrayList<>(); int choice = scanner.nextInt(); while (choice != 0) { switch (choice) { case 1: // Circle double radius = scanner.nextDouble(); Shape circle = new Circle(radius); shapeList.add(circle); break; case 2: // Rectangle double x1 = scanner.nextDouble(); double y1 = scanner.nextDouble(); double x2 = scanner.nextDouble(); double y2 = scanner.nextDouble(); Point topLeftPoint = new Point(x1, y1); Point lowerRightPoint = new Point(x2, y2); Rectangle rectangle = new Rectangle(topLeftPoint, lowerRightPoint); shapeList.add(rectangle); break; } choice = scanner.nextInt(); } shapeList.sort(Comparator.naturalOrder()); for (Shape shape : shapeList) { System.out.print(String.format("%.2f", shape.getArea()) + " "); } } } abstract class Shape implements Comparable<Shape> { abstract double getArea(); @Override public int compareTo(Shape other) { return Double.compare(this.getArea(), other.getArea()); } } class Rectangle extends Shape { private Point topLeftPoint; private Point lowerRightPoint; public Rectangle(Point topLeftPoint, Point lowerRightPoint) { this.topLeftPoint = topLeftPoint; this.lowerRightPoint = lowerRightPoint; } public double getLength() { double length = topLeftPoint.getX() - lowerRightPoint.getX(); return (length < 0) ? -length : length; } public double getHeight() { double height = topLeftPoint.getY() - lowerRightPoint.getY(); return (height < 0) ? -height : height; } public double getArea() { double area = getLength() * getHeight(); return (area < 0) ? -area : area; } } class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public double getArea() { double area = Math.PI * radius * radius; return area; } } class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } }
测试点参考:

我的分析:这题需要比较严谨地按照题目要求来写,一开始我没有掌握比较的知识,后面经过学习才得以获得满分,但代码中还是存在着些许不足的。代码中没有对用户输入进行错误处理。考虑添加适当的输入验证逻辑,以确保输入的数据类型正确且合法。可以使用try-catch块来捕获可能的异常,并给用户相应的提示。注释和文档:代码中缺少注释和文档来说明类、方法和变量的用途、参数和返回值等信息。建议添加适当的注释来提高代码的可读性和可维护性。还可以为类、方法和变量添加Javadoc注释,以便通过生成文档来查看详细的说明。代码中使用了while循环来读取和处理用户输入,这是一个有效的方式。可以考虑使用增强的for循环来遍历形状列表,以使代码更加简洁和易读。使用Comparator.naturalOrder()对形状列表进行排序是可行的。但需要注意的是,如果形状类中存在相同面积的情况,可能会出现不稳定的排序结果。可以考虑添加额外的排序规则,以确保相同面积的形状按照特定规则进行排序。
心得体会:
题目整体难度都在选课系统上,只能可怜的捞到一些分,所以没什么太多权威性的分析。期中考试试题可以说是比较简单,做得比较顺手的一次,做的过程中没有非常多的困难,感觉自己的代码逻辑性还有很大的进步空间,我应该要多根据题目的要求来标准化自己的代码比较好,这样的话后续的改进也会比较方便,而不是一拿到题目就先按照自己的思路乱写一通。
改进建议:
1.
感觉自己的代码逻辑性还有很大的进步空间,以及自己对Java的理解还不够透彻,还有很多需要学的东西,这与自己平常没有太注重语言的学习有很大关系,学到头来发现很多知识自己都只是懵懵懂懂记得,但根本不会用,学了也等于白学,所以我还需要锻炼自己写代码的逻辑能力,尽量在每次写代码之前脑子里都要有一个自己的基本框架,不要急于求成,静下心来学会解决问题。
2.
代码还有很大的空间需要改进,我还需要学习优化代码的能力,比如一些输入输出的超时问题,还有自己代码有很多赘余的需要删减等,有一些题目可以用到更简单的方法,但是大部分题目还是应该按照思路来写,自己有一些投机取巧的方法是不可取的。
总结:
1.学到的Java基础知识
基础概念/语法:面向对象(继承、封装、多态)基础、包、类、接口、方法、对象、属性、第一个 Java 程序。
数据类型:1)基本数据类型8种:byte、short、int、long、float、double、char、boolean;2)引用数据类型
变量类型:局部变量、实例变量(成员变量)、类变量(静态变量)
修饰符:public、private、不写、protected、static、final、abstract、synchronized ,volatile
运算符:1)算术运算符:+、-、*、/、%、++、--;2)关系运算符:==、!=、>、<、>=、<=;3)逻辑运算符:&&、||、!;4)赋值运算符:=、+=、-=、*=、/=;5)条件运算符:Object x = (expression) ? value if true : value if false;
循环结构:for 循环、while 循环、do...while 循环
条件语句:if...else、if...else if...else
异常处理:try...catch...finally、throws、throw
字符串:String、StringBuilder、StringBuffer
其他:switch case、数组、日期时间、枚举、使用 IDE 进行 DEBUG
2.需要进一步学习的地方
类与对象、类的封装、继承与多态等知识的更深入学习,并将这些知识更加合理的运用到自己的代码里。
3.对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见
java的学习过程终于告一段落了,经过漫长的下学期的学习,我对java这门语言有了更深刻的了解,也明白java的内容非常庞大,还需要我们不断去挖掘学习,这和我们上学期的浅学c语言的感觉完全不一样,这个学期的题目全部都偏难,并且农夫过河的实验的渐渐推进也让我学到了很多新的知识,希望自己在以后的学习过程中能够更加认真,更加独立地完成作业,而不是等到截止前匆匆忙忙赶,这样就会导致自己的思考时间大大缩短,最后也很感谢一学期以来老师的教导,和这些题目,没有这些我可能java基本的知识都很难掌握。
posted on
浙公网安备 33010602011771号