编程练习5.29要求您编写一个程序,该程序可以打印用户输入的任意一年的赢博体育十二个月的日历。
运行这个程序应该产生如下内容:
你想显示哪一年?2018年1月2018年苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年2月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2018年3月21日22日23日24日25日26日27日28日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年4月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 2018年5月30日苏莫你我们Fr Sa) 1 2 3 45 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年6月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日2018年7月27 28 29 30苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年8月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年9月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1819 20 21日22日23日24日25日26日2018年10月27 28 29 30苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年11月31日苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 2018年12月苏莫你我们Th Fr Sa) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31
这是一个非常具有挑战性的问题!很少有试图解决这个问题的程序员能够在第一次尝试时就将这个问题的解决方案概念化并实现。相反,大多数程序员会分阶段地解决这个问题,从一个明显不正确的简单解决方案开始,然后通过一系列越来越接近理想最终产品的版本。本实验练习将带您在相当大的指导下完成该过程。下面我们将遍历程序的几个版本,直到我们到达一个可以完成我们想要的赢博体育功能的版本。在此过程中,您将获得一些使用循环和if-else语句的经验。
对于我们的第一个版本,我们将从打印一个月的日历开始。
创建一个新项目,并将以下代码放入程序的main方法中。
int细胞;for(cell = 1;cell <= 42;cell++) {System.out.print(cell);}
运行这个程序并记下它产生的输出。您会立即注意到这里有几个明显的错误。
第一个问题很容易解决。修改代码,使程序打印从1到42的数字,数字之间有空格。
接下来,我们要解决赢博体育数字都出现在同一行上的问题。解决这个问题的明显方法是在适当的位置打印换行符。要在Java中打印换行,可以使用语句
System.out.println ();
这条命令不输出任何内容,后跟一个换行符。
现在的诀窍是让换行符出现在正确的位置。一种方法是在每个能被7整除的数字后面打印一个换行符。
此外,在循环开始前添加一个print语句,用于打印显示一周中的天数的日历标题。
现在运行你的程序应该产生如下所示的结果:
Su Mo Tu We Th Fr Sa 12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
下一个需要解决的问题是,大多数月份并非从周日开始。
对于我们的下一个版本,添加一些代码,提示用户输入一个数字,这个月应该从星期几开始,其中星期日= 1,星期六= 7。
一旦知道了每个月的第一天应该是星期几,就可以将该信息与循环计数器变量单元格结合起来,为日历网格中的每个单元格生成正确的天数。
现在运行你的程序应该产生如下所示的结果:
一月从星期几开始?(1 =星期日,7 =星期六)6 Su Mo Tu We Th Fr Sa -4 -3 -2 -1 0 12 34 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35 36 37
您的循环现在将处理两个不同的变量。第一个变量cell是循环计数器变量。第二个变量date是通过将cell与第一个到达的星期的日期相结合而得到的数字。在您的打印语句中,您现在将在单元格中打印日期。
下一个要解决的问题是确保我们不打印负数,并且我们在每个数字之前打印正确的空格数,以使数字与列标题很好地对齐。
换句话说,我们想要一个程序产生的东西看起来更像这样:
一月从星期几开始?(1 =星期日,7 =星期六)6 Su Mo Tu We Th Fr Sa 12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35 36 37
要实现这一点,找到打印数字的语句,并将其替换为一组if-else语句,执行以下操作:
日期
小于1,打印三个空格,不打印数字。日期
小于10,则输出后跟数字的两个空格。下一个版本将包括可以自动确定一个月从星期几开始以及一个月有多少天的代码。我们将利用一个Java类来完成这个任务,这个Java类包含许多处理日期的有用方法。这个Java类是Java类库的一部分,Java类库是一个可以执行有用任务的大型类集合。
我们已经看到了一个有用类的例子,即Scanner类。要使用这个类,通常使用import语句导入该类,创建一个属于该类的对象,然后调用该对象的各种方法来完成有用的工作:
//导入扫描器类//创建一个Scanner对象input。扫描器输入=新的扫描器(System.in);//调用输入对象的nextInt方法//完成有用的工作。int = input.nextInt();
为了处理时间和日期信息,我们将使用Calendar类。下面是使用这个类需要知道的一些事情。
日历
类中,您需要将此import语句置于程序的顶部:进口java.util.Calendar;
日历
对象并将其存储在名为时间
做日历时间= Calendar. getinstance ();
时间
对象到所需月份和年份的第一天使用设置()
方法,使用年、月、日。的日历
class使用一个月份的编号系统,其中1月是0,12月是11,所以你必须从用户给你的月份数字中减去1:time.set(第1个月,1);
dayOfWeek = time.get(Calendar.DAY_OF_WEEK);
daysInMonth = time.getActualMaximum(Calendar.DATE);
String name = time.getDisplayName(Calendar.MONTH,Calendar.LONG,Locale.ENGLISH)
使用如上所述的Calendar类,修改程序以提示用户输入月份和年份,然后打印当月的日历。
当你的程序运行时,它看起来应该像这样:
您想显示哪个月份和年份?2012年9月2012年9月Su Mo Tu We Th Fr Sa 12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
现在我们有了一个程序,可以打印用户输入的任何月份的日历,我们可以完成程序了。将提示用户输入月份和年份的代码替换为只提示用户输入年份的代码。在日历制作逻辑周围放置一个循环,循环该年份中的赢博体育月份,从第1个月到第12个月,为用户指定的年份中的每个月打印日历。
当你完成这个程序,把你的项目文件夹归档,并通过电子邮件给我评分。如果你在实验中没有完成这个练习,你可以在实验结束后的第二天下午5点之前交上来,不会迟到。