问题描述:
中国有句俗语叫“三天打鱼两天晒网”。某人从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");
}
}
测试结果: