编程示例:求闰年的年份的函数
编程示例:求闰年的年份的函数
今年是2020年2月29日,这个日子是闰年中的闰日。特意分享一下有关闰年的小例子。
输入一个年份值,判断是否是闰年
例如输入2020,输出是闰年,输入2019年,输出是平年
闰年用1 表示,平年用0表示
逻辑如下,能被4整除,却不能被100整除的数,是闰年,
能被400整除的数是闰年。
不能被4整除的数是平年,
能被100整除却不能被400整除的数是平年。
以上的四类整数的集合关系如下:
这个函数的实现是简单的,只要如实地把上述描述转化成编程语言的代码就行了。
不管是Java,C,还是Javascript等语言,写成的代码都是很相似的。
例子写法一
int is_leap_year(int years)
{
if(years%4==0&&years%100!=0)
{return 1;}
if(years%400==0)
{return 1;}
if(years%4!=0)
{return 0;}
if(years%100==0&&years%400!=0)
{return 0;}
}
根据集合的嵌套关系,也就是父子集合之间的关系,程序可以等价地写成如下的两种写法
例子写法二
int is_leap_year(int years)
{
if(years%400==0)
{return 1;}
else
{if (years%100==0)
{return 0;}
else
{
if (year%4==0)
{return 1;}
else
{return 0;}
}
}
}
例子写法三
int is_leap_year(int years)
{
if(years%4!=0)
{return 0;}
else
{if (years%100!=0)
{return 1;}
else
{
if (year%400!=0)
{return 0;}
else
{return 1;}
}
}
}
根据写法二和写法三,我们可以使用嵌套的条件语句,实现集合的父子关系。
接下来,做程序的性能分析,这三种程序写法在逻辑上都能保证正确性。
这个小函数的执行效率与条件的判断次数高度地负相关。
能被4整除,却不能被100整除的数,占整数的24%,
能被400整除的数占整数的0.25%。
不能被4整除的数占整数的75%,
能被100整除却不能被400整除的数占整数的0.75%。
在以1到400这400个整数作为测试用例,让三种写法的程序,都执行400次时,
计算一下各个程序执行的总的条件判断的次数如下:
写法一的条件判断次数
2*400*24%+3*400*0.25%+4*400*75%+6*400*0.75%=1413
写法二的条件判断次数
3*400*24%+1*400*0.25%+4*400*75%+2*400*0.75%=1495
写法三的条件判断次数
2*400*24%+4*400*0.25%+1*400*75%+3*400*0.75%=505
由以上的计算可知,条件判断的前后顺序很重要,集合越大,越需要优先进行条件判断。
明显可知程序写法三的执行效率最高。
在写法3的基础上,可以把%4 这个求余操作改写 &3的位操作。在逻辑上它们是完全等价的,
而且几乎所有的主流编程语言都支持位操作。位操作与求余操作相比,程序的执行效率提高很多,
程序的可读性下降很多。作为一个需要执行无数次的系统底层函数来说,执行效率优先于程序的可读性。