三天打鱼两天晒网

博客围绕“三天打鱼两天晒网”问题展开,某人从2010年1月1日起按此规律行事,需判断指定日期是打鱼还是晒网。给出解决思路,包括定义数组存月份天数、分割日期、计算整年、整月及剩余天数,最后总天数对5取余判断状态,还给出代码及测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼“还是'晒网'。用ç或C ++语言/ JAVA /蟒实现程序解决问题。

解决思路:

定义两个长度为13的数组来保存平年和闰年的月份天数(0号索引值为0,方便将月份和对应索值引对应起来),然后对输入进来的合法日期(不合法日期忽略,其输出结果为:非法日期)进行分割,分割出年,月,日循环计算整年所经过的天数,循环变量我的初始值设为2010年,我自增,每次自增后进行平闰年判断,如果是闰年总天数加366,平年加355.当我的值自增到等于当前年份时,退出循环,此时得到了整年经过的天数,然后对当前年份进行平闰年判断,对整月份的天数进行计算,如果是闰年,则将闰年的月份数组前一个月(当前月份的值,且不含月)个值进行相加,得到整月份的天数,最后总天数等于整年份的天数加整月份的天数再加当前日期数。

总的计算思路为:

(1):先求整年数的总天数

(2):再求整月数的总天数

(3):剩下的天数

(4):三者相加就是总经过的天数

(5):总天数对5求余数,余数为1/2/3为打鱼,0/4为晒网。

 

代码如下:

package com.programmingmethed.work;

import java.util.regex.Pattern;


/**
 * 三天打鱼两天晒网
 * 功能: 给定一个日期字符串判断出这一天是打鱼还是晒网或者是非法日期
 * @author dengyong
 * 
 */
public class Fishing {
	
	/**
	 * 平年的月份数组
	 */
	static int []commonYear = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	static final int sumCommon = 365; //平年天数
	
	/**
	 * 闰年的月份数组
	 */
	static int []leapYear = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	static final int sumLeap = 366; //闰年天数
	
	/**
	 * 检查日期合法性
	 * @param date 日期字符串
	 * @throws Exception
	 */
	void checkDate(String date) throws Exception {
		//如果不符合2018-02-13这样的格式就认为不合法
		if (!Pattern.matches("\\d{4}-\\d{2}-\\d{2}", date)) {
			throw new Exception("日期格式不正确");
		}
		//将日期字符串分割出年月日并解析成整型数
		String []arrayDate = date.split("-");
		int year = Integer.parseInt(arrayDate[0]);
		int month = Integer.parseInt(arrayDate[1]);
		int day = Integer.parseInt(arrayDate[2]);
		
		if (year < 2010) { //如果年份小于2010年
			throw new Exception("日期小于2010");
		}
		
		if (month > 12 || month <= 0) { //月份大于12或小于0
			throw new Exception("月份不合法");
		}
		
		if (isLeapYear(year) && (day > leapYear[month] || day < 0)) { //如果是闰年并且对应的天数日期不符合
			throw new Exception("本月天数有误");
		}
		
		if ((!isLeapYear(year)) && ( day > commonYear[month] || day < 0)) { //如果是平年并且对应的天数日期不符合
			throw new Exception("本月天数有误");
		}
	}
	
	/**
	 * 判断是否是闰年
	 * @param year 年份
	 * @return 是否是闰年
	 */
	boolean isLeapYear(int year) {
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0){  //是闰年
			return true;
		}
		return false;
	}
	
	/**
	 * 计算从2010年1月1日起至目标日期一共过了多少天
	 * @param date 日期
	 * @return 总天数
	 */
	int countDays(String date) {
		try {
			checkDate(date); //检查日期合法性
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} 
		int days = 0; //记录总天数
		int startYear = 2010;
		//将日期字符串分割出年月日并解析成整型数
		String []arrayDate = date.split("-");
		int nowYear = Integer.parseInt(arrayDate[0]);
		int month = Integer.parseInt(arrayDate[1]);
		int day = Integer.parseInt(arrayDate[2]);
		
		//计算整年天数并相加
		for (int i = startYear; i < nowYear; i++) {
			if (isLeapYear(i)) { //如果是闰年
				days += sumLeap; //加上闰年的天数366
			} else {
				days += sumCommon; //加上平年的天数365
			}
		}
		boolean leap = isLeapYear(nowYear); //保存nowYear是否是闰年
		//处理剩余的月份及日期
		if (leap) {  //如果是闰年
			for (int i = 0; i < month; i++) {
				days += leapYear[i];
			}
		} else { //平年
			for (int i = 0; i < month; i++) {
				days += commonYear[i];
			}
		}
		days += day;
		return days; //返回总天数
	}
	
	/**
	 * 得到一个日期对应的打鱼还是晒网的结果
	 * @param date 日期字符串
	 * @return 打鱼 或 晒网
	 */
	public String result(String date) {
		//获得总天数
		int days = countDays(date);
		
		if (-1 == days) { //如果是异常日期反悔得到的-1
			return "非法日期";
		}
		
		int remainder = days % 5;
		
		//如果余数是1,2,3就位打鱼
		if (remainder == 1 || remainder == 2 || remainder == 3) {
			return "打鱼";
		} else {
			return "晒网";
		}
	}
	
	public static void main(String[] args) throws Exception {
		Fishing f = new Fishing();
		System.out.println(f.result("2015-02-90"));
	}

}

附加批量的文件数据处理代码:

package com.programmingmethed.work;

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

/**
 * 批量处理一个文件的数据来得到结果
 * @author dengyong
 *
 */
public class BetchProcess {
	
	/**
	 * 读文件中的日期数据并将结果写入到结果文件中
	 * @param dataPAth 日期数据文件路径
	 */
	public static void dealData(String dataPAth) {
		Fishing f = new Fishing(); //创建一个对象,用于结果判断
		String resultPath = newName(dataPAth);//构建一个结果文件的路径
		try {
			//利用字符流来读写文件
			BufferedReader br = new BufferedReader(new FileReader(new File(dataPAth)));
			BufferedWriter bw = new BufferedWriter(new FileWriter(new File(resultPath)));
			String line = ""; //暂存所读的一行数据
			String result = ""; //保存计算的结果即是打鱼还是晒网还是非法日期
			//循环读取文件,若读到文件未返回的是null
			while (null != (line = br.readLine())) {
				result = f.result(line); //将读出来的一行日期字符串进行结果判断
				bw.write(line+"\t"+result); //写入到结果文件中
				bw.newLine(); //换行
			}
			bw.close();
			br.close();
			System.out.println("已完成,请查看文件: " + resultPath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过源数据路径构建一个结果集路径
	 * 例如:目标文件路径为:E:/../@.txt  则结果文件路径为: E:/../@[结果].txt
	 * @param dataPath 源路径
	 * @return 目标路径
	 */
	static String newName(String dataPath) {
		String []list = dataPath.split("/");
		String oldName = list[list.length-1];
		String newName = oldName.substring(0, oldName.indexOf("."))+"[结果]"+".txt";
		return dataPath.replace(oldName, newName);
	}
	
	public static void main(String[] args) {
		BetchProcess.dealData("E:/我的程序设计/Test/TestData.txt");
	}

}


测试结果:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值