三天打鱼两天晒网问题(C++)

/******************************/
文件名称:三天打鱼两天晒网
编程语言:C++
编译器:Visual C++ 6.0
完成日期:2019年02月28日
作者:无奈¬_¬`啊

一.问题

中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/java/python实现程序解决问题。
此处我是用C++实现的。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。

二.思考

首先三天打鱼两天晒网,周期为5天,所以只要计算出指定日期到2010年01月01日有多少天,并用这个天数除以5求余数,如果余数是0或者4则说明他在晒网,余数为1,2,3则在打渔,这个不难想象。
接下来我们的主要任务就是求天数,这也是这个问题的核心部分,因为每年的天数不一样,闰年366天,平年365天,所以必须区分好闰年和平年。
可以被4整除而且不被100整除的或者能被400整除的就是闰年,否则是平年。用代码表示则如下:

if(x%4==0&&x%100!=0||x%400==0) temp=1;
	else temp=0;

temp是1表示闰年,0表示平年。
闰年比平年多一天,这个多出来的一天就是2月里28天或者29天,闰年2月有29天。所以在判断日期的正确性的时候需要注意。

if(temp==0)
				{
					if(z>28)
					{
						cout<<"平年2月只有28天!";
						exit(0);
					}
				}

继续求天数,我们先求出2010年到指定年前一年的天数,然后在细算到月份日份。
年份的不同就代表着闰年和平年,所以就麻烦了,你得先判断这段时期之间每一年的年份,然后再决定加多少天。

for(int i=2010; i<x; i++)
	{
		if(temp) t+=366;
		else t+=365;
	}

x为指定年份;
计算好年份后我们就需要计算月份日份了,计算到指定月份的天数加上指定的日份·,就计算出总天数了;
然而又存在大月小月所以加的天数也不同:

switch(y)
	{
		case 1:
			t+=z;
			break;
		case 2:
			t=t+31+z;
			break;
		case 3:
		{
			if(temp==1) t=t+60+z;
			else t=t+59+z;
		}
		break;
		case 4:
		{
			if(temp==1) t=t+91+z;
			else t=t+90+z;
		}
		break;
		case 5:
		{
			if(temp==1) t=t+121+z;
			else t=t+120+z;
		}
		break;
		case 6:
		{
			if(temp==1) t=t+152+z;
			else t=t+151+z;
		}
		break;
		case 7:
		{
			if(temp==1) t=t+182+z;
			else t=t+181+z;
		}
		break;
		case 8:
		{
			if(temp==1) t=t+213+z;
			else t=t+212+z;
		}
		break;
		case 9:
		{
			if(temp==1) t=t+244+z;
			else t=t+243+z;
		}
		break;
		case 10:
		{
			if(temp==1) t=t+274+z;
			else t=t+273+z;
		}
		break;
		case 11:
		{
			if(temp==1) t=t+305+z;
			else t=t+304+z;
		}
		break;
		case 12:
		{
			if(temp==1) t=t+335+z;
			else t=t+334+z;
		}
		break;
		default:
			cout<<"输入有误,请重新输入!";
	}

这个方法有点笨,需要自己算出加多少天,也可以用数组来加,奈何我有点不理解所以用那个这个笨办法了):
最后让我们加上日份就大功告成了也就是上面的z,y表示的是月,z表示日。
不要大意了,还要判断日期的正确性,闰年2月28天,大月小月,不多阐述,代码献上:

	if(y<0||y>12)
	{
		cout<<"读取的月份错误,请重新输入!";
		exit(0);
	}
	else
	{
		if(z<0||z>31)
		{
			cout<<"读取的日份错误,请重新输入!";
			exit(0);
		}
		else
		{
			if(y==2)
			{
				if(z>29)
				{
					cout<<"2月最多有29号!";
					exit(0);
				}
				if(temp==0)
				{
					if(z>28)
					{
						cout<<"平年2月只有28天!";
						exit(0);
					}
				}
				if(temp==1)
				{
					if(z>29)
					{
						cout<<"平年2月只有29天!";
						exit(0);
					}
				}
			}
			else
			{
				if(y==4||y==6||y==9||y==11)
					if(z>30)
					{
						cout<<"小月不能超过30天";
						exit(0);
					}
			}
		}
	}

最后的最后就是文件操作了,需要用到ofstream类和ifstream类,通过文件流对象进行操作。
通过键盘将年月日输入保存到in.txt文件里,然后通过文件流对象的操作,读取in.txt里的内容并放到in.dat文件里,在读取出来进行操作,将结果输出到out.txt文件里;以上对文件的操作都是在D:\gyy\ 路径下操作,代码如下:

int x,y,z;
	int a[3];
	ofstream outfile("d:\\gyy\\in.txt",ios::out);   //创建一个in.txt用来保存文件
	cout<<"请输入日期:"<<endl;
	for(int i=0; i<3; i++)                          //以数组的形式保存
	{
		cin>>a[i];
		outfile<<a[i]<<" ";
	}
	ifstream infile("d:\\gyy\\in.txt",ios::in);    //以下四行代码实现将in.txt里的数据读入到in.dat文件里
	ofstream outfile1("d:\\gyy\\in.dat",ios::out); //1
	for(i=0; i<3; i++)                             //2
	{
		infile>>a[i];                              //3
		outfile1<<a[i]<<" ";
	}                          //4
	infile.open("d:\\gyy\\in.dat",ios::in);        //以下3行代码将in.dat里的数据读取并赋值给对应的日期
	for(i=0; i<3; i++)                             //1
		infile>>a[i];                              //2
	x=a[0];
	y=a[1];
	z=a[2];                        //3

	nf(x);                                       //判断闰年还是平年;
	panduan(y,z);                               //判断日期的正确性
	display(x);                                 //计算2010到指定日期前一年是经过多少天
	display1(y,z);                               //细算到指定日期的那天

	ofstream outfile2("d:\\gyy\\out.txt",ios::out);//创建一个输出文件out.txt
	int b=t%5;
	if(b<4&&b!=0) outfile2<<"小明在打渔!";       //向out.txt文件输入结果
	else outfile2<<"小明在晒网!";
	infile.close();
	outfile.close();
	outfile1.close();
	outfile2.close();

三.总结·

这次的程序设计,给予了我一点小喜悦,通过自己的努力,查阅书籍,结合自己的知识做出来的程序,虽然有点冗杂,但是总的来说功能是完善的,就是代码写的过于冗杂,在判断日期的正确性是用了太多的if else语句,完全可以改进为对数组操作将12个月份的数据放在数组中,需要就提取很方便(自我检讨一下);
三天打鱼俩天网究竟是褒义还是贬义,潜意识中是认为做事不专心,这俩天在学习这个,过俩天又在做其他事。所以做出这个程序后我也希望可以以后的我也不再三天打鱼两天晒网了!!!
(纪念我的第一篇博客!)

最后附上完整版代码:

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
class Time
{
	private:
		int t;//表示天数
		int temp;//判断闰年,平年的条件,1代表闰年
	public:
		void nf(int);//判断年份的闰平
		void panduan(int,int);//判断日期的正确性
		void display(int);//返回2010年到指定年份前一年的总天数
		void display1(int,int);
		void fileoperation();
};
void Time::nf(int x)                  //先判断这个是否为闰年
{
	if(x<2010) cout<<"读取的年份太小!,请重新输入!";
	if(x%4==0&&x%100!=0||x%400==0) temp=1;
	else temp=0;
}
void Time::display(int x)            //返回2010年到指定年份前一年的总天数
{
	for(int i=2010; i<x; i++)
	{
		if(temp) t+=366;
		else t+=365;
	}
}
void Time::display1(int y,int z)
{
	t=0;
	switch(y)
	{
		case 1:
			t+=z;
			break;
		case 2:
			t=t+31+z;
			break;
		case 3:
		{
			if(temp==1) t=t+60+z;
			else t=t+59+z;
		}
		break;
		case 4:
		{
			if(temp==1) t=t+91+z;
			else t=t+90+z;
		}
		break;
		case 5:
		{
			if(temp==1) t=t+121+z;
			else t=t+120+z;
		}
		break;
		case 6:
		{
			if(temp==1) t=t+152+z;
			else t=t+151+z;
		}
		break;
		case 7:
		{
			if(temp==1) t=t+182+z;
			else t=t+181+z;
		}
		break;
		case 8:
		{
			if(temp==1) t=t+213+z;
			else t=t+212+z;
		}
		break;
		case 9:
		{
			if(temp==1) t=t+244+z;
			else t=t+243+z;
		}
		break;
		case 10:
		{
			if(temp==1) t=t+274+z;
			else t=t+273+z;
		}
		break;
		case 11:
		{
			if(temp==1) t=t+305+z;
			else t=t+304+z;
		}
		break;
		case 12:
		{
			if(temp==1) t=t+335+z;
			else t=t+334+z;
		}
		break;
		default:
			cout<<"输入有误,请重新输入!";
	}
}
void Time::panduan(int y,int z)
{
	if(y<0||y>12)
	{
		cout<<"读取的月份错误,请重新输入!";
		exit(0);
	}
	else
	{
		if(z<0||z>31)
		{
			cout<<"读取的日份错误,请重新输入!";
			exit(0);
		}
		else
		{
			if(y==2)
			{
				if(z>29)
				{
					cout<<"2月最多有29号!";
					exit(0);
				}
				if(temp==0)
				{
					if(z>28)
					{
						cout<<"平年2月只有28天!";
						exit(0);
					}
				}
				if(temp==1)
				{
					if(z>29)
					{
						cout<<"平年2月只有29天!";
						exit(0);
					}
				}
			}
			else
			{
				if(y==4||y==6||y==9||y==11)
					if(z>30)
					{
						cout<<"小月不能超过30天";
						exit(0);
					}
			}
		}
	}
}
void Time::fileoperation()
{
	int x,y,z;
	int a[3];
	ofstream outfile("d:\\gyy\\in.txt",ios::out);   //创建一个in.txt用来保存文件
	cout<<"请输入日期:"<<endl;
	for(int i=0; i<3; i++)                          //以数组的形式保存
	{
		cin>>a[i];
		outfile<<a[i]<<" ";
	}
	ifstream infile("d:\\gyy\\in.txt",ios::in);    //以下四行代码实现将in.txt里的数据读入到in.dat文件里
	ofstream outfile1("d:\\gyy\\in.dat",ios::out); //1
	for(i=0; i<3; i++)                             //2
	{
		infile>>a[i];                              //3
		outfile1<<a[i]<<" ";
	}                          //4
	infile.open("d:\\gyy\\in.dat",ios::in);        //以下3行代码将in.dat里的数据读取并赋值给对应的日期
	for(i=0; i<3; i++)                             //1
		infile>>a[i];                              //2
	x=a[0];
	y=a[1];
	z=a[2];                        //3

	nf(x);                                       //判断闰年还是平年;
	panduan(y,z);                               //判断日期的正确性
	display(x);                                 //计算2010到指定日期前一年是经过多少天
	display1(y,z);                               //细算到指定日期的那天

	ofstream outfile2("d:\\gyy\\out.txt",ios::out);//创建一个输出文件out.txt
	int b=t%5;
	if(b<4&&b!=0) outfile2<<"小明在打渔!";       //向out.txt文件输入结果
	else outfile2<<"小明在晒网!";
	infile.close();
	outfile.close();
	outfile1.close();
	outfile2.close();
}
int main()
{
	Time q;
	q.fileoperation();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42419462/article/details/88011201