- 常规解法
- 特殊解法
通过此文章,将介绍一种求以上问题的极简算法。(文字不好看就看图片吧)
常规解法
常规解法是通过一个数组,保存12个月每个月的天数,(默认2月是28天),输入年份后,将该月之前的所有天数之和加起来,再加上该月日期,即可得到平年下该年月日为该年的第几天,但是如果是闰年,并且月数大于等于3月,那说明该年天数还得继续得加上一天,通过此方法可以求得任意年日是该年的第几天。
常规解法源码贴出:
#include特殊解法#include int main() { int year, month, day, sum = 0, i, j, flag = 0; int monthdays[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; printf("请输入年份:"); scanf("%d", &year); printf("请输入月数:"); scanf("%d", &month); printf("请输入日期:"); scanf("%d", &day); if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { flag = 1; } else { flag = 0; } for (i = 0; i < month - 1; i++) { sum = sum + monthdays[i]; } sum = sum + day; if (month >= 3 && flag) { sum = sum + 1; } printf("taday is %dth dayn", sum); return 0; }
此算法易懂,但是代码量较大,并且定义数组也占用内存资源,下面介绍非常规 *** 作:精简代码:真正的核心代码就几行。
先贴出核心代码:
#includeint days(int y, int m, int d); int main() { int year, month, day; printf("请输入年份:"); scanf("%d", &year); printf("请输入月数:"); scanf("%d", &month); printf("请输入日期:"); scanf("%d", &day); printf("该日是该年的第%d天n", days(year, month, day) - days(year, 1, 1) + 1); } int days(int y, int m, int d) { if (m < 3) { y--; m += 12; } return 365 * y + (y >> 2) - y / 100 + y / 400 + (153 * m - 457) / 5 + d - 306; }
分析过程:
函数功能 计算出该年该天距离0001-1-1(公元1年1月1日)的天数
算法思路: 1,先找出每个月天数的规律
把1月和2月当成上一年的13月和14月
月份:03-04-05-06-07;08-09-10-11-12;13-14;
天数:31-30-31-30-31;31-30-31-30-31;31-30(28)
为了凸显规律,5个月,5个月一组
规律就是:1-0-1-0-1(重复)
2,找到m个月之前有多少天的公式(以3月为第一个月)
由此规律就可以知道在m月(以3月为第一个月)之前有多有多少天
月份:03-04-05-06-07;08-09-10-11-12;13-14;
天数: 0- 1- 1- 2- 2; 3- 4- 4- 5- 5; 6- 7(28)(7用不到)
所以有此表达式:(3*m-7)/5
加上每个月30天后的gl
月份:03-04-05-06- 07; 08- 09- 10- 11- 12;13-14;
天数: 0-31-61-92-122;153-184-214-245-275;306-337(28)
(因为求得是每个月之前的天数,正好2月在最后一天,所以这个数据可以舍弃,直接加上day即可(day<=28))
所以有此表达式:(153*m-457)/5,求得m月之前有多有多少天
如:m=3,之前只有0天
m=4,之前有31天
…
但是这是以3月为第一个月的每个月之前的天数
当月数为3月之前,总天数不可能为负数,所以当月数为3月之前时,要将其转化为13,14月
但是这样子在三月之前的天数都时300多天,相当于向前一年借了有年,所以年数要减少一年
所以得出天数的规律:365y+(153m-457)/5-306+d
3,解决闰年每年多一天的问题
四年一闰,百年不闰,四百年再闰
所以每四年天数就要多一天:y>>2(相当于y/4(取整))
但是每100年就不闰,所以百年时的天数不会相加,所以要减回去
同理四百年再闰,还得加上这些年有多少个400年,补上2月多有的一天
所以核心结果就是右边的公式:365y+(y>>2)-y/100+y/400+(153m-457)/5+d-306
(此算法是我大一寒假看到的,不算我的)
仔细一看核心代码,也就只有两行。
现在有了上面的函数之后,求两任一年1月份天数之长,也就可以通过相减就可以得到,所以在主函数我们只需要调用以下语句,就可以达到目的,求得以上问题:
days(year,month,day) - days(year,1,1) +1
(子函数的功能是算距离某一天的天数,计算是该年的某一天需要再加上一天)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)