三天打鱼两天晒网,用java语言实现

问题描述

中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言实现程序解决问题
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。

思路分析

笔者在完成这道题目时,正在学习Java,所以就想用Java完成。所以本题目是Java语言完成的。看到这题目,先简化题目,“三天打鱼,两天晒网”可以看成五天一个循环,根据总天数除五取余。根据得到的余数,如果余数为1,2,3则这个人在打鱼;如果余数为0,4则这个人在晒网。所以要先计算出当前输入日期距离2010年1月1日过去了多少天。这样就不得不涉及判断闰年的计算(闰年计算后面再说),基本到这里本题的基本要求就算实现了。
然后就是提高要求,对输入年月日进行正确性检测,年输入必须大于等于2010,输入年份小于2010就要报错;月份需输入在1~12月份,输入其他报错;日的输入需要小于等于当前月份的最大天数。这就是输入正确性检验的大致思路。对于文件的输入和输出,直接调用java的IO流实现文件读取和写入。

实现过程

详细步骤:
实现基本要求:
1.思考需要建立的程序流程图:
在这里插入图片描述

2.建立一个java工程(笔者用的软件是IDEA )命名为SAYING,在默认的文件夹src下建立后缀名为.java的文件。
这里大体思考一下需要的文件:
Main.java(包含程序主方法,调用以下.java文件)
FishAndNet.java(判断打鱼或晒网)
Year.java(判断闰年)
MonthAndDay.java(计算经过的天数)

3.基本要求的代码实现:
首先在Main.java中编写以下代码:


public class Main {
    public static void main (String[] args) throws Exception {
        java.util.Scanner y=new java.util.Scanner(System.in);    //创建键盘输入扫描器
        int year;
       	int month;
        int day;      //定义年,月,日
        System.out.println("请输入年月日");
        year=y.nextInt();              //接收年输入
        month=y.nextInt();           //接收月输入
        day=y.nextInt();               //接收日输入
        Year year1=new Year();                 //建立判断闰年对象
        MonthAndDay date=new MonthAndDay();        //建立计算经过天数的对象
        boolean leapYear1=year1.judgeYear(year);      //接收判断是否闰年的布尔值变量
        if(leapYear1==true){
            System.out.println("闰年");
        }
        else {
            System.out.println("非闰年");
        }
        System.out.println("你输入了:"+year+"年"+month+"月"+day+"日");
        int d=date.judgeMonth(day,month,year,leapYear1);
        System.out.println("据2010年1月1日已过去"+d+"天");
        FishAndNet x=new FishAndNet();     
        String fish=x.judgeFish(d);
        System.out.println("这一天,你在"+fish);
    }
}

在Year.java文件中编写以下代码,用于闰年的判断:

public class Year {
    public boolean judgeYear(int year){
        if((year%4==0&&year%100!=0)||year%400==0){
            return true;//是闰年返回true
        }else{
            return false;//非闰年返回false
        }
    }
}

在MonthAndDay.java文件中编写以下代码,用于计算经过的天数:
这一部分可以说是程序的关键部分,如果总天数计算不对,那么就直接影响程序的执行结果,为此,简单阐述一下这部分的思路:
用一个例子来说明,例如:输入为2015年6月15日,程序会分为三部分计算总天数(年,月,日)。
首先,年的计算,由2015-2010=5,得出已经是第五年了,中间过去了2010,2011,2012,2013,2014,这五个年头,判断这五年中每一年是否闰年,是闰年,按366天计算,加到总天数里面,不是闰年则按365天算,得到整年所过去的天数sumDate=365+365+366+365+365=1826(天)。即过一年判断一年,然后求和。
其次,月的计算,定义两个数组,一个表示闰年月份天数的,一个表示平年月份天数,即代码演示中的leapYear[]和noLeapYear[],当得到输入的月份currentMonth(5月)时,这时已经过去了1月,2月,3月,4月,这里先判断2015是否闰年,判断出非闰年,则调用noLeapYear[]数组,将sumDate=sumDate+noLeapYear[1]+noLeapYear[2]+noLeapYear[3]+noLeapYear[4]=1826+31+28+31+30=1946(天)
最后,加上当前日currentDay,当前日为15号,则sumDate=sumDate+15=1946+15=1961

public class MonthAndDay {
    public int judgeMonth(int currentDay,int currentMonth,int currentYear,boolean l){
        Year a=new Year();
        int sumDate=0;            //总天数,初始化为零
        int yearOld=currentYear-2010;   //经过的年数=当前年份-2010
        for(int i=0;i<yearOld;i++){
            if (a.judgeYear(2010+i))  //判断所经过的年份有没有闰年
                sumDate=sumDate+366; //若(当前年份-2010)中的年份是闰年,总天数+366
            else sumDate=sumDate+365;//若(当前年份-2010)中的年份不是闰年,总天数+365
        }
        int[] leapYear={0,31,29,31,30,31,30,31,31,30,31,30,31};
        int[] noLeapYear={0,31,28,31,30,31,30,31,31,30,31,30,31};
		//定义闰年和非闰年月份天数的数组,这里将每个数组第一个数赋为零的原因是方便计算,将数组的下表号和月份保持一致
       // leapYear[]={31,29,31,30,31,30,31,31,30,31,30,31};
       if (a.judgeYear(currentYear)){
           for(int i=0;i<currentMonth;i++)
               sumDate=sumDate+leapYear[i]; //若是闰年,则用leapYear[]进行计算
       }else{
           for(int i=0;i<currentMonth;i++)
               sumDate=sumDate+noLeapYear[i];//若不是闰年,则用noLeapYear[]进行计算
       }
       sumDate=sumDate+currentDay;//之前计算的天数+当前的日
       return sumDate;//返回总天数
    }
}

在FishAndNet.java中编写判断“打鱼”或“晒网”的代码:

public class FishAndNet {
    public String judgeFish(int sum){
        int a=sum%5;   //总天数除5取余
        if(a>=1&&a<=3)
            return("打鱼");  //余数是1,2,3,则此人在打鱼
        else
            return("晒网");  //其余情况(余数为0和4),则在晒网
    }
}

到此本题目的基本要求就实现了。但为了让程序更加完美,那就要做提高要求了,毕竟,连基本的输入判断正确性都没有也是不行的。所以亟待解决的就是输入正确性判断。
实现提高要求:
要实现提高要求,先建立两个.java文件:
InputCorrect.java(判断输入正确性)
ReadAndWrite.java(读文件和写文件)

输入输出的txt文件:
in.txt(输入文件)
out.txt(输出文件)
首先,在InputCorrect.java中编写以下代码:

public class InputCorrect {
    public boolean Input(int year,int month,int day){
    Year a=new Year();
    boolean sign;    //用于判断输入正确或错误,并返回
        if(year<2010) {
            System.out.println("输入年份需大于2010");
            sign=false;
            year=2010; 
        }else sign=true;    //判断年份输入是否符合规范
        if(sign){
            if(month>12||month<1){
                System.out.println("输入月份不正确!");
                sign=false;
                month=1;
            }else sign=true;  //判断月份输入是否在1到12月份之间,不是则月份赋为1
        }
        int[] b={0,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年月份的天数
        int[] c={0,31,28,31,30,31,30,31,31,30,31,30,31};  //平年月份的天数
        boolean leapyear1=a.judgeYear(year); //先判断当前年份是否闰年
        if(sign) {     //前面两步(年和月)输入都正确才会执行日的正确性判断
            if (leapyear1) {
                if (day <=b[month] && day >= 1) //是闰年,采用b数组
                    sign = true;
                else
                    sign = false;
            } else {
                if (day <= c[month] && day >= 1) //是平年,采用c数组
                    sign = true;
                else
                    sign = false;
            }
        }
        return sign;
    }
}

建立ReadAndWrite.java文件,主要就是包含两个函数fileRead()和write():

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
import java.io.BufferedWriter;

public class ReadAndWrite {
    public String fileRead() throws Exception {
        File file = new File("D:\\JAVAcode\\src\\in.txt");
        FileReader reader = new FileReader(file);//定义一个fileReader对象,用来初始化BufferedReader
        BufferedReader bReader = new BufferedReader(reader);//new一个BufferedReader对象,将文件内容读取到缓存
        StringBuilder win = new StringBuilder();//定义一个字符串缓存,将字符串存放缓存中

        String s = "";
        while ((s =bReader.readLine()) != null) {//逐行读取文件内容,不读取换行符和末尾的空格
            win.append(s);//将读取的字符串添加换行符后累加存放在缓存中
        }
        bReader.close();
        String str = win.toString();//将读取的文件内容以字符串赋给str
        System.out.println(str);
        return str;//返回文件内容str
        //return str;
        //int[] a=new int[3];
        //return 0;
    }
  public static void write(String s1) throws IOException {//要写入内容为s1
      try {
          File f = new File("D:\\JAVAcode\\src\\out.txt");
          if(f.exists()){
              System.out.print("文件存在");
          }else{
              System.out.print("文件不存在");
              f.createNewFile();//不存在则创建
          }
          BufferedWriter output = new BufferedWriter(new FileWriter(f));
          output.write(s1); //将s1写入文件
          output.close();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}

方法已经写好了,剩下的就是调用了,所以主函数也要加一些代码调用,以实现流程图中的逻辑和内容:
前面我们已经提到,读取文件内容返回类型是字符串,但主程序中运行的年月日是int型,所以这里需要使用类型转换,将String转换为int型,这里我用了
int cnm=Integer.parseInt(rnm);
这个函数将String类型的rnm转化为int型的cnm,以‘“运行结果”的in.txt文件内容20130213,此时int型变量cnm的值为20130213;但我们想要的是年份2013,月份02,日13。笔者经过思考可以用一些基本的运算解决这个问题,即代码中的:
year=cnm/10000;
month=cnm%10000/100;
day=cnm-(year* 10000+month* 100);
这样即可得到正确的年月日。

public class Main {
    public static void main (String[] args) throws Exception {
        java.util.Scanner y=new java.util.Scanner(System.in);
        int year;
       	int month;
        int day;
        System.out.println("选择你要进行的输入方式:1.文件输入;2.手动输入");
        int wor= y.nextInt();
        ReadAndWrite rw=new ReadAndWrite();
        if(wor==1){ //采取文件输入
            String rnm=rw.fileRead();
            int cnm=Integer.parseInt(rnm);
            year=cnm/10000;
            month=cnm%10000/100;
            day=cnm-(year*10000+month*100);
        }else{  //用户手动输入
            System.out.println("请输入年月日");
            year=y.nextInt();
            month=y.nextInt();
            day=y.nextInt();
        }
        String ss;  //ss为写入文件内容的字符串
        InputCorrect input=new InputCorrect();
        boolean we=input.Input(year,month,day);
        do{
        if(we){
            System.out.println("日期输入符合格式");
           // ss="日期输入符合格式";
        }else{
            System.out.println("日期输入不符要求,请重新输入:");
          //  ss="日期输入不符要求,请重新输入:";
            year=y.nextInt();
            month=y.nextInt();
            day=y.nextInt();
            we=input.Input(year,month,day);
        }
        }while(we==false);
        Year year1=new Year();
        MonthAndDay date=new MonthAndDay();
        boolean leapYear1=year1.judgeYear(year);
        if(leapYear1==true){
            System.out.println("闰年");
            ss="闰年\n";
        }
        else {
            System.out.println("非闰年");
            ss="非闰年\n";
        }
        System.out.println("你输入了:"+year+"年"+month+"月"+day+"日");
        ss=ss+"你输入了:"+year+"年"+month+"月"+day+"日\n";
        int d=date.judgeMonth(day,month,year,leapYear1);
        System.out.println("据2010年1月1日已过去"+d+"天");
        ss=ss+"据2010年1月1日已过去"+d+"天\n";
        FishAndNet x=new FishAndNet();
        String fish=x.judgeFish(d);
        System.out.println("这一天,你在"+fish);
        ss=ss+"这一天,你在"+fish;
      //  System.out.println(ss);
        rw.write(ss);  //将ss写入文件
    }
}

运行结果展示

in.txt文件输入:
在这里插入图片描述
运行结果(文件输入):
在这里插入图片描述
手动输入:
在这里插入图片描述
写入文件内容:
在这里插入图片描述
在这里插入图片描述

总结与不足

因为笔者正在学习java,通过这次练习,让我掌握和巩固了已学习的java知识,也学习了一些还未学到的java内容,其实本题涉及的算法都是最简单,最基本的,时常复习练习一下基本的算法对学过的知识也是一种巩固,毕竟温故而知新嘛。
但这次时间比较紧,对文件的读取和写入了解的还不透彻,所以文件的读取和写入还不完善,希望大佬指正。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值