题目:
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。以下是用Java语言实现。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数 据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。目前,只完成了基本要求,提高要求还存在问题,问题尚未解决。
代码一:此方法嵌套较多懂
package zuoye;
import java.util.Scanner;
/**
* 题目:中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,
* 问这个人在以后的某一天中是在“打鱼”还是在“晒网”。
* 思路:1、求出从2010年01月01日至输入的日期共有多少天(其中注意闰年的判断)
* 天数=2010年的天数+2010年以后到输入的年份整年的天数+输入那年年内的天数
* 2、用天数对5取余,余数为1、2、3,则在打鱼;余数为0、4,则在晒网;
*
* @author
*
*/
//此方法嵌套比较多,比较难看懂
public class Demo03 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in); //输入
System.out.println("输入年份:");
int year = scan.nextInt(); //输入年份
System.out.println("输入月份");
int month = scan.nextInt(); //输入月份
if(month < 0 || month > 12) { //判断月份输入是否有误
System.out.println("输入有误,请重新输入:");
int month1 = scan.nextInt(); //之前月份输入有误,重新输入月份
}
System.out.println("输入日期");
int day = scan.nextInt(); //输入日份
if(day < 0 ||day > 31) { //判断日期输入是否有误
System.out.println("输入有误,请重新输入:");
int day1 = scan.nextInt(); //之前日期输入有误,重新输入日期
}
int sum = 0;//记录相差的总天数
int sum1 = 0;//记录当前日期在这一年内过的天数
switch(month-1) { //输入的月份减去1,算出输入月份之前月份的天数和
case 12:sum1 += 31;
case 11:sum1 += 30;
case 10:sum1 += 31;
case 9:sum1 += 30;
case 8:sum1 += 31;
case 7:sum1 += 31;
case 6:sum1 += 30;
case 5:sum1 += 31;
case 4:sum1 += 30;
case 3:sum1 += 31;
case 2:
if((year %4 ==0 && year %100 !=0)||year %400 ==0) {
sum1 +=29;
}else {
sum1 +=28;
}
case 1:sum1 += 31;
}
sum1 +=day; //输入年的天数=输入月份本月的天数+输入月份之前月份的天数
if(year == 2010) { //若输入年是2010年,减去已经过去的1月1日,即就是总天数
sum = sum1 -1;
}else if(year>2010) { //若输入年份不是2010年 则天数=2010年的天数+2010年以后的天数
int sum2 = 365; //2010年的天数
int sum3 = 0; //记录相差年份的整天数
for(int i = 2011;i<year;i++ ){
if((i %4 ==0 &&i %100 !=0)||(year %400 ==0)){ //判断是否是闰年
sum3 +=366; //闰年366天
}else {
sum3 +=365; //非闰年365天
}
}
//总天数=输入年的年内天数+2010年的天数+2010年至输入年之前的天数
sum = sum1 + sum2 +sum3;
}
System.out.println("2010年1月1日至输入天数相差:"+sum+"天");
//判断是在打鱼还是在晒网
if(sum % 5 ==0 ||sum %5 ==4) {
System.out.println(year+"年"+month+"月"+day+"日"+"在打鱼");
}else if(sum %5 ==1 || sum %5 ==2 ||sum %5 -
==3){
System.out.println(year+"年"+month+"月"+day+"日"+"在晒;
}
}
-
- 方法二:
代码二:此方法结构简单,较清晰
package zuoye;
import java.util.Scanner; //Scanner类在Java.util包内
/**
* 题目:中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,
* 问这个人在以后的某一天中是在“打鱼”还是在“晒网”。
* 思路:1、求出从2010年01月01日至输入的日期共有多少天(其中注意闰年的判断)
* 天数=从2010年到输入的年份整年的天数+输入那年年内的天数
* 2、用天数对5取余,余数为1、2、3,则在打鱼;余数为0、4,则在晒网;
* @author 吴伟娜
*
*/
//此方法结构清晰,易理解
public class Demo02 {
public static void main(String[] args) {
//从键盘输入20100101后至今随便的日期
System.out.println("请输入从2010年1月1日至今之间随便的一个日期(日期格式如20100101):");
Scanner scan = new Scanner(System.in); //输入
System.out.println("输入年份:");
int year = scan.nextInt(); //输入年份
System.out.println("输入月份");
int month = scan.nextInt(); //输入月份
while(month < 0 || month > 12) { //判断月份输入是否有误
System.out.println("输入有误,请重新输入:");
int month1 = scan.nextInt(); //之前月份输入有误,重新输入月份
break;
}
System.out.println("输入日期");
int day = scan.nextInt(); //输入日份
while(day < 0 || day > 31) { //判断日期输入是否有误
System.out.println("输入有误,请重新输入:");
int day1 = scan.nextInt(); //之前日期输入有误,重新输入日期
break;
}
panDuan(getAllYearDays(year, month,day)); //调用判断的方法,进行判断是在打鱼还是在晒网
}
/**
* 闰年和平年的判断:
* 年份%4 == 0 && year%100 != 0 或者 year%400 ==0 时,为闰年,否则为平年
* @param year
* @return
*/
public static boolean isRunNian(int year) {//判断是否为闰年
if((year%4 ==0 && year%100 !=0)||year%400 ==0) {
return true;
}
else {
return false;
}
}
/**
* 计算从2010年1月1日至输入的日期的天数:
* 天数=从2010年到输入的年份整年的天数+输入那年年内的天数
* 定义方法getAllYearDays:获得从2010年到输入的年份之间的天数
* @param year
* @param month
* @param day
* @return
*/
public static int getAllYearDays(int year,int month,int day) {//计算年内的天数
int sum = 0;
for(int y= 2010;y < year;y++) {
if(isRunNian(year)) { //若为闰年,一年为366天
sum += 366;
}else { //不是闰年,一年为365天
sum += 365;
}
}
return sum +=getYearInDays(year,month,day);
}
//每月的天数的判断
public static int getDay(int year,int month) {
int days = 0;
switch(month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:days = 31; //每年的1、3、5、7、8、10、12月是31天
case 4:
case 6:
case 9:
case 11:days = 30; //每年的4、6、9、11月是30天
case 2: //2月分两种情况:闰年和平年
if(isRunNian(year)) { //判断是否是闰年
days = 29; //闰年则为29天
}else {
days = 28; //否则为28天
}
}
return days;
}
/**
* 计算输入的那年年内的天数:
* 定义getYearInDays方法并调用getDay()方法来计算年内天数的和
* @param year
* @param month
* @param day
* @return
*/
public static int getYearInDays(int year,int month,int day) {
int sum = 0;
for(int m =1;m < month; m++) { //从1月开始,至输入月份的天数进行累加
sum += getDay(year,m);
}
return sum+day;
}
/**
* 判断是在打鱼还是在晒网:
* 用算的天数和对5取余,若余数为1、2、3,则在打鱼;
* 若余数为0、4,则在晒网
* @param days
*/
public static void panDuan(int days) { //判断是在打鱼还是在晒网
if(days % 5 == 1 ||days %5 == 2 || days %5 ==3) {
System.out.println("在打鱼!");
}else if(days % 5 == 0 ||days % 5 == 4) {
System.out.println("在晒网!");
}
}
}
方法三:
代码三:此方法代码量最短,通过调用SimpleDateFormat类来利用时间计算出天数,SimpleDateFormat类的相关用法查看API文档
package zuoye;
import java.util.Scanner;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//此方法代码量最短,通过调用SimpleDateFormat类来利用时间计算出天数
public class Demo01{
public static void main(String[] args) throws ParseException {
//从键盘输入日期
System.out.println("输入一个日期,格式为YYYYMMDD");
Scanner scan = new Scanner(System.in);
String date1 = "20100101";//定义初始日期为2010年1月1日
String date2 = scan.nextLine();//从键盘输入一个日期
/**SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类
*可以计算出从2010年1月1日至输入日期公有多少毫秒的时间
*用计算出来的时间除以(24*60*60*1000)即是天数
*/
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
Date d1 = sf.parse(date1);
Date d2 = sf.parse(date2);
System.out.println(d1);
System.out.println(d2);
long time = d2.getTime() - d1.getTime(); //算出从2010年至输入的日期的毫秒数
int day = (int) (time/1000/3600/24) + 1; //毫秒数转换为天数
System.out.println(day);
//判断打鱼还是晒网
if(day %5 == 4 || day %5 == 0){
System.out.println("在晒网");//天数对5取余,余数为0、4,则晒网
}else{
System.out.println("在打鱼"); //天数对5取余,余数为1、2、3则为打鱼
}
}
}
总结:在此次练习中,主要是算法思维,思维清楚,实现结果就不难。主要是计算从2010年1月1日到输入的日期共多少天。天数的计算分为三部分:1.如果输入的年份是2010,则只需要计算月份;2、若输入的年份大于2010,则需要算2010年至输入年份间整年的天数;3、再加上输入年份那年的天数即可。主要是提高要求部分,通过IO流FileReader、FileWriter、BufferedReader、BufferedWriter进行输入输出时,出了差错,目前还在解决问题,尚未完成此功能。