(壹)判断某天是星期几
基本思路:
首先,我们先选择一个基准1900年1月1日(周一)
其次,我们需要算出X年X月X日与1900年1月1日相差多少天(D1),(D1)包括:(1)X年1月1日与1900年1月1日相差多少天(D2)(2)X年X月1日与X年1月1日相差多少天(D2)(3)X年X月X日与X年X月1日相差多少天(D3)。计算D1需要判断平闰年并用循环相加,计算D2需要构造一个关于平闰年月份天数的数组并用循环相加,D3=X日中的X。
最后,我们取D1除以7的余数,余数是几就是星期几(余0即周日)。
代码如下:
#include<stdio.h>
//判断平闰年
int leap_(int year)
{
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return 1;
else
return 0;
}
//算出D1
int D1_(int year)
{
int i = 0, D1 = 0;
for(i = 1900; i < year; i++)
{
if(leap_(i) == 1)
D1 += 366;
else
D1 += 365;
}
return D1;
}
//算出D2
int D2_(int year, int month)
{
int l_[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//l代表leap闰年
int c_[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//c代表common平年
int i = 0,D2 = 0;
int leap = leap_(year);
for(i = 1; i < month; i++)
{
if(leap == 1)
D2 += l_[i];
else
D2 += c_[i];
}
return D2;
}
//定义一个输出除7余几的函数
int re_(int D)
{
return D % 7;
}
int main()
{
int year, month, day;
scanf("%d %d %d", &year, &month, &day);
int D = 0, re = 0;
D = D1_(year) + D2_(year, month) + day;
re = re_(D);
if(re_(D) == 0)
re = 7;
printf("%d年%d月%d日是星期%d", year, month, day, re);
return 0;
}
对代码的完善:
可能在某些情况下,我们输入的月份或者天数与实际不相符合,而上述代码中并没有体现纠错的功能,下面我们对其增添一个判断是否输入错误的函数:
在上述代码的re_函数后面添加如下代码:
int error_(int year, int month, int day)
{
int l_[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//l代表leap闰年
int c_[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//c代表common平年
if(year < 1900)
return 0;
if(month < 1 || month > 12)
return 0;
if(leap_(year) == 1 && day > l_[month])//“== 1”可以省
return 0;
if(leap_(year) == 0 && day > c_[month])
return 0;
return 1;
}
int main()
int year, month, day;
while(1)
{
scanf("%d %d %d", &year, &month, &day);
if(error_(year, month, day) == 0)
{
printf("Date is error!Please input again:\n");
}
else
break;
}
int D = 0, re = 0;
D = D1_(year) + D2_(year, month) + day;
re = re_(D);
if(re_(D) == 0)
re = 7;
printf("%d年%d月%d日是星期%d", year, month, day, re);
return 0;
}
这样写出来的代码虽然看起来很长,且毋庸置疑一定有别的方法更快更简洁,但对于我这样的初学者而言,这样写思路较为清晰,不容易出错,准确率更高,减少面向答案编程的情况。
(贰)计算某两天相差多少天
[法一]:
基本思路:
上一题中我们以1900年1月1日为基准点,计算X年X月X日与1900年1月1日相差多少天,我们可以以此为启发,不妨以公元0年1月1日为基准点(公元前的日期就不算了哈),分别计算Y年Y月Y日和Z年Z月Z日与公元0年1月1日相差多少天,不妨分别设为D1天和D2天,|D1-D2|即为二者相差的天数。
代码如下:
#include<stdio.h>
//判断平闰年
int leap_(int year)
{
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return 1;
else
return 0;
}
//算出D1
int D1_(int year)
{
int i = 0, D1 = 0;
for(i = 0; i < year; i++)
{
if(leap_(i) == 1)
D1 += 366;
else
D1 += 365;
}
return D1;
}
//算出D2
int D2_(int year, int month)
{
int l_[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//l代表leap闰年
int c_[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//c代表common平年
int i = 0,D2 = 0;
int leap = leap_(year);
for(i = 1; i < month; i++)
{
if(leap == 1)
D2 += l_[i];
else
D2 += c_[i];
}
return D2;
}
int main()
{
int year1, month1, day1, year2, month2, day2;
scanf("%d %d %d", &year1, &month1, &day1);
scanf("%d %d %d", &year2, &month2, &day2);
int D1 = D1_(year1) + D2_(year1, month1) + day1;
int D2 = D1_(year2) + D2_(year2, month2) + day2;
int D = ((D1 > D2) ? (D1 - D2) : (D2 - D1));
printf("%d年%d月%d日与%d年%d月%d日相差%d天", year1, month1, day1, year2, month2, day2, D);
return 0;
}
这个代码与(壹)中代码类似,为了增强简洁性,笔者省去了判断输入格式是否正确的代码,有兴趣的读者可以自行添加(能发到评论区更是我的荣幸)
[法二]:
基本思路:
手撕,直接暴力拆解两个日期的年、月、日,进行差值运算。整体思路与[法一]大同小异,复杂度比[法一]更高,故笔者不再赘述,有兴趣的读者可以自行完成。此外,C语言中还提供了标准库函数<time.h>,可以更方便的计算日期,由于笔者的能力有限,故在此不再叙述,有兴趣的读者可以自行查阅。待笔者学习以后更新也可。
(叁)计算某日之后X天的日期
基本思路:
首先构造出平闰年月份天数的数组,并可以将某年某月的天数返回
其次利用“进位思想”,天数超过本月的天数时,月份加1,天数重置为1;当月数超过12时,年份加1,月份重置为1;
最后利用循环的手段,实现“进位”过程
代码如下:
#include<stdio.h>
int leap_(int year)
{
return ((year % 4 == 0 && year % 100 != 0)|| year % 400 == 0);
//若为闰年,则括号里为真,返回值为1;反之,若为平年,则括号里为假,返回值为0。
}
int day_(int year, int month)
{
int l_[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int c_[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(leap_(year) == 1)
return l_[month];
else
return c_[month];
}
int main()
{
int year = 0, month = 0, day = 0, N = 0, i = 0;
scanf("%d %d %d", &year, &month, &day);
scanf("%d", &N);
for(i = 1; i <= N; i++)
{
day++;
if(day > day_(year, month))
{
day = 1;//“进位”,天数重置为1。
if(month > 12)
{
month = 1;//“进位”,月数重置为1。
year++;
}
else{
month++;
}
}
}
printf("%d年%d月%d日", year, month, day);
return 0;
}
(肆)计算某日之前X天的日期
基本思路:
与上一题思路基本相同,运用“借位思想”,当天数小于1时,月数要减1,天数重置为上月天数的数值;如果月数小于1时,年数要减1,月数重置为12。利用循环的手段进行“借位”过程。
代码如下:
#include<stdio.h>
int leap_(int year)
{
return ((year % 4 == 0 && year % 100 != 0)|| year % 400 == 0);
//若为闰年,则括号里为真,返回值为1;反之,若为平年,则括号里为假,返回值为0。
}
int day_(int year, int month)
{
int l_[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int c_[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(leap_(year) == 1)
return l_[month];
else
return c_[month];
}
int main()
{
int year = 0, month = 0, day = 0, N = 0, i = 0;
scanf("%d %d %d", &year, &month, &day);
scanf("%d", &N);
for(i = 1; i <= N; i++)
{
day--;
if(day < 1)
{
if(month >= 2)
{
month--;
day = day_(year, month);
}
else
{
year--;
month = 12;
day = 31;
}
}
}
printf("%d年%d月%d日", year, month, day);
return 0;
}
以上为四道有关日期编程的问题解答,之后会陆续更新,感谢您的耐心阅读与对笔者的信任。如果对我的方法有疑问,敬待您的留言。
&spm=1001.2101.3001.5002&articleId=143982570&d=1&t=3&u=7e3e066212fc4c16ad96800c2a31fc3e)
3446

被折叠的 条评论
为什么被折叠?



