classSolution: defromanToInt(self, s: str) -> int: mapping = {'I':1, 'V': 5, 'X': 10, 'L': 50, 'C':100, 'D': 500, 'M': 1000} i = 0 result = 0 l = len(s) while i < l : if s[i] == 'I' : if i + 1 < l and s[i+1] == 'V' : result += 4 i += 1 elif i + 1 < l and s[i+1] == 'X': result += 9 i += 1 else: result += 1 elif s[i] == 'X': if i + 1 < l and s[i+1] == 'L': result += 40 i += 1 elif i + 1 < l and s[i+1] == 'C': result += 90 i += 1 else: result += 10
elif s[i] == 'C': if i + 1 < l and s[i+1] == 'D': result += 400 i += 1 elif i + 1 < l and s[i+1] == 'M': result += 900 i += 1 else: result += 100 else: result += mapping[s[i]] i += 1 return result
我就写了上面的代码,果然极其乏味,我以此写对了,不用 mapping 也是可以的,用了也没节省很多。从中,我学到了一个点,就是 Python 是没有 switch 语句的,只能用 if 来代替,那也没什么。
然后我还是看了看评论和题解,果然,就是这么无聊的题目,有人也能给你写出一朵花来:
1 2 3 4
classSolution: defromanToInt(self, s: str) -> int: d = {'I':1, 'IV':3, 'V':5, 'IX':8, 'X':10, 'XL':30, 'L':50, 'XC':80, 'C':100, 'CD':300, 'D':500, 'CM':800, 'M':1000} returnsum(d.get(s[max(i-1, 0):i+1], d[n]) for i, n inenumerate(s))
来赏析一个老哥的作品,Python,两行搞定。简直了。同样是使用 dict 数据结构做了个映射,看看这个老哥的功力,对 api 熟悉到了一定的境界,让我叹为观止。这里用到了 dict 的一个 api,get 方法,这个方法允许输入第二个参数,参数的作用是一旦没有取到,就用第二个参数作为缺省值来返回。老哥利用了这一点,每次迭代都尝试从串里取两位出来,如果取到了合法值,就查表取得数值,如果没有取到合法值,就用第二个位的字母的值代替,真是巧妙,省掉了多少个 if 条件啊,妙,实在是妙!
再看 max 函数的用法,迭代的过程中,每次需要取两个出来,但是第一个字符的时候,只能取一个,用了一个 max,当下标为负数的时候,就只取一位数字,又是妙到颠毫。还展示了一个 enumerate 方法迭代 dict 的用法,就相对来说比较平淡了。
上一篇文章洋洋洒洒介绍了一些关于我对 IoC 的学习和理解,这篇文章继续来说说这个话题。认识一个事物,常用的方法就是 5W1H 法,这个方法提醒我们,尽可能全面去认识,不要遗漏某些方面,这里,最最重要的,可能就是 Why,也就是为什么。
这其实是一个非常艰难的话题,我只能硬着头皮来写写,因为能参考的东西实在是不多,就算是 Martin 老爷,也更多谈及了 What 的问题,比较少谈及了 Why,对于他来说,似乎是不言自明的。但是,说实在的,我不明白。比如说,我不明白,我们为什么要 IoC?如果不使用 IoC 的话,我们还有什么选择?IoC 和其他选择之间,优劣如何?
如果细看 Martin 老爷的文章,话里话外似说,其实所有的框架都是 IoC 的。我们似乎不能去对比 IoC 和非 IoC 的框架。等于就失去了和从差异去认识的机会了。
局限于英文水平和对软件工程“学术界”了解的浅薄,我对 Inverstion of Control —— 中文或许可以翻译成“反向控制” —— 的理解,总是停滞在一种似是而非的程度。我尝试通过搜索来学习,发现我能搜到的中文文章,都不能给我很大的帮助,有的在大谈特谈 Spring 框架如何如何;有的又说,想搞清楚 IoC,你先要理解 DIP …… ;也有的,干脆就说,所谓的 IoC 根本就是 DI。一时间,各种术语满天飞,越发让我觉得糊涂了。
不得已,我又开始搜寻英文资料,发现基本也是各种意见都有,但是无一例外都会指向一个地方,就是 Martin Fowler(马丁・福勒)的文章(很感谢国外这些博客的作者,都有良好的习惯,让人比较容易找到一个概念的发展脉络)。通过学习和对比各种国内的文章,我似乎对这个概念更加清晰了一些,不敢说全懂了,但是总算比以前明了了一点。特此记录。
classSolution: defstrStr(self, haystack: str, needle: str) -> int: i, j = len(haystack), len(needle) if j == 0: return0 x, y = 0, 0 while x <= i - j: for y inrange(j): if haystack[x + y] != needle[y]: break if needle[y] == haystack[x + y]: return x else: x += 1 return -1
classSolution: defsearchInsert(self, nums: List[int], target: int) -> int: for i inrange(len(nums)): if target <= nums[i]: return0if i == 0else i returnlen(nums)
yum update error: rpmdb: BDB0113 Thread/process 4196/140144005818432 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages index using db5 - (-30973) error: cannot open Packages database in /var/lib/rpm CRITICAL:yum.main:
classSolution: defcountAndSay(self, n: int) -> str: if n == 1: return"1" say, i, new = "1", 1, "" while i < n: num = say[0] count = 0 for j inrange(len(say)): if num == say[j]: count += 1 else: new += str(count) + num count = 1 num = say[j] new += str(count) + num say, new = new, "" i += 1 return say
另外,值得一提的是,有不少人提到了递归法,这个题目显然具备了递归的结构,比如,计算第 n 个串,本质上就是对第 n - 1 个串的描述。所以,可以用递归法,不过这个题目的特殊之处在于,用递归写,也并没有简单多少,反倒增加了栈的成本。没什么意思,其实栈里只是存储了 n - 1 个串的表达而已,用一个变量就可以存了。像我上面写的代码一样。