两个多月前我参加了Udacity的无人驾驶入门课程,里面有一个专题是关于如何解决难题的,在这里希望总结一下自己的收获和体会。文章的主要内容如下:
- 启发问题:如何计算两个日期之间的天数?
- 解决问题的思路
- 程序实现的过程
- 如何借助已有的成熟思路?
- 用python实现A*寻路算法
- 这次解决问题的思路是什么?
- 收获和体会
启发问题:如何计算两个日期之间的天数?
给定两个日期date_a和date_b(默认规定date_a是在时间上早于或者等于date_b,也没有时间穿越之类的特殊情况 :-P),请计算这两个日期之间的天数。
面对一个问题,第一步应该做的肯定是分析问题。如果理解上就出现了偏差,那么求解的过程一定是曲折的,而且基本上无法得到期望中的输出。
对于上述这个问题,我们可以得知:
输入:两个任意的日期,第一个日期应该要早于第二个日期(但是为了程序的严谨性,仍需要判断一下);
输出:一个表示天数的正整数。
要点:闰年和非闰年的一年总天数不同,因为对应的二月份其天数分别为29和28.
解决问题的思路
如果是由你用笔算来解决这个问题,你的计算过程是怎么样的呢?
这是一个很好的切入点,因为我们可以借鉴自己的计算过程,看是否能够把这个计算过程转变成程序写出来。比如说给定的两个日期分别是20151125和20170509,我们可能想到的是:
总天数 = 20151125到20151231的天数 + 20160101到20161231的天数 + 20170101到20170509的天数
又或者是:
总天数 = 20150101到20170509的天数 - 20150101到20151125的天数
计算过程中都需要判断哪一年是闰年,这个闰年的二月份是否包含在需要计算的日期里面,如果是按照这样类似的“人类思维”来编写程序,一定是能够实现的,但这对于计算机而言,是否是最优解呢?
我们都知道计算机最擅长的事情就是循环简单的动作,那么针对这个问题,我们是否可以让计算机从20151125开始,一天一天地数到20170509呢?
OK,我们来试一下。
程序实现的过程
1. 所需的函数
days_between_dates() : 计算两个日期之间的天数,返回一个正整数;
date_is_before() : 判断某一个日期是否在另一个日期之前,除了检验输入的两个日期的前后关系以后,还可以用于判断是否已经数到了第二个日期(此时需要结束数数的循环);
next_day() : 返回下一个日期;
is_leap_year() : 判断某一年是否是闰年
days_in_month() : 返回某一个月的天数;
2. 简化问题(关键所在)
从整体出发,一开始并不需要考虑哪一年是闰年,哪个月多少天,我们可以简化为假设每个月都是30天(令函数days_in_month()直接return 30),如果计算结果正确,那么再往下走,完善days_in_month()函数返回具体每个月多少天就可以得到一个完整的解决方案了。
3. 完整代码如下
def is_leap_year(year):
if year % 4 == 0:
return True
else:
return False
def days_in_month(year, month):
leap_year = {
1:31, 2:29, 3:31, 4