一:题目要求:
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。需要通过键盘录入日期,再读文件,判断是晒网还是打鱼,再将结果写出。
首先需要解决的是录入日期的格式问题,根据题意要求,录入的日期格式为八位纯数字,比如2010年1月1日即为20100101,那么录入的日期为八位纯数字自然而然想到的是正则表达式 String regex = "\\d{8}"; 调用String类中的matches方法这很容易就可以判断录入日期是否为八位纯数字格式。判断为8位纯数字后没有结束,因为从2010年1月1日开始,所以输入的日期一定要大于2010年1月1日,其次,月份只有12个月,大月的天数为31天,小月的天数为30天,闰年的2月为29天,平年的2月为28天,这些都将影响到日期格式的正确与否,影响到接下来对日期的操作,我想到的是用String类中的subString()分别截取1-4位,5-6位,7-8位用Integer类中的parseInt()方法将截取的子串去转化为int类型就可以分别至上而下进行日期的具体格式判断。
接下来就需要通过键盘去录入日期,但是需要判断的日期个数并不确定,我想到的是在while(true)循环中,通过是否继续录入判断是否跳出循环,来决定需要录入的日期的具体个数,另外我需要一个不定长的数组去存键盘录入的每个日期字符串,用集合就可以,没有过多考虑,用的是ArrayList集合即可,其它集合也都可以选择。
当录入结束之后,并且将录入的日期字符串都存入到了集合中,遍历集合将每个字符串写出到in.txt中,写出我用的是PrintStream,它可以直接使用println()方法写出一个字符串,对于本程序的实现比较方便,很容易就将字符串写到in.txt中。
接下来就是将in.txt中的内容读入后进行打鱼或者晒网的判断后将结果写到out.txt中即可。同样用PrintStream的println()方法。
为了使程序更加人性化,将结果写到out.txt中之后我选择调用java.awt.Desktop.getDesktop().open()方法在程序运行的最后直接打开out.txt,使结果更为直观。
到此为止,程序的大体已经实现,换一种说法其实是还没开始实现,因为本程序具体需要实现的是打鱼还是晒网的判断,实现的 方式是通过给定的日期和初始日期的时间2010年1月1日之前的天数之差,再根据三天打鱼两天晒网的5天一循环,取余,就可以得出给定的日期是打鱼还是晒网,这需要通过判断平年闰年,2月的天数,由于在输入格式的判断中,已经进行过闰年平年的判断,于是想到直接用Java中的Calendar,Calendar类本身是抽象类,用的其实是它实现抽象方法的子类对象,其中一个的值是2010年1月1日,另个是给定的日期,那么两个对象调用getTimeInMillis()方法获取毫秒差根据毫秒和天的单位换算就能求取天数之差:
long day = (now.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 60 / 60 / 24;
为了包含2010年1月1日这一天方便5天一循环的判断可以day++;
另外一个思路在开始的时候我想到的是调用该类对象的add方法不断从2010年1月1日增加1天直到与给定日期相同,因为该方法非常智能化,对属性Calendar.DATE的不断自增会自动进行年月的改变而不会超出一个月31天或者30天或者29天的上限,但是该思路如果给定的日期在很久很久以后,需要花费的时间将会较长。
int count = 0; while (true) { if (first.get(Calendar.YEAR) == now.get(Calendar.YEAR) && first.get(Calendar.MONTH) == now.get(Calendar.MONTH) && first.get(Calendar.DATE) == now.get(Calendar.DATE)) { break; } first.add(Calendar.DATE, 1); count++; } count++;
以上是我对三天打鱼两天晒网的java代码实现的思路