c++与三天打鱼两天晒网相关
问题描述
中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。
设计思路
*问题分析与算法设计
根据题意可以将解题过程分为三步:
1)计算从2010年1月1日开始至指定日期共有多少天;
2)由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除;
3)根据余数判断他是在“打鱼”还是在“晒网”;
在这三步中,关键是第一步。可以利用ctime中的tm结构体输入年月日,然后将结构体转换为time_t类型与20100101转换成的time_t求差值,差值再除以86400即为间隔天数。
流程图
代码
头文件
#pragma once
#include<iostream>
#include<string>
#include<fstream>
#include<ctime>
using namespace std;
int judge(string);
int calculate(string);
int judgedate(int, int, int);
函数实现
#include"head.h"
int judge(string s)//判断字符串是否合法
{
int len;
int y, m, d;//定义年月日
len = s.size();//求字符串长度
if(len != 8) return 0;//正确的字符串长度应该为8
for(int i=0;i<8;i++)
{
if (s[i] < 48 || s[i]>57) return 0;//判断字符串中是否有非数字
}
y = (s[0] - 48) * 1000 + (s[1] - 48) * 100 + (s[2] - 48) * 10 + (s[3] - 48);//数字ASCII码-48即为对应的数值
m = (s[4] - 48) * 10 + (s[5] - 48);
d = (s[6] - 48) * 10 + (s[7] - 48);
if (judgedate(y, m, d)) return 1;
else return 0;
}
int judgedate(int y, int m, int d)//判断年月日是否规范
{
if (y < 2010) return 0;
int leap;
if (m < 1 || m>12) return 0;
if ((y % 400 == 0) || (y % 4 == 0 && y % 100 != 0)) leap = 1;//判断是否闰年,leap为1则表示为闰年
else leap = 0;//leap0为表示为平年
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) //1,3,5,7,8,10,12有31天。。
{
if (d<=0 || d > 31)
{
return 0;
}
}
else if (m == 4 || m == 6 || m == 9 || m == 11) //4,6,9,11有30天
{
if (d<= 0 || d > 30)
{
return 0;
}
}
else
{
if (leap)
{
if (d <= 0 || d > 29) return 0;
}
else
{
if (d <= 0 || d > 28) return 0;
}
}
}
int calculate(string s)//计算日期
{
int y, m, d,sec,interval;
tm t1 = { 0 };
tm t2 = { 0 };
y = (s[0] - 48) * 1000 + (s[1] - 48) * 100 + (s[2] - 48) * 10 + (s[3] - 48);
m = (s[4] - 48) * 10 + (s[5] - 48);
d = (s[6] - 48) * 10 + (s[7] - 48);
t1.tm_year = 2010 - 1900; t1.tm_mon = 1; t1.tm_mday = 1;// 计算的日期是20100101
t2.tm_year = y - 1900; t2.tm_mon = m; t2.tm_mday = d;// 将输入的日期转化为tm结构体
sec = difftime(mktime(&t2), mktime(&t1));//转换结构体为time_t,利用difftime,计算时间差
interval= sec / 86400 ;//间隔秒数除以86400即为间隔天数,因为一天有86400秒(60*60*24)
if (interval % 5 > 4 && interval % 5 < 3) return 0;
else return 1;
}
主函数
#include"head.h"
int main()
{
string a,b;
fstream f1, f2;
f1.open("in.txt", ios::app);
f2.open("out.txt", ios::app);
cout << "请输入要查询的日期" << endl;
cin >> a;
f1 << '\n' << a;//将字符串输入in.txt
f1.close();
f1.open("in.txt", ios::in);
while(!f1.eof())
{
f1 >> b;
}
if (judge(b))//从in.txt读取刚才输入的字符串,判断是否合法
{
if (calculate(b))
{
f2 << '\n' << b << "打渔";
cout << "打渔" << endl;
}
else
{
f2 << '\n' << b << "晒网";
cout << "晒网" << endl;
}
}
else
{
cout << "error" << endl;//提示错误信息
f2 << '\n' << b << "查询日期不合规范";
f2.close();
}
system("pause");
return 0;
}
运行结果
心得体会
采用了8位数字的字符串的形式进行字符串的输入,在将字符串还原为数字时,数字的值为ASCII码所代表的值,需要减去48才是本来的值。