1.问题描述
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。
2.问题要求
基本要求
1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:
1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。
3.作业提示
问题分析与算法设计
1)计算从2010年1月1日开始至指定日期共有多少天;
2)由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除;
3)根据余数判断指定日期是“打渔”还是“晒网”; 若 余数为1,2,3,则他是在“打渔”,否则 是在“晒网”
4.问题解决
4.1程序流程图
4.2源代码
交互界面
package fish;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
/**
*
* <p>
* Title:Menu
* </p>
* <p>
* Description:该类用于与用户进行数据交互
* </p>
*
* @author Dynamic
* @date 2018年8月28日 下午8:48:26
*
*/
public class Menu extends JFrame {
private String input;
private String res;
/**
*
* @Description:生成一个交互界面,用于接收用户输入,提示用户,返回测试结果
*/
public Menu() {
this.setTitle("算法测试");
JLabel l1 = new JLabel("请输入测试日期(yyyymmdd)或者测试文件所在路径");
l1.setBounds(60, 20, 500, 30);
this.add(l1);
this.setBounds(500, 500, 400, 220);
JTextField t = new JTextField();
t.setBounds(105, 50, 200, 30);
this.add(t);
JButton b1 = new JButton("日期测试");
b1.setBounds(100, 100, 100, 30);
this.add(b1);
JButton b2 = new JButton("文件测试");
b2.setBounds(210, 100, 100, 30);
this.add(b2);
JLabel l = new JLabel(res);
l.setBounds(120, 150, 200, 30);
this.add(l);
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
input = t.getText();
if (isRightInput(input)) {
Fish f = new Fish(input);// 判断是打渔或晒网
res = f.getRes();
} else {
// res = "输入格式不正确";
}
l.setText(res);// 显示测试结果
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
input = t.getText();
BufferedWriter fw = new BufferedWriter(new FileWriter("F://res.txt"));
BufferedReader br = new BufferedReader(new FileReader(input));
String line = null;
while ((line = br.readLine()) != null) {
if (isRightInput(line)) {
Fish f = new Fish(line);// 判断是打渔或晒网
res = f.getRes();
fw.write(res);// 将测试结果写入指定文件中
fw.newLine();// 写入行
} else {
fw.write(res);
fw.newLine();
}
}
res = "请在F://res.txt查看测试文本的结果";
l.setText(res);
br.close();
fw.close();
} catch (FileNotFoundException e1) {
res = "文件不存在,请输入正确路径";
l.setText(res);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
this.setLayout(null);
this.setVisible(true);
}
/**
*
* @Description:用于判断用户输入的时间是否合法
* @param input
* @return false|true
*/
public boolean isRightInput(String input) {
String format = "\\d{8}";// 定义匹配规则
Pattern p = Pattern.compile(format);// 实例化Pattern
Matcher m = p.matcher(input);// 验证字符串内容是否合法
if (m.matches()) {
int year = Integer.parseInt(input.substring(0, 4));
int month = Integer.parseInt(input.substring(4, 6));
int day = Integer.parseInt(input.substring(6, 8));
if (year < 2010 || month > 12 || month <= 0 || (month == 2 && day > 30)) {
if (year < 2010) {
res = "年份小于2010年";
}
if (month > 12) {
res = "月份不合法";
} else {
res = "日期不是合法日期";
}
return false;
} else
return true;
} else {
res = "请输入8位数字";
return false;
}
}
public static void main(String args[]) {
Menu n = new Menu();
}
}
核心算法
package fish;
/**
*
* <p>
* Title:Fish
* </p>
* <p>
* Description:该类用于判断打渔还是晒网
* </p>
*
* @author Lenovo
* @date 2018年8月28日 下午8:45:40
*
*/
public class Fish {
private String input;
private char[] arry;
private int year;
private int month;
private int day;
/**
*
* @Description:把日期字符串通过转换赋值给相应year,month,day
* @param input
*/
public Fish(String input) {
this.input = input;
arry = input.toCharArray();
year = arry[0] * 1000 + arry[1] * 100 + arry[2] * 10 + arry[3];
month = arry[4] * 10 + arry[5];
day = arry[6] * 10 + arry[7];
}
/**
*
* @Description:判断是否为闰年
* @return: true|false
*/
public boolean isLeapYear() {
return ((year % 4 == 0 && year % 100 != 0) | year % 4 == 0);
}
/**
*
* @Description:计算指定日期的距此年第一天的天数 @return(展示方法参数和返回值)
*/
public int month() {
int temp = 0;
switch (month - 1) {
case 11:
temp += 30;
case 10:
temp += 31;
case 9:
temp += 30;
case 8:
temp += 31;
case 7:
temp += 31;
case 6:
temp += 30;
case 5:
temp += 31;
case 4:
temp += 30;
case 3:
temp += 31;
case 2:
temp += 28;
case 1:
temp += 31;
}
return temp;
}
/**
*
* @Description:求指定日期与初始日期的差并对5取余,判断当天该打渔还是晒网
* @return “打渔” |“晒网”
*/
public String getRes() {
int num = 0;
int min = 0;
int temp;
if (isLeapYear()) {
num = (year - 2010);
min = (num - 1) * 365 + num / 4;
temp = month() + 1;
num = min + temp + day;// 指定日期与初始日期的差
} else {
num = (year - 2010);
min = (num - 1) * 365 + num / 4;
temp = month();
num = min + temp + day;// 指定日期与初始日期的差
}
if (num % 5 == 1 || num % 5 == 2 || num % 5 == 3) {// 对差取余,判断是否符合打渔的条件
return "这一天是打渔";
} else {
return "这一天是晒网";
}
}
}