题目集4~6总结心得
Posted wyk24
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题目集4~6总结心得相关的知识,希望对你有一定的参考价值。
1.前言
第四次题目集是三次题目集里题量最大的一次,二到四题主要是练习对数据的判断,处理,包括对数据的查找,删除排序,总体难度不是很大,但对算法有很高要求,容易运行超时。第一题和第五题主要练习我们对类与对象的使用,其中第一题更难,需要写多个类,题目较为复杂,难度大。第七题又是判断日期先后,计算隔天数,与前面的题目相比,我们不用自己写各种日期类和判断日期的方法,这次我们可以使用java里原本就有的有关日期的方法。难度不大。
第五次题目集题量看起来很大,但是前四题都比较简单,要求使用正则表达式。后两题是在第三次题目集的基础上,两题都给我们提供了类图,要求我们按类图要求写题,把以前的代码进行修改,难度还行。
第六次题目集就一题,是三次作业中最难的一题,要求特别多,测试点多,难度大。是在第四次第一题的基础上,增加更多需求,里面有复杂的判断条件。给出了多种异常情况,需要在程序中进行处理。
2.设计与分析
训练集004第一题:7-1 菜单计价程序-3
分数 30
作者 蔡轲
单位 南昌航空大学
设计点菜计价程序,根据输入的信息,计算并输出总价格。
输入内容按先后顺序包括两部分:菜单、订单,最后以"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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
试题分析:
这是比较复杂的一题,需要我们综合运用类的知识 ,包括类的定义,类的组合等。
本题要求设计一个点菜程序,需要实现以下功能:
输入菜单信息,包括菜名和基础价格;
输入订单信息,包括桌号标识、点菜记录、删除信息和代点菜信息;
计算每桌的总价,包括折扣计算;
输出每桌的订单记录处理信息和总价。
我们可以先定义一些类来实现这些功能:
Dish类:表示菜品,包含菜名和基础价格;
Menu类:表示菜单,包含所有菜品信息,可以通过菜名查找菜品信息;
Record类:表示点菜记录,包含序号、菜品信息、份额和份数,可以计算该记录的价格;
Order类:表示订单,包含多条点菜记录,可以添加、删除、查找记录,可以计算订单的总价;
Table类:表示桌子,包含桌号、订单信息和总价,可以添加、删除、查找订单,可以计算桌子的总价;
这题当时没有写,因为第四次作业题量较大,我第一次见过一道题的题目有这么长,看了一下题目,直接被吓的跳过了。然后做完后面的题目,没有时间来做这道题了。主要是对时间把控不到位,没有把时间全部用在写题目上,以后要注意。还有就是没有那种勇于探索的精神,遇到困难直接放弃了。
训练集004第三题:7-3 去掉重复的数据
分数 10
作者 翁恺
单位 浙江大学
在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,去掉所有重复的数字。最后按照输入顺序输出没有重复数字的数据。所有重复的数字只保留第一次出现的那份。
输入格式:
你的程序首先会读到一个正整数 n,1≤n≤100000。
然后是 n 个整数,这些整数的范围是 [1, 100000]。
输出格式:
在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格。
输入样例:
5
1 2 2 1 4
输出样例:
1 2 4
代码长度限制
16 KB
时间限制
1500 ms
内存限制
150 MB
源代码展示:
查看代码
import java.util.Scanner;
import java.util.LinkedHashSet;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();
LinkedHashSet<Integer> set = new LinkedHashSet<>();
for(int i = 0;i<n;i++)
set.add(input.nextInt());
String number = set.toString();
String numbers=number.substring(1,number.length()-1);
String[] split = numbers.split(",");
for(int i = 0;i<split.length;i++)
System.out.print(split[i]);
试题代码分析:
本题题目容易,但是很容易超时,为了让这题运行不会超时,我使用了LinkedHashSet,可以自动将输入的数据中重复的东西去除,且不会改变数据输入时的数据,但是用LinkedHashSet会使数据有,[]这些符号,我们用substring把一头一尾的[]去掉,然后用split分割字符串,遇到,就分割一次,刚好就可以正确输出。
SourceMonitor生成的报表内容:
踩坑心得:
一开始使用数组来存入数据,然后一一遍历,删除重复数据,从逻辑上是对的但是运行超时了,然后我又想使用二分法提高运行效率,结果还是超时,最后用hashset存入数据,结果发现答案错误,查找资料得知,hashset在存入数据时虽然不会输入重复数据,但是可能改变顺序,最后是用了LinkHashset才做对的。
改进建议:
用linkhashset可以做对这题,但并不是常归方法,如果可以用数组或arrylist存入数据,用简单的算法做出这题会更好。
训练集004第四题:7-4 单词统计与排序
分数 15
作者 张峰
单位 山东科技大学
从键盘录入一段英文文本(句子之间的标点符号只包括“,”或“.”,单词之间、单词与标点之间都以" "分割。
要求:按照每个单词的长度由高到低输出各个单词(重复单词只输出一次),如果单词长度相同,则按照单词的首字母顺序(不区分大小写,首字母相同的比较第二个字母,以此类推)升序输出。
输入格式:
一段英文文本。
输出格式:
按照题目要求输出的各个单词(每个单词一行)。
输入样例:
Hello, I am a student from China.
输出样例:
student
China
Hello
from
am
a
I
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源代码展示:
查看代码
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
String[] word = new String[100];
int[] num = new int[100];
String t = null;
int a = 0,m=19;
String english = input.nextLine();
String[] split = english.split(" ");
for(int i = 0;i < split.length;i++)
for(int j=0;j<split[i].length();j++)
if(split[i].charAt(j)==\',\'||split[i].charAt(j)==\'.\')
split[i] = split[i].substring(0,split[i].length()-1);
for(int i = 0;i < split.length;i++)
split[i].toLowerCase();
for(int i = 0;i < split.length;i++)
num[i] = split[i].length();
for(int i = 0;i<split.length;i++)
for(int j = 0;j < split.length - i - 1;j ++)
if(num[j] < num[j+1])
t = split[j];
split[j] = split[j+1];
split[j+1] = t;
a = num[j];
num[j] = num[j+1];
num[j+1] = a;
//if(num[j]==num[j+1])
for(int i = 0;i<split.length;i++)
for(int j = 0;j < split.length - i - 1;j ++)
for(int k = 0;k<num[j];k++)
if(num[j]==num[j+1]&&split[j].toLowerCase().charAt(k) > split[j+1].toLowerCase().charAt(k))
t = split[j];
split[j] = split[j+1];
split[j+1] = t;
a = num[j];
num[j] = num[j+1];
num[j+1] = a;
break;
if(num[j]!=num[j+1])
break;
if(split[j].equals(split[j+1]))
break;
if(split[j].toLowerCase().charAt(k)==split[j+1].toLowerCase().charAt(k))
continue;
if(split[j].toLowerCase().charAt(k) < split[j+1].toLowerCase().charAt(k))
break;
System.out.println(split[0]);
for(int i=1;i<split.length;i++)
if(split[i].equals(split[i-1]))
continue;
System.out.println(split[i]);
试题代码分析:
输入一个长字符串,用split分割这个字符串,当遇到空格、逗号或句号时就分割一次。接下来判断子字符串长度,按长度递减排列,如果遇到相同长度的字符,就比较首字母的先后顺序,如果还是相等就往后比较,如果比到最后一位还是相等,则说明两个字符相同,结束本次循环,不输出重复字符串。
SourceMonitor生成的报表内容:
踩坑心得:
在写代码的时候没有考虑到同一个单词可能出现在不同位置多次,一开始使用的类似冒泡法来排序,当在不同位置出现多个相同的单词且字符长度相同时,排序可能不正确。导致较长文本输出错误。
改进建议:
for循环写的不够简化,可以优化for循环。
训练集004第五题:7-5 日期问题面向对象设计(聚合一)
分数 50
作者 段喜龙
单位 南昌航空大学
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
1 year month day n //测试输入日期的下n天
2 year month day n //测试输入日期的前n天
3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
当输入有误时,输出格式如下:
Wrong Format
当第一个数字为1且输入均有效,输出格式如下:
year-month-day
当第一个数字为2且输入均有效,输出格式如下:
year-month-day
当第一个数字为3且输入均有效,输出格式如下:
天数值
输入样例1:
在这里给出一组输入。例如:
3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:
2312
输入样例2:
在这里给出一组输入。例如:
2 1935 2 17 125340
输出样例2:
在这里给出相应的输出。例如:
1591-12-17
输入样例3:
在这里给出一组输入。例如:
1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:
2017-2-24
输入样例4:
在这里给出一组输入。例如:
0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:
Wrong Format
代码长度限制
16 KB
时间限制
10000 ms
内存限制
64 MB
源代码展示:
查看代码
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity())
System.out.println("Wrong Format");
System.exit(0);
m = input.nextInt();
if (m < 0)
System.out.println("Wrong Format");
System.exit(0);
// System.out.print(date.day.getMonth().getYear().getValue() + "-" + date.day.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
else if (choice == 2) // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity())
System.out.println("Wrong Format");
System.exit(0);
n = input.nextInt();
if (n < 0)
System.out.println("Wrong Format");
System.exit(0);
//System.out.print(
// date.day.getMonth().getYear().getValue() + "-" + date.day.getMonth().getValue() + "-" + date.day.getValue() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
else if (choice == 3) //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity())
System.out.println( fromDate.getDaysofDates(toDate));
else
System.out.println("Wrong Format");
System.exit(0);
else
System.out.println("Wrong Format");
System.exit(0);
class DateUtil
//private int day;
Day day;
public DateUtil()
public DateUtil(int d, int m, int y)
this.day = new Day(d,m,y);
// this.d = d;
// this.m = m;
// this.y = y;
public Day getDay()
return day;
public void setDay(Day d)
this.day = d;
public boolean checkInputValidity()
if(day.validate()&&day.getMonth().validate()&&day.getMonth().getYear().validate())
return true;
else
return false;
public boolean compareDates(DateUtil date)
if(day.getMonth().getYear().getValue() > date.day.getMonth().getYear().getValue())
return false;
else if(day.getMonth().getYear().getValue() < date.day.getMonth().getYear().getValue())
return true;
else
if(day.getMonth().getValue() > date.day.getMonth().getValue())
return false;
else if(day.getMonth().getValue() < date.day.getMonth().getValue())
return true;
else
if(day.getValue()>date.day.getValue())
return false;
else
return true;
public boolean equalTwoDates(DateUtil date)
if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getValue()==day.getValue()&&date.day.getMonth().getValue()==day.getMonth().getValue())
return true;
else
return false;
public String showDate()
return (day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue());
public DateUtil getNextNDays(int m)
int d;
/* while(true)
if(day.getMonth().getYear().isLeapYear())
if(m>366)
m=m-366;
day.getMonth().getYear().yearIncrement();
else
break;
else
if(m>365)
m=m-365;
day.getMonth().getYear().yearIncrement();
else
break;
*/
while(true)
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
if(day.getMonth().getYear().isLeapYear())
a[2] = 29;
if(m+day.getValue()<=a[day.getMonth().getValue()])
// for(int i = 0;i < m;i++)
// day.dayIncrement();
d = day.getValue() + m;
break;
if(m+day.getValue()>a[day.getMonth().getValue()])
m=m-a[day.getMonth().getValue()];
day.getMonth().monthIncrement();
if(day.getMonth().getValue()==13)
day.getMonth().resetMin();
day.getMonth().getYear().yearIncrement();
DateUtil nextdate = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), d);
return nextdate;
public DateUtil getPreviousNDays(int m)
// int day1 = day;
// int month1 = month;
// int year1 = year;
int i;
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
while(true)
if(day.getMonth().getYear().isLeapYear())
if(m>366)
m=m-366;
day.getMonth().getYear().yearReduction();
else
break;
else
if(m>365)
m=m-365;
day.getMonth().getYear().yearReduction();
else
break;
for(i=0;i<m;i++)
if(day.getMonth().getYear().isLeapYear())
a[2]=29;
if(day.getValue()==1)
day.getMonth().monthReduction();
if(day.getMonth().getValue()==0)
day.getMonth().resetMax();
day.getMonth().getYear().yearReduction();
day.resetMax();
else
day.dayReduction();
DateUtil beforedate = new DateUtil(day.getMonth().getYear().getValue(), day.getMonth().getValue(), day.getValue());
return beforedate;
public int getDaysofDates(DateUtil date)
boolean b = equalTwoDates(date);
boolean x = compareDates(date);
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
// int[] m = new int[]0,31,28,31,30,31,30,31,31,30,31,30,31;
int year1 = day.getMonth().getYear().getValue();
int month1 =day.getMonth().getValue();
int day1 = day.getValue();
int year2 = date.day.getMonth().getYear().getValue();
int month2 =date.day.getMonth().getValue();
int day2 = date.day.getValue();
int k = 0;
int i;
if(b)
k = 0;
else
if(x)
if(year1<=year2)
for(i=year1;i<year2;i++)
if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
k=k+366;
else
k=k+365;
// if(year==toDate.year)
if(month1<month2)
for(i=month1;i<month2;i++)
if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
a[2]=29;
k=k+a[i];
if(month1>=month2)
for(i=month2;i<month1;i++)
if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
a[2]=29;
k=k-a[i];
k=k+day2-day1;
else
//
if(year1>=year2)
for(i=year2;i<year1;i++)
if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
k=k+366;
else
k=k+365;
// if(year==toDate.year)
if(month2<month1)
for(i=month2;i<month1;i++)
if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
a[2]=29;
k=k+a[i];
if(month2>=month1)
for(i=month1;i<month2;i++)
if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
a[2]=29;
k=k-a[i];
k=k-day2+day1;
return k;
class Day
private int value;
Month month;
int[] mon_maxnum = 31,28,31,30,31,30,31,31,30,31,30,31;
public Day()
public Day(int yearValue, int monthValue, int dayValue)
this.month = new Month(yearValue,monthValue);
this.value = dayValue;
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public Month getMonth()
return month;
public void setMonth(Month value)
this.month = value;
public void resetMin()
value = 1;
public void resetMax()
//if(month.getYear().isLeapYear())
// mon_maxnum[1] = 29;
value = mon_maxnum[month.getValue() - 1];
public boolean validate()
if(month.getValue()>=13||month.getValue()<=0)
return false;
if(month.getYear().isLeapYear())
mon_maxnum[1] = 29;
if(value >= 1&&value <= mon_maxnum[month.getValue() - 1])
return true;
else
return false;
public void dayIncrement ()
value = value + 1;
public void dayReduction ()
value = value - 1;
class Month
private int value;
Year year;
public Month()
public Month(int yearValue, int monthValue)
this.year = new Year(yearValue);
this.value = monthValue;
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public Year getYear()
return year;
public void setYear(Year year)
this.year = year;
public void resetMin()
value = 1;
public void resetMax()
value = 12;
public boolean validate()
if(value >= 1&&value <= 12)
return true;
else
return false;
public void monthIncrement ()
value = value + 1;
public void monthReduction ()
value = value - 1;
class Year
private int value;
public Year()
public Year(int value)
this.value = value;
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public boolean isLeapYear()
if((value%4 == 0&&value%100 != 0)||(value%400 == 0))
return true;
else
return false;
public boolean validate()
if(value>=1900&&value<=2050)
return true;
else
return false;
public void yearIncrement ()
value = value + 1;
public void yearReduction ()
value = value - 1;
试题代码分析:
用了聚合,month里有year,day里有month,在使用年月日的类的时候,层层套用,年月日的类中有不同的方法。
SourceMonitor生成的报表内容:
踩坑心得:
判断年月日的日期合法性时,没有正确调用不同类的方法,导致日期合法性报错。一开始做题时,没有把握好不同类之间的关系,在调用时会出错。
改进建议:
有些方法虽然在类图中有,但是感觉作用不大,可以删除。
训练集005第六题:7-6 日期问题面向对象设计(聚合二)
分数 34
作者 段喜龙
单位 南昌航空大学
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
1 year month day n //测试输入日期的下n天
2 year month day n //测试输入日期的前n天
3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
当输入有误时,输出格式如下:
Wrong Format
当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2
当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2
当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:值
输入样例1:
在这里给出一组输入。例如:
3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:
The days between 2014-2-14 and 2020-6-14 are:2312
输入样例2:
在这里给出一组输入。例如:
2 1834 2 17 7821
输出样例2:
在这里给出相应的输出。例如:
1834-2-17 previous 7821 days is:1812-9-19
输入样例3:
在这里给出一组输入。例如:
1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:
1999-3-28 next 6543 days is:2017-2-24
输入样例4:
在这里给出一组输入。例如:
0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:
Wrong Format
代码长度限制
16 KB
时间限制
10000 ms
内存限制
源代码展示:
查看代码
import java.util.Scanner;
public class Main
public static void main(String[] args)
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity())
System.out.println("Wrong Format");
System.exit(0);
m = input.nextInt();
if (m < 0)
System.out.println("Wrong Format");
System.exit(0);
System.out.print(date.year.getValue() + "-" + date.month.getValue() + "-" + date.day.getValue() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
else if (choice == 2) // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity())
System.out.println("Wrong Format");
System.exit(0);
n = input.nextInt();
if (n < 0)
System.out.println("Wrong Format");
System.exit(0);
System.out.print(
date.year.getValue() + "-" + date.month.getValue() + "-" + date.day.getValue() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
else if (choice == 3) //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity())
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
else
System.out.println("Wrong Format");
System.exit(0);
else
System.out.println("Wrong Format");
System.exit(0);
class Day
private int value;
public Day(int value)
super();
this.value = value;
public Day()
super();
// TODO Auto-generated constructor stub
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public void dayIncrement()
value = value + 1;
public void dayReduction()
value = value - 1;
class Year
private int value;
public Year(int value)
super();
this.value = value;
public Year()
super();
// TODO Auto-generated constructor stub
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public boolean isLeapYear()
if((value%4 == 0&&value%100 != 0)||(value%400 == 0))
return true;
else
return false;
public boolean validate()
if(value >= 1820&&value <= 2020)
return true;
else
return false;
public void yearIncrement()
value = value + 1;
public void yearReduction()
value = value - 1;
class Month
private int value;
public int getValue()
return value;
public void setValue(int value)
this.value = value;
public Month()
super();
// TODO Auto-generated constructor stub
public Month(int value)
super();
this.value = value;
public void resetMin()
value = 1;
public void resetMax()
value = 12;
public boolean validate()
if(value >= 1&&value <= 12)
return true;
else
return false;
public void monthIncrement()
value = value + 1;
public void monthReduction()
value = value - 1;
class DateUtil
Year year;
Month month;
Day day;
int[] mon_maxnum = 31,28,31,30,31,30,31,31,30,31,30,31;
public DateUtil(int y, int m, int d)
super();
this.year = new Year(y);
this.month = new Month(m);
this.day = new Day(d);
public DateUtil()
super();
// TODO Auto-generated constructor stub
public Year getYear()
return year;
public void setYear(Year year)
this.year = year;
public Month getMonth()
return month;
public void setMonth(Month month)
this.month = month;
public Day getDay()
return day;
public void setDay(Day day)
this.day = day;
public void setDayMin()
day.setValue(1);
public void setDayMax()
if(year.isLeapYear())
mon_maxnum[1] = 29;
day.setValue(mon_maxnum[day.getValue() - 1]);
public boolean checkInputValidity()
if(month.validate()&&year.validate()&&day.getValue() >= 1&&day.getValue() <=mon_maxnum[month.getValue() - 1] )
return true;
else
return false;
public DateUtil getNextNDays(int m)
int d;
while(true)
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
if(year.isLeapYear())
a[2] = 29;
if(m+day.getValue()<=a[month.getValue()])
// for(int i = 0;i < m;i++)
// day.dayIncrement();
d = day.getValue() + m;
break;
if(m+day.getValue()>a[month.getValue()])
m=m-a[month.getValue()];
month.monthIncrement();
if(month.getValue()==13)
month.resetMin();
year.yearIncrement();
DateUtil nextdate = new DateUtil(year.getValue(), month.getValue(), d);
return nextdate;
public DateUtil getPreviousNDays(int m)
// int day1 = day;
// int month1 = month;
// int year1 = year;
int i;
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
while(true)
if(year.isLeapYear())
if(m>366)
m=m-366;
year.yearReduction();
else
break;
else
if(m>365)
m=m-365;
year.yearReduction();
else
break;
for(i=0;i<m;i++)
if(year.isLeapYear())
a[2]=29;
if(day.getValue()==1)
month.monthReduction();
if(month.getValue()==0)
month.resetMax();
year.yearReduction();
setDayMax();
else
day.dayReduction();
DateUtil beforedate = new DateUtil(year.getValue(), month.getValue(), day.getValue());
return beforedate;
public boolean compareDates(DateUtil date)
if(year.getValue() > date.year.getValue())
return false;
else if(year.getValue() < date.year.getValue())
return true;
else
if(month.getValue() > date.month.getValue())
return false;
else if(month.getValue() < date.month.getValue())
return true;
else
if(day.getValue()>date.day.getValue())
return false;
else
return true;
public boolean equalTwoDates(DateUtil date)
if(date.year.getValue() == year.getValue()&&date.day.getValue()==day.getValue()&&date.month.getValue()==month.getValue())
return true;
else
return false;
public int getDaysofDates(DateUtil date)
boolean b = equalTwoDates(date);
boolean x = compareDates(date);
int[] a=0,31,28,31,30,31,30,31,31,30,31,30,31;
// int[] m = new int[]0,31,28,31,30,31,30,31,31,30,31,30,31;
int year1 = year.getValue();
int month1 =month.getValue();
int day1 = day.getValue();
int year2 = date.year.getValue();
int month2 =date.month.getValue();
int day2 = date.day.getValue();
int k = 0;
int i;
if(b)
k = 0;
else
if(x)
if(year1<=year2)
for(i=year1;i<year2;i++)
if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
k=k+366;
else
k=k+365;
// if(year==toDate.year)
if(month1<month2)
for(i=month1;i<month2;i++)
if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
a[2]=29;
k=k+a[i];
if(month1>=month2)
for(i=month2;i<month1;i++)
if((year2%4 == 0&&year2%100 != 0)||(year2%400 == 0))
a[2]=29;
k=k-a[i];
k=k+day2-day1;
else
//
if(year1>=year2)
for(i=year2;i<year1;i++)
if((i%4 == 0&&i%100 != 0)||(i%400 == 0))
k=k+366;
else
k=k+365;
// if(year==toDate.year)
if(month2<month1)
for(i=month2;i<month1;i++)
if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
a[2]=29;
k=k+a[i];
if(month2>=month1)
for(i=month1;i<month2;i++)
if((year1%4 == 0&&year1%100 != 0)||(year1%400 == 0))
a[2]=29;
k=k-a[i];
k=k-day2+day1;
return k;
public String showDate()
return (year.getValue()+"-"+month.getValue()+"-"+day.getValue());
试题代码分析:
年月日的类里只有基本属性,各种判断,计算的方法都放在dateutil类里面,判断闰年的方法没有变,重点是由往前一天变到n天,就要考虑有跨年,跨月的情况,我利用上一题的原理,相当于往前加n个一天,用一个for循环每次往前加一天,跨越月份或年份就往前加一,天数从1开始重新记算,用if来实现。往前多少天也是同一原理,先算往前一天,然后用循环。题目还要求可以求两日期的天数差,首先要判断前后输入的日期谁大谁小,按题目要求如果前面的日期大,就返回真,后面大返回假。计算日期差值,以前面的日期大为例:先判断两日期年份是否相同,如果相同就判断月份,不相同就两个年份相减每差一年就加上对就年的天数,然后判断月份,如果是前面的日期月份大,就加上这两月份相差的天数,要是整的月份,反之减去相差天数,最后判断天数,与月份逻辑相同,最后将年月日的得的结果放一起就是差的天数。
SourceMonitor生成的报表内容:
踩坑心得:
计算前多少天后多少天时,算法不是很好,导致运行可能超时。再计算最大值时出现错误。
改进建议:
改进算法,使得计算结果不会出错。
训练集006第一题:7-1 菜单计价程序-4
分数 100
作者 蔡轲
单位 南昌航空大学
本体大部分内容与菜单计价程序-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)//根据序号查找一条记录
本次课题比菜单计价系列-3增加的异常情况:
1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"
2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"
3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。
4、重复删除,重复的删除记录输出"deduplication :"+序号。
5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。
6、菜谱信息中出现重复的菜品名,以最后一条记录为准。
7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。
8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。
9、份额超出范围(1、2、3)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。
10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。
11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。
12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。
13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"
14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。
15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)
16、所有记录其它非法格式输入,统一输出"wrong format"
17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。
本次作业比菜单计价系列-3增加的功能:
菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"
例如:麻婆豆腐 9 T
菜价的计算方法:
周一至周五 7折, 周末全价。
注意:不同的四舍五入顺序可能会造成误差,请按以下步骤累计一桌菜的菜价:
计算每条记录的菜价:将每份菜的单价按份额进行四舍五入运算后,乘以份数计算多份的价格,然后乘以折扣,再进行四舍五入,得到本条记录的最终支付价格。
最后将所有记录的菜价累加得到整桌菜的价格。
输入格式:
桌号标识格式: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 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 1 2
2 delete
2 delete
end
输出样例:
在这里给出相应的输出。例如:
table 31:
1 num out of range 16
2 油淋生菜 18
deduplication 2
table 31: 0 0
输入样例1:
份数超出范围+份额超出范围。例如:
麻婆豆腐 12
油淋生菜 9 T
table 31 2023/2/1 14/20/00
1 麻婆豆腐 1 16
2 油淋生菜 4 2
end
输出样例1:
份数超出范围+份额超出范围。例如:
table 31:
1 num out of range 16
2 portion out of range 4
table 31: 0 0
输入样例2:
桌号信息错误。例如:
麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end
输出样例2:
在这里给出相应的输出。例如:
wrong format
输入样例3:
混合错误:桌号信息格式错误+混合的菜谱信息(菜谱信息忽略)。例如:
麻婆豆腐 12
油淋生菜 9 T
table 55 2023/3/31 12/000/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end
输出样例3:
在这里给出相应的输出。例如:
wrong format
输入样例4:
错误的菜谱记录。例如:
麻婆豆腐 12.0
油淋生菜 9 T
table 55 2023/3/31 12/00/00
麻辣香锅 15
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end
输出样例4:
在这里给出相应的输出。例如:
wrong format
table 55:
invalid dish
麻婆豆腐 does not exist
2 油淋生菜 14
table 55: 14 10
输入样例5:
桌号格式错误(以“table”开头)+订单格式错误(忽略)。例如:
麻婆豆腐 12
油淋生菜 9 T
table a 2023/3/15 12/00/00
1 麻婆 豆腐 1 1
2 油淋生菜 2 1
end
输出样例5:
在这里给出相应的输出。例如:
wrong format
输入样例6:
桌号格式错误,不以“table”开头。例如:
麻婆豆腐 12
油淋生菜 9 T
table 1 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
tab le 2 2023/3/15 12/00/00
1 麻婆豆腐 1 1
2 油淋生菜 2 1
end
输出样例6:
在这里给出相应的输出。例如:
table 1:
1 麻婆豆腐 12
2 油淋生菜 14
wrong format
record serial number sequence error
record serial number sequence error
table 1: 26 17
其他用例请参考公开的测试用例
代码长度限制
50 KB
时间限制
1000 ms
内存限制
64 MB
题目分析:
题目与第四次实验第一题相似,但是上次的实验第一题没有做出来,结果这次也没做出来。
3.总结:
这三次比上三次要难上许多,让我们更加熟练的使用类,对类的理解更深入,也发现许多存在的问题,在遇到难题的时候没有坚忍的心态,导致没有好好努力去做菜单的题目,为此要吸取教训,下次一定挑战到底,无论任何题目都不放弃。给老师的建议:希望以后出比较难的题目时能多给点思路上的提示。<
Blog作业03
目录
前言
设计与分析
踩坑心得
改进建议
总结
前言
这三次作业的题目只有2道题,但是在题量减小的同时,这三次作业集的难度也相应的上去了,题目的质量很好,运用很广泛,也考验了很多的知识点。这三次的作业的知识面比前两次覆盖的更加广泛。
第7次作业集的第一题和第二题都应用了继承,考察了类和构造方法的使用,父类子类的知识。
第8次作业集的1个题目,是对字符串相关知识的考查则可以使用接口,也可以用字符串的知识解决,也复习了基础和类还有构造方法。
第9次作业的题目,是对上次题目集的改编题目比较难,但是后面做起来会简单一点,知识过硬的话也很容易过。
题目集7
题量:2道
难度:较难
7-2:
- 首先,在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0
- 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边不能组成三角形),则输出
Wrong Format
。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n
,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格; - 排序后的各图形类型及面积,格式同排序前的输出;
- 所有图形的面积总和,格式为
Sum of area:总面积值
。
7-3:
输入格式:
- 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0
- 根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出
Wrong Format
。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ]
,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前; - 输出分组后的图形类型及面积,格式为
[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积]
,各组内格式为图形名称:面积值
。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; - 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
- 各组中面积之和的最大值输出,格式为
The max area:面积值
。
题目集8
题量:1道
难度:较难
7-4:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
- 存款、取款功能输入数据格式:
卡号 密码 ATM机编号 金额
(由一个或多个空格分隔), 其中,当金额大于0时,代表取款,否则代表存款。 - 查询余额功能输入数据格式:
卡号
输出格式:
①输入错误处理
- 如果输入卡号不存在,则输出
Sorry,this card does not exist.
。 - 如果输入ATM机编号不存在,则输出
Sorry,the ATM\'s id is wrong.
。 - 如果输入银行卡密码错误,则输出
Sorry,your password is wrong.
。 - 如果输入取款金额大于账户余额,则输出
Sorry,your account balance is insufficient.
。 - 如果检测为跨行存取款,则输出
Sorry,cross-bank withdrawal is not supported.
。
②取款业务输出
输出共两行,格式分别为:
[用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③存款业务输出
输出共两行,格式分别为:
[用户姓名]在[银行名称]的[ATM编号]上存款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
④查询余额业务输出
¥[金额]
金额保留两位小数。
题目集9
题量:1道
难度:较难
7-5:
-
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
- 取款功能输入数据格式:
卡号 密码 ATM机编号 金额
(由一个或多个空格分隔) - 查询余额功能输入数据格式:
卡号
输出格式:
①输入错误处理
- 如果输入卡号不存在,则输出
Sorry,this card does not exist.
。 - 如果输入ATM机编号不存在,则输出
Sorry,the ATM\'s id is wrong.
。 - 如果输入银行卡密码错误,则输出
Sorry,your password is wrong.
。 - 如果输入取款金额大于账户余额,则输出
Sorry,your account balance is insufficient.
。
②取款业务输出
输出共两行,格式分别为:
业务:取款 [用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③查询余额业务输出
业务:查询余额 ¥[金额]
金额保留两位小数。
- 取款功能输入数据格式:
设计与分析
import java.util.ArrayList; import java.util.Scanner; import java.util.TreeSet; public class Main { public static Scanner input = new Scanner(System.in); public static void main(String[] args){ ArrayList<Integer> list = new ArrayList<Integer>(); int x = input.nextInt(); while(x != 0){ if(x < 0 || x > 4){ System.out.println("Wrong Format"); System.exit(0); } list.add(x); x = input.nextInt(); } DealCardList dealCardList = new DealCardList(list); if(dealCardList.validate()==false){ System.out.println("Wrong Format"); System.exit(0); } dealCardList.showResult(); input.close(); } } class DealCardList{ ArrayList<Card> cardList=new ArrayList<>(); public DealCardList() { } public DealCardList(ArrayList<Integer> card) { for (Integer integer : card) { if (integer==0)break; switch (integer){ case 1: Card card1=new Card(new Circle(Main.input.nextDouble())); card1.getShape().setShapeName("Circle"); cardList.add(card1); break; case 2: Card card2=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble())); card2.getShape().setShapeName("Rectangle"); cardList.add(card2); break; case 3: Card card3=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble())); card3.getShape().setShapeName("Triangle"); cardList.add(card3); break; case 4: Card card4=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble())); card4.getShape().setShapeName("Trapezoid"); cardList.add(card4); break; } } } public boolean validate(){ boolean ret=true; for (Card card : cardList) { if (card.getShape().validate()==false){ ret=false; break; } } return ret; } public void cardSort(){ TreeSet<Card> cards = new TreeSet<>(cardList); for (Card card : cards) { System.out.print(card.getShape()); } } public double getAllArea(){ double sum=0; for (Card card : cardList) { sum+=card.getShape().getArea(); } return sum; } public void showResult(){ System.out.println("The original list:"); for (Card card : cardList) { System.out.print(card.getShape()); } System.out.println(); System.out.println("The sorted list:"); cardSort(); System.out.println(); System.out.printf("Sum of area:%.2f\\n",getAllArea()); } } class Card implements Comparable<Card>{ private Shape shape; public Card() { } public Card(Shape shape) { this.shape = shape; } public Shape getShape() { return shape; } public void setShape(Shape shape) { this.shape = shape; } public int compareTo(Card card) { return (int)(shape.getArea()-card.getShape().getArea()); } } abstract class Shape{ private String shapeName; public Shape() { } public Shape(String shapeName) { this.shapeName = shapeName; } public String getShapeName() { return shapeName; } public void setShapeName(String shapeName) { this.shapeName = shapeName; } public abstract double getArea(); public abstract boolean validate(); public String toString() { return getShapeName()+":"+String.format("%.2f ",getArea()); } } class Circle extends Shape{ private double radius; public Circle() { } public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea() { return Math.PI*radius*radius; } public boolean validate() { return this.radius>0; } } class Trapezoid extends Shape{ private double top; private double bottom; private double height; public Trapezoid() { } public Trapezoid(double top, double bottom, double height) { this.top = top; this.bottom = bottom; this.height = height; } public double getArea() { return (top+bottom)*height/2; } public boolean validate() { return top>0&&height>0&&bottom>0; } }
import java.util.ArrayList; import java.util.Scanner; import java.util.TreeSet; public class Main { public static Scanner input = new Scanner(System.in); public static void main(String[] args){ ArrayList<Integer> list = new ArrayList<Integer>(); int x = input.nextInt(); while(x != 0){ if(x < 0 || x > 4){ System.out.println("Wrong Format"); System.exit(0); } list.add(x); x = input.nextInt(); } DealCardList dealCardList = new DealCardList(list); if(dealCardList.validate()==false){ System.out.println("Wrong Format"); System.exit(0); } dealCardList.showResult(); input.close(); } } class DealCardList{ ArrayList<Card> cardList=new ArrayList<>(); public DealCardList() { } public DealCardList(ArrayList<Integer> card) { for (Integer integer : card) { if (integer==0)break; switch (integer){ case 1: Card card1=new Card(new Circle(Main.input.nextDouble())); card1.getShape().setShapeName("Circle"); cardList.add(card1); break; case 2: Card card2=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble())); card2.getShape().setShapeName("Rectangle"); cardList.add(card2); break; case 3: Card card3=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble())); card3.getShape().setShapeName("Triangle"); cardList.add(card3); break; case 4: Card card4=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble())); card4.getShape().setShapeName("Trapezoid"); cardList.add(card4); break; } } } public boolean validate(){ boolean ret=true; for (Card card : cardList) { if (card.getShape().validate()==false){ ret=false; break; } } return ret; } public void cardSort(){ TreeSet<Card> cards = new TreeSet<>(cardList); for (Card card : cards) { System.out.print(card.getShape()); } } public double getAllArea(){ double sum=0; for (Card card : cardList) { sum+=card.getShape().getArea(); } return sum; } public void showResult(){ System.out.println("The original list:"); for (Card card : cardList) { System.out.print(card.getShape()); } System.out.println(); System.out.println("The sorted list:"); cardSort(); System.out.println(); System.out.printf("Sum of area:%.2f\\n",getAllArea()); } } class Card implements Comparable<Card>{ private Shape shape; public Card() { } public Card(Shape shape) { this.shape = shape; } public Shape getShape() { return shape; } public void setShape(Shape shape) { this.shape = shape; } public int compareTo(Card card) { return (int)(shape.getArea()-card.getShape().getArea()); } } abstract class Shape{ private String shapeName; public Shape() { } public Shape(String shapeName) { this.shapeName = shapeName; } public String getShapeName() { return shapeName; } public void setShapeName(String shapeName) { this.shapeName = shapeName; } public abstract double getArea(); public abstract boolean validate(); public String toString() { return getShapeName()+":"+String.format("%.2f ",getArea()); } } class Circle extends Shape{ private double radius; public Circle() { } public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea() { return Math.PI*radius*radius; } public boolean validate() { return this.radius>0; } } class Trapezoid extends Shape{ private double topSide; private double bottomSide; private double height; public Trapezoid() { } public Trapezoid(double topSide, double bottomSide, double height) { this.topSide = topSide; this.bottomSide = bottomSide; this.height = height; } public double getArea() { return (topSide+bottomSide)*height/2; } public boolean validate() { return topSide>0&&height>0&&bottomSide>0; } }
package sa; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class c { public static void main(String[] args) { List<Atm> atmList1 = new ArrayList<>(); atmList1.add(new Atm("01","中国建设银行")); atmList1.add(new Atm("02","中国建设银行")); atmList1.add(new Atm("03","中国建设银行")); atmList1.add(new Atm("04","中国建设银行")); List<Account> accountList1 = new ArrayList<>(); List<Card> cardList1 = new ArrayList<>(); List<String > subCardNumList1_1 = new ArrayList<>(); List<String > subCardNumList1_2 = new ArrayList<>(); subCardNumList1_1.add("6217000010041315709");subCardNumList1_1.add("6217000010041315715"); subCardNumList1_2.add("6217000010041315718"); cardList1.add(new Card("中国建设银行",1,"3217000010041315709","88888888",10000,subCardNumList1_1)); cardList1.add(new Card("中国建设银行",1,"3217000010041315715 ","88888888",10000,subCardNumList1_2)); Account a1 = new Account("杨过",cardList1); List<Card> cardList2 = new ArrayList<>(); List<String > subCardNumList2_1 = new ArrayList<>(); subCardNumList2_1.add("6217000010051320007"); cardList1.add(new Card("中国建设银行",1,"3217000010051320007", "88888888",10000,subCardNumList2_1)); Account a2 = new Account("郭靖",cardList2); accountList1.add(a1); accountList1.add(a2); Bank bank1 = new ChinaConstructionBank("中国建设银行",1,atmList1,accountList1); List<Atm> atmList2 = new ArrayList<>(); atmList2.add(new Atm("05","中国工商银行")); atmList2.add(new Atm("06","中国工商银行")); List<Account> accountList2 = new ArrayList<>(); List<Card> cardList3 = new ArrayList<>(); List<Card> cardList4 = new ArrayList<>(); List<String > subCardNumList3_1 = new ArrayList<>(); List<String > subCardNumList3_2 = new ArrayList<>(); List<String > subCardNumList3_3 = new ArrayList<>(); List<String > subCardNumList4_1 = new ArrayList<>(); List<String > subCardNumList4_2 = new ArrayList<>(); subCardNumList3_1.add("6222081502001312389"); subCardNumList3_2.add("6222081502001312390"); subCardNumList3_3.add("6222081502001312399"); subCardNumList3_3.add("6222081502001312400"); cardList3.add(new Card("中国工商银行",2,"3222081502001312389","88888888",10000,subCardNumList3_1)); cardList3.add(new Card("中国工商银行",2,"3222081502001312390","88888888",10000,subCardNumList3_2)); cardList3.add(new Card("中国工商银行",2,"3222081502001312399","88888888",10000,subCardNumList3_3)); subCardNumList4_1.add("6222081502051320785"); subCardNumList4_2.add("6222081502051320786"); cardList4.add(new Card("中国工商银行",2,"3222081502051320785","88888888",10000,subCardNumList4_1)); cardList4.add(new Card("中国工商银行",2,"3222081502051320786","88888888",10000,subCardNumList4_2)); Account a3 = new Account("张无忌",cardList3); Account a4 = new Account("韦小宝",cardList4); accountList2.add(a3); accountList2.add(a4); Bank bank2 = new IcBc("中国工商银行",2,atmList2,accountList2); Card card1 = new Card("6217000010041315709"); Scanner scanner = new Scanner(System.in); List<String> stringsList = new ArrayList<>(); String s = scanner.nextLine(); while(!s.equals("#")){ stringsList.add(s); s = scanner.nextLine(); } Bank bank = null, anotherBank = null; for (String s1 : stringsList) { String[] str = s1.split("\\\\s+"); if (str[0].substring(0,4).equals("6222")) { bank = bank2; anotherBank = bank1; } else if (str[0].substring(0,4).equals("6217")) { bank = bank1; anotherBank = bank2; } if(str.length == 1){ bank.findMoney(str[0]); } else { Card card = new Card(str[0],str[1]); bank.reviseMoney(anotherBank,card,str[2],Double.parseDouble(str[3])); } } } } class Account{ private String userName; List<Card> cardList; public Account() { } public Account(String userName, List<Card> cardList) { this.userName = userName; this.cardList = cardList; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public List<Card> getCardList() { return cardList; } public void setCardList(List<Card> cardList) { this.cardList = cardList; } } class Atm extends Bank{ public String num; public String belongBankName; public Atm() { } public Atm(String num,String belongBankName) { this.num = num; this.belongBankName = belongBankName; } public String getNum() { return num; } } class Bank { public String bankName; public int bankNum; List<Atm> atmList; private List<Account> accountList; Card findCard; Account findAccount; public Bank() { } public Bank(String bankName, int bankNum, List<Atm> atmList, List<Account> accountList) { this.bankName = bankName; this.bankNum = bankNum; this.atmList = atmList; this.accountList = accountList; } public List<Atm> getAtmList() { return atmList; } public void setAtmList(List<Atm> atmList) { this.atmList = atmList; } public List<Account> getAccountList() { return accountList; } public void setAccountList(List<Account> accountList) { this.accountList = accountList; } public boolean reviseMoney(Bank anotherBank, Card card,String atmNum, double reviseMoney){ if(checkCardIsHave(card) && checkAtmIsHave(atmNum,anotherBank) && checkDrawMoneyIsCorrect(reviseMoney)){ this.findCard.modifyMoney(reviseMoney); if (reviseMoney < 0) { System.out.printf("%s在%s的%s号ATM机上存款¥%.2f\\n",this.findAccount.getUserName() ,this.bankName,atmNum,(-reviseMoney)); } else { System.out.printf("%s在%s的%s号ATM机上取款¥%.2f\\n",this.findAccount.getUserName() ,this.bankName,atmNum,reviseMoney); } System.out.printf("当前余额为¥%.2f\\n",this.findCard.getBalance()); return true; } return false; } public double findMoney(String cardNum){ for(Account a : this.accountList){ for(Card c : a.cardList){ for (String sudNum : c.getSubCardNumList()) { if ( cardNum.equals(sudNum) ) { System.out.printf("¥%.2f\\n",c.getBalance()); return c.getBalance(); } } } } return -1; } public boolean checkCardIsHave(Card card){ boolean numError = true; boolean pwdError = true; boolean haveAtm = false; for(Account a : this.accountList){ for(Card c : a.cardList){ for (String sudNum : c.getSubCardNumList()) { if ( card.getBankCardNum().equals(sudNum) ) { numError = false; } if ( card.getCardPassword().equals(c.getCardPassword()) ) { pwdError = false; } } if( !numError && !pwdError ){ this.findCard = c; this.findAccount = a; return true; } } } if (numError) { System.out.println("Sorry,this card does not exist."); } if (pwdError) { System.out.println("Sorry,your password is wrong."); } return false; } public boolean checkAtmIsHave(String atmNum,Bank antherBank){ for (Atm atm : this.atmList){ if ( atmNum.equals(atm.getNum()) ) { return true; } } for (Atm atm : antherBank.atmList) { if ( atmNum.equals(atm.getNum()) ) { System.out.println("Sorry,cross-bank withdrawal is not supported."); return false; } } System.out.println("Sorry,the ATM\'s id is wrong."); return false; } private boolean checkDrawMoneyIsCorrect(double drawMoney) { boolean success = false; if (this.findCard.getBalance() < drawMoney) { System.out.println("Sorry,your account balance is insufficient."); return false; } if (findCard.subBankNum != this.bankNum) { System.out.println("Sorry,cross-bank withdrawal is not supported."); } oo第二次博客总结