本文给大家介绍如何使用C++语言解决万年历问题,笔者尽量做到讲解过程简单、细致,让读者可以轻松阅读。
正文开始:
目录
前提知识
1.闰年的判断方法
普通闰年:公历年份是4的倍数,且不是100的倍数,为闰年。
世纪闰年:公历年份是400的倍数也是闰年。
其他为平年。
2.每年、月的时长
平年一年365天。每月天数分别为{ 31,28,31,30,31,30,31,31,30,31,30,31 }。
闰年二月多一天,为29天,一年366天。
3.公元1年的第一天是星期一
讲解
笔者讲解的万年历问题有两种输入输出类型,按年输出or按月输出。
根据模块化程序设计思想,我们把万年历问题分为计算天数和输出两个部分。
借助函数我们可以将复杂的问题分解为小问题分别解决。
函数说明
分多个模块进行:
(1)RUN:计算当年是否是闰年
(2)MD:MonthDay,计算当月的天数,函数名简写为MD
(3)YFD:YearFirstDay,计算当年第一天是星期几,简写为YFD
(4)MFD:MonthFirstDay,计算当月第一天是星期几,简写为MFD
(5)Print:根据当月天数打印万年历 i)Print_1:打印选择1的万年历 ii)Print_2:打印选择2的万年历
代码讲解
主函数
先输出提示内容。
cout << "万年历显示程序" << endl;
cout << "***********************" << endl;
cout << "1 按年输出" << endl << "2 按月输出" << endl << "0 退出" << endl;
cout << "***********************" << endl;
根据输入,输出不同类的万年历或退出。
for (int i = 1;;i++)
{
cout << "万年历 " << i << " :" << endl;
cout << "请输入您的选择" ;
int choice;
cin >> choice;
if (choice == 1)
{
cout << "请输入显示的年份" ;
int year;
cin >> year;
Print_1(year);
}
else if (choice == 2)
{
int year, month;
cout << "请输入显示的年份" ;
cin >> year;
cout << "月份" ;
cin >> month;
Print_2(year, month);
}
else if (choice == 0)
{
cout << "程序结束!" << endl;
break;
}
cout << endl;
}
以上只是简单的输入与函数调用。for循环是为了有多次输入与输出,直至输入0,结束。
(1)RUN:计算当年是否是闰年
根据闰年规则,我们可以容易地写出函数RUN
bool RUN(int year)
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return 1;
else
return 0;
}
(2)MD:计算当月的天数
月份为2月时,根据闰年判断输出天数。不是二月时,直接输出当月天数即可。
int MD(int year, int month)
{
int a[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2)
{
if (RUN(year))
return a[1] + 1;
else
return a[1];
}
else
{
return a[month - 1];
}
}
这里笔者用数组记载每月天数。读者也可以用switch-case结构来输出。
(3)YFD:计算当年第一天是星期几
根据公元1年的第一天是星期一,笔者用函数递归的方法解决这个问题:
今年第一天星期数是(去年第一天星期数+去年全年天数)%7
int YFD(int year)//输出结果为 0-6(0表示星期天)
{
if (year == 1)
return 1;
else
{
if (RUN(year - 1))
return (YFD(year - 1) + 366) % 7;
else
return (YFD(year - 1) + 365) % 7;
}
}
(4)MFD:当月第一天是星期几
类似上一个函数,运用函数递归:
这个月第一天星期数是(上个月第一天星期数+上个月天数)%7
注意:函数形参不仅仅是月份,因为每月天数要根据年份用MD函数计算。
int MFD(int year, int month)
{
if (month == 1)
return YFD(year);
else
return (MFD(year, month - 1) + MD(year, month - 1)) % 7;
}
(5)Print_1:打印选择1的万年历
void Print_1(int year)
{
for (int j = 1;j <= 12;j++)
{
cout << " " << j << "月" << endl;
Print_2(year,j);
}
}
(6)Print_2:打印选择2的万年历
首先输出头表," 日 一 二 三 四 五 六"。
获取第一天的星期数和该月天数。
输出第一天时,与星期数对齐,之后的天数依次输出。
这里需要一个用于换行的标志pos,用于记载每个数的位置,一旦到达末尾要换行。
void Print_2(int year, int month)
{
cout << " 日 一 二 三 四 五 六" << endl;
int pos = MFD(year, month), day = MD(year, month);
cout << setw(4 * pos + 4) << 1;
pos++;
if (pos == 7)
{
cout << endl;
pos = 0;
}
for (int i = 2;i <= day;i++)
{
cout << setw(4) << i;
pos++;
if (pos == 7)
{
cout << endl;
pos = 0;
}
}
cout << endl;
}
完整代码
#include<iostream>
#include<iomanip>
using namespace std;
bool RUN(int year);
int MD(int year, int month);
int YFD(int year);
int MFD(int year, int month);
void Print_1(int year);
void Print_2(int year, int month);
bool RUN(int year)
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return 1;
else
return 0;
}
int MD(int year, int month)
{
int a[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2)
{
if (RUN(year))
return a[1] + 1;
else
return a[1];
}
else
{
return a[month - 1];
}
}
int YFD(int year)//输出结果为 0-6(0表示星期天)
{
//用函数递归解决
//今年第一天星期数是(去年第一天星期数+去年全年天数)%7
if (year == 1)
return 1;
else
{
if (RUN(year - 1))
return (YFD(year - 1) + 366) % 7;
else
return (YFD(year - 1) + 365) % 7;
}
}
int MFD(int year, int month)
{
//递归
//这个月第一天星期数是(上个月第一天星期数+上个月天数)%7
if (month == 1)
return YFD(year);
else
return (MFD(year, month - 1) + MD(year, month - 1)) % 7;
}
void Print_1(int year)
{
for (int j = 1;j <= 12;j++)
{
cout << " " << j << "月" << endl;
Print_2(year,j);
}
}
void Print_2(int year, int month)
{
cout << " 日 一 二 三 四 五 六" << endl;
int pos = MFD(year, month), day = MD(year, month);
cout << setw(4 * pos + 4) << 1;
pos++;
if (pos == 7)
{
cout << endl;
pos = 0;
}
for (int i = 2;i <= day;i++)
{
cout << setw(4) << i;
pos++;
if (pos == 7)
{
cout << endl;
pos = 0;
}
}
cout << endl;
}
int main()
{
cout << "万年历显示程序" << endl;
cout << "***********************" << endl;
cout << "1 按年输出" << endl << "2 按月输出" << endl << "0 退出" << endl;
cout << "***********************" << endl;
for (int i = 1;;i++)
{
cout << "万年历 " << i << " :" << endl;
cout << "请输入您的选择" ;
int choice;
cin >> choice;
if (choice == 1)
{
cout << "请输入显示的年份" ;
int year;
cin >> year;
Print_1(year);
}
else if (choice == 2)
{
int year, month;
cout << "请输入显示的年份" ;
cin >> year;
cout << "月份" ;
cin >> month;
Print_2(year, month);
}
else if (choice == 0)
{
cout << "程序结束!" << endl;
break;
}
cout << endl;
}
return 0;
}