一、题目名称:“三天打鱼两天晒网”
二、题目内容:中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。
三、算法设计:
1.输入当前日期的年、月、日。
2.检验当前日期是否合法。
3.从2010年开始遍历
3.1若当前年份小于输入年份
3.1.1若当前年份为闰年,则总天数累加366
3.1.2若当前年份不是闰年,则总天数累加365
3.2遍历年份+1
4.计算输入的月份之前每个月的天数,并累加到总天数中
5.将输入的日期累加到总天数中
6.将总天数对5取模,得到余数
7.若余数为1、2、3时,则当天打鱼,否则为晒网。
四、调试截图:
1.调试输入部分,确保程序能由接收到输入。
2.调试计算天数的部分,验证间隔天数是否正确。
五、测试结果:
1.结果测试
2.日期合法性测试
六、遇到的困难及解决方案:
1.第一次测试时,程序运行完的总天数不正确,调试后发现,通过观察变量的取值发现,输入的月和日取值始终相同,查找代码才发现是将两个变量名字写成了一个。
2.验证日期合法性时,开始采用的方法是直接暴力if-else选择判断,遇到的问题是所需要考虑的情况太多,导致判断十分繁琐、层次不清晰。例如:年份是否为闰年、月份是否包含二月、每个月月份的天数等等,都需要一个个判断。通过查阅,发现Java中有判断日期合理性的方法。
// 检验日期的合法性,合法返回true,不合法返回false
public static boolean isValidDate(String strDate) {
boolean isValid = true;// 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
dateFormat.setLenient(false);
dateFormat.parse(strDate);
} catch (ParseException e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
isValid = false;
}
return isValid;
}
3.在测试文件读入部分时,遇到的困难是无法将年、月、日分开读入。解决的办法也很简单,在in.dat文件中存储日期时,将年月日用特殊符号分隔开,直接利用String类型中的split()方法读取,并将年月日分别放String数组中,再进行后续操作。
// 从in.dat文件中读取日期
public static void inputDate() throws Exception {
File file = new File("src/in.dat");
BufferedReader br = new BufferedReader(new FileReader(file));// 输入流
String str;
while ((str = br.readLine()) != null) {// 按行读取
String[] ss = str.trim().split("-");// 日期格式为yyyy-MM-dd
// for test
// System.out.println(ss[0].trim() + "-" + ss[1].trim() + "-" + ss[2].trim());
}
br.close();// 关闭流
}