打印日历程序,输入年份,输出本年的阳历.
第一次看到这个题目时,匆匆去写,遇到一个问题,就是每年的第一天是星期几不好确定,就想出键盘输入吧,但那岂不是太不友好了,后来得知,原来这个要依靠一个已知的星期,而且越早的程序应用起来越广泛,所以取了1900年1月1日,当然别的日子也可以,只要你知道.
下面是我的算法实现.
本这种算法的关键有三点:
一.确定某年第一天是星期几/
二.确定每月第一天是一年中的第几天
三.一个结构体数组
#include<iostream.h>
#include<stdlib.h>
struct Cdays
{
int dayinmonth;//某天是某月的第几天
int dmonth;//某天是一年中的第几个月中的
int dweek;//某天是星期几
int dtotalweek;//某天是一年的第几个星期(没有要求算此项)
};
bool funisleap(int year)
{
return ((year%4==0)&&(year%100!=0)||(year%400==0));
}
void funfirstofmon(int A[],bool isleap)//实现找出第月第一天是一年中的第几天
{
int i=0;
int sum=0;
int B1[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年的月份数组
int B2[12]={31,29,31,30,31,30,31,31,30,31,30,31};//闰年的月份数组
if (isleap)//闰年时
{
for(i=0;i<12;i++)
{
sum=sum+B2[i];//每月的第一天等于这天之前的天数+1,一月份除外
A[i+1]=sum+1;
}
}
else//平年时
{
for(i=0;i<12;i++)
{
sum=sum+B1[i];//每月的第一天等于这天之前的天数+1,一月份除外
A[i+1]=sum+1;
}
}
A[0]=1;//一月第一天当然是一年中的第一天,不用算
}
int funtotalweek(int day)//求出某天是一年中的第几周函数
{
if (day%7==0)
return day/7;
else
return day/7+1;
}
int fungetweek(int day,int firstWeekOfYear)//某天是星期几
{
int vweek=-1;
int temp=-1;
if (day%7==0)
vweek=7;
else
vweek=day%7;
vweek+=firstWeekOfYear;
if (vweek<=7)
return vweek-1;
else
{
vweek=vweek-7;
return vweek-1;
}
}
int fungetmonth(int Firstofmon[],int dayinyear,int yeardays,Cdays array[])
{
int i=0,j=0;
int vmonth=0;
for (j=0;i<=12;j++)
{//dayinyear是一年中的第n天,用这个值和Firstofmon[]数组中元素作比较,找到符合要求的第一个区间,即得到月份
if (dayinyear>=Firstofmon[j]&&dayinyear<Firstofmon[j+1]&&Firstofmon[j+1]!=0)//第12月无下个月份,不能用这种方法比较,所以用Firstofmon[j+1]!=0标出到else中去单独确定
{
vmonth=j+1;
break;
}
else if(Firstofmon[j+1]==0)//到12月份啦
{
vmonth=12;
break;
}
}
return vmonth;
}
void funweekmonth(int Firstofmon[],int yeardays,Cdays array[],int firstWeekOfYear)//为年数组添月/星期值,每个元素为struct型的三个元素
{
int whichmonth=-1,whichweek=-1;
int tempmonth=1;
int i=0,j=0;
for(i=1;i<=yeardays;i++)
{//以下三行为结构体数组赋值
array[i].dmonth=fungetmonth(Firstofmon,i,yeardays,array);//为结构体数组赋值月份
array[i].dtotalweek=funtotalweek(i);//为结构体数组赋值第几周
array[i].dweek=fungetweek(i,firstWeekOfYear);为结构体数组赋值星期几
for(j=0;j<=11;j++)//将每月第一天对应的年结构体数组置为1,便于以后计算
if (i==Firstofmon[j])
{
array[i].dayinmonth=1;//将每月第一天置为一,其余的不管(其余的为0,初始化时置的)
break;
}
}
for(i=1;i<=yeardays;i++)//进一步填充结构体数组array[],确定一年中的第一天为其对应所月的第n天
{
for(j=0;j<=11;j++)
if (array[i].dayinmonth==0)//初始化时置所有array[i].dayinmonth都为0
array[i].dayinmonth=array[i-1].dayinmonth+1;//得出某天是所在月的第几天,因为本月的第一天array[i]值等于1,所以依次加一
else
continue;
}
}
void display(int yeardays,int Firstofmon[],Cdays array[])//打印函数
{
int i=0,counter=0;
for(i=1;i<=yeardays;i++)
{
for(int j=0;j<12;j++)
if(i==Firstofmon[j])//遍历到了某月的第一天时
{
cout<<"/n/n"<<j+1<<"月"<<endl;
j++;
counter=0;//标记置0时,为下个月的格式输出每行三组作准备
break;
}
cout<<"[ "<<array[i].dayinmonth<<" 星期"<<array[i].dweek<<"/"<<array[i].dtotalweek<<"周 "<<i<<"th ]/t";
counter++;
if (counter%3==0)
cout<<endl;
}
}
void display1(int yeardays,int Firstofmon[],Cdays array[])//打印函数
{
int i=0,m=0;
int tag=1;//标记tag为0时表示输出前要计算位置,为1时表示不必计算输出位置
for(i=1;i<=yeardays;i++)
{
for(int j=0;j<12;j++)
if(i==Firstofmon[j])//遍历到了某月的第一天时
{
cout<<"/n/n"<<j+1<<"月"<<endl;
j++;
tag=0;//tag置为0,为每月的第一次/t格式输出作准备
for(m=0;m<7;m++)
switch(m)
{
case 0:{cout<<"Sun./t";break;}
case 1:{cout<<"Mon./t";break;}
case 2:{cout<<"Tues./t";break;}
case 3:{cout<<"Wednes./t";break;}
case 4:{cout<<"Thurs./t";break;}
case 5:{cout<<"Fri./t";break;}
case 6:{cout<<"Satur./t";break;}
}
cout<<endl;
break;//可提高执行效率,因一这个数组中只有一个值与i相同,没必要再往下找
}
if (tag==0)
{
switch(array[i].dweek)
{
case 1:{cout<<"/t";break;}
case 2:{cout<<"/t/t";break;}
case 3:{cout<<"/t/t/t";break;}
case 4:{cout<<"/t/t/t/t";break;}
case 5:{cout<<"/t/t/t/t/t";break;}
case 6:{cout<<"/t/t/t/t/t/t";break;}
}
tag=1;
}
cout<<array[i].dayinmonth<<"/t";
if (array[i].dweek==6)
cout<<endl;
}
}
int fungetweekofyear(int year)
{
long int num=0;
int countleap=0;
int countnoleap=0;
for(int i=1900;i<year;i++)
{
if (funisleap(i))
countleap++;
else
countnoleap++;
}
num=366*countleap+365*countnoleap;//how many days are there between 19000101 to this year
int week=-1;
week=num%7;
week++;//to this year week
return week;
}
void funcircle()
{
int year=0;
bool isleap=false;
int i=0,j=0;
int vmonth=0,vweek=0;
int firstWeekOfYear=-1;
int Firstofmon[13]={0};//每个月的第一天是一年中的第几天,放入数组中
Cdays array[367];//结构体数组,从array[1]开始存储
cout<<"input a year:";
cin>>year;
firstWeekOfYear=fungetweekofyear(year);//what the week is it year-01-01
cout<<"今年第一天是星期="<<firstWeekOfYear<<endl;
isleap=funisleap(year);
cout<<endl;
int yeardays=0;
if (isleap)
yeardays=366;
else
yeardays=365;
//初始化结构体数组
for(i=1;i<=yeardays;i++)
{
array[i].dayinmonth=0;
array[i].dmonth=0;
array[i].dweek=0;
array[i].dtotalweek=0;
}
funfirstofmon(Firstofmon,isleap);//得到第几天数组,存该月第一天是一年中的第几天
funweekmonth(Firstofmon,yeardays,array,firstWeekOfYear);//计算是第几个月,星期几,将结果放入结构体数组中
int whichform=-1;
cout<<"输入一种显示方式:输入1 为简洁显示,输入 2 为详细显示 :";//1是简单方式,2是详细方式
cin>>whichform;
cout<<"/n公元"<<year<<"年";
if (isleap)
cout<<"是闰年"<<endl;
else
cout<<"是平年"<<endl;
if (whichform==2)
{
cout<<"/n打印数组Firstofmon[],共12项,表示本月第一天是一年中的第几天"<<endl;
for(i=0;i<12;i++)
cout<<"第"<<i+1<<"月第一天是"<<year<<"年几"<<Firstofmon[i]<<"天"<<endl;//已通过测试
cout<<endl;
display(yeardays,Firstofmon,array);
}
else if (whichform==1)
display1(yeardays,Firstofmon,array);
else
{cout<<"输入错误,按任意键退出!!/n";exit(0);}
cout<<"/n/n_____explorewen^1^:that is all!_______"<<endl;
char iscontinue='A';
cout<<"继续执行吗?( y / n )";
cin>>iscontinue;
if (iscontinue=='y')
funcircle();
else if (iscontinue=='n')
{ cout<<"结束执行,按任意键退出!!/n" ;exit(0);}
else
cout<<"输入出错,按任意键退出!!";
}
void main()
{
cout<<"__________print calendar__________"<<endl;
funcircle();
cin.get();
}