“三天打鱼两天晒网”
一. 内容
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C++语言实现程序解决问题。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,并将结果输出至out.txt文件。
二. 步骤:
1.算法分析
按三天打鱼两天晒网,要计算2010年1月1日之后某一天是打渔还是晒网,先计算出起始日期到查询日期之间相差的天数,再用计算出的天数除以5取余,若为1,2,3则是晒网,否则便是打渔,再将日期信息和结果通过文件方法分别存入in.text文件和out.text文件中。最主要的便是在计算天数的时候,要注意平年和闰年的区别、每月的天数问题以及闰年的2月是29天。 ((闰年能被4除尽 且 不能被100除尽)或 能被400除尽)
2.概要设计
3.测试(设计测试用例或测试代码的设计与实现,测试结果截屏))
测试代码:
Date d1(2010,1,1);
Date d2(2011,1,1),d;
cout << "起始日期:";
d1.printDate(d1);
cout << "查询日期:";
d2.printDate(d2);
int s = d.sumDay(d2) - d.sumDay(d1);
cout << "经历天数:" << s << endl << d.judge(s) << endl;
d.saveDate(d1,d2,s);
实现结果:
4.调试(对测试出的问题进行调试,界面截屏,调试修正编码)
5.代码实现
**Date.h文件**
#include<iostream>
#include<string>
using namespace std;
class Date{ //日期类
private:
int year; //年份
int month; //月份
int day; //日份
public:
Date(){}; //无参构造函数
Date(int y, int m, int d);
//年份、月份、日份设置
void setYear();
void setMonth();
void setDay();
//年份、月份、日份获取
int getYear();
int getMonth();
int getDay();
void printDate(Date &d); //打印日期
void inputDate(Date &d); //输入日期
int sumDay(Date &d); //该日期总天数
string judge(int index); //打渔晒网判断
void saveDate(Date &d1, Date &d2, int s);
};
**main.cpp**
#include"Data.h"
#include<fstream>
void Date::setYear(){
cin >> year;
}
Date::Date(int y, int m, int d){
year = y;
month = m;
day = d;
}
void Date::setMonth(){
cin >> month;
}
void Date::setDay(){
cin >> day;
}
int Date::getYear(){
return year;
}
int Date::getMonth(){
return month;
}
int Date::getDay(){
return day;
}
void Date::printDate(Date &d){
cout << d.getYear() << "年" << d.getMonth() << "月" << d.getDay() << "日" << endl;
}
void Date::inputDate(Date &d){
//利用循环控制输入的查询日期在起始日期之后
while(true){
cout << "请输入要查询的日期年份、月份、日份:" << endl;
d.setYear();
d.setMonth();
d.setDay();
if(d.getYear()<2010 || d.getMonth()<1 || d.getDay()<1){
cout << "输入时间位于2010年1月1日之前,请重新输入!" << endl;
}else{
break;
}
}
cout << "查询日期为:" ;
d.printDate(d);
}
int Date::sumDay(Date &d){
int sum = 0; //年月日折合成的总天数
for(int i=0; i<d.getYear(); i++){
if((d.getYear()%4 == 0 && d.getYear()%100!=0) || d.getYear()%400==0){ //判断当前年份是否是闰年
sum += 1*366;
}else{
sum+= 1*365;
}
}
for(int i=0; i<d.getMonth(); i++){
if((d.getYear()%4 == 0 && d.getYear()%100!=0) || d.getYear()%400==0){ //先判断当前年份是否是闰年,在判断2月天数
if(i==2){
sum += 1*29;
}else{
sum += 1*28;
}
}else if(i==1 || i==3 || i==5 || i==7 || i==8 || i==10 || i==12){
sum += 1*31;
}else{
sum += 1*30;
}
}
sum += d.getDay();
return sum;
}
string Date::judge(int index){
int flag = index % 5;
if(flag<4){
return "这一天在打渔!";
}else{
return "这一天在晒网!";
}
}
void Date::saveDate(Date &d1, Date &d2, int s){
// 创建两个文件流对象,ofs1用来保存日期信息,ofs2保存结果
ofstream ofs1,ofs2;
ofs1.open("in.text",ios::out);
ofs1 << "起始日期:" << d1.getYear() << "年" << d1.getMonth() << "月" << d1.getDay() << "日" << endl
<< "查询日期:" << d2.getYear() << "年" << d2.getMonth() << "月" << d2.getDay() << "日" << endl;
ofs1.close();
ofs2.open("out.text",ios::out);
ofs2 << "经历天数:" << s << endl << judge(s) << endl;
ofs2.close();
}
int main(){
Date d1(2010,1,1);
Date d2,d;
cout << "起始日期:";
d1.printDate(d1);
d.inputDate(d2);
int s = d.sumDay(d2) - d.sumDay(d1);
// int s = d.sumDay(d2);
cout << "经历天数:" << s << endl << d.judge(s) << endl;
d.saveDate(d1,d2,s);
system("pause");
return 0;
}
三. 心得体会(关键问题的解决思路及步骤总结)
在程序设计过程中,我使用c++进行编写,遇到的最主要的问题就是每年的月份天数不同和平年闰年的判断,我通过网上查阅资料,利用对输入年份添加判定条件来判定当前年份是否为闰年。对于月份天数的相加,我通过if语句来实现;对于最后结果的实现,我通过计算起始日期和查询日期各自的天数总和作差再取余来判断那天的活动。中途,在测试数据的时候,发现我可以输入2010年之前的数据,在最后,我利用while循环限制用户输入的查询日期必须在2010年1月1日之后,以此来达到题目要求。
总的来说,在这次完成作业的过程中,遇到的问题不多,但是我写的算法不够简洁,比如求月份天数,可以使用数组的方式来实现月份天数求和,在之后,我会努力加强算法方面的练习。