Kata08:字典是个好东西

Kata08地址

这次的练习又是一个单词游戏,规则很简单,判断一个长度为6的单词是否可以由两个短单词组合而成。

举例来说:

  al + bums => albums
  bar + ely => barely
  be + foul => befoul
  con + vex => convex
  here + by => hereby
  jig + saw => jigsaw
  tail + or => tailor
  we + aver => weaver

作者要求写三次代码:

  • 第一次用最直接最易懂的方法
  • 第二次用最高效的方法
  • 第三次用可扩展性最高的方法

对于我们来说,考虑高效和可扩展性基本已经养成习惯了,强行去写低效直接的代码反而更难做到,于是我们决定不做无用功,直接一步到位。

思路

思路大体来说有正反两种。

正的意思是遍历单词的时候就生成所有可能的长度为6的单词并记录,然后处理长度为6的单词时只要判断是否在记录中即可,显然这样做的复杂度是平方,不可取。

反的意思是先记录所有长度小于6的单词,遇到长度为6的单词时遍历它的所有二分形式并判断二分结果是否存在。对于长度为6的单词来说只有五种二分组合,复杂度是n,可以接受。

思路出来了,具体写的时候反而遇到了两个小麻烦。

第一个麻烦是思维定式,我和小伙伴在写代码的时候不约而同地使用了Kata06中的hash函数,写到一半才发现根本没必要hash,因为这次的处理过程是位置相关的,hash已经没有意义了,只会损耗性能。

第二个麻烦是语言理解不当,我一开始用数组来存储小于6的单词,但是发现速度很慢,要30多秒才能出结果。我想了半天认为性能瓶颈是二分单词,但是这又和一开始分析的结果矛盾。这时候小伙伴写完来找我讨论,我就说起这个问题,然后我发现我2了,这里显然该用字典而不是数组。。。用数组的话Python内置的in操作其实是遍历数组,这样一来复杂度又变成了平方,自然就慢了。换了字典之后果然有效,直接提升两个数量级,不到0.3秒就跑完了。

代码

上代码,依然很简单:

import collections

all_words = {}
n = 6

def generateSon(word):
    for i in range(len(word) - 1):
        yield word[:i], word[i:]

a = 0

with open("wordlist.txt") as f:
    for i in f.readlines():
        word = i.strip()
        if len(word) < n:
            all_words[word] = 1
        elif len(word) == n:
            for son1, son2 in generateSon(word):
                if son1 in all_words and son2 in all_words:
                    a += 1

print a

最后输出的是可以由短单词组成的长度为6的单词数量。

扩展性

上面的代码已经提取出了长度限制n,可以换成任意长度。但是还有一个扩展问题没有解决:划分段数。

这里假设的是二分,那如果要把单词分成三段四段甚至更多该怎么办呢?

讨论了半天递归循环之类的东西,我们最终想到了一个简单的解决办法:封装一个函数,内部多次调用generateSon

这个函数很简单,参数是划分段数,然后用generateSon进行划分,如果划分完数量不够就按顺序再对划分结果进行划分,数量够了就返回。由于是二分,所以可以划分出任意长度,假设要三段,那把第一次二分结果中的任意一段再次二分即可;假设要四段,那把第一次二分的两个结果都进行二分即可,其他段数同理。

思路很清晰了,由于太懒我们没有实现这个函数,大家感兴趣可以自己写一下。

总结

这个练习本质上还是很有用的,对于那些并不习惯从效率和扩展性方面思考的程序员来说可以得到很好的锻炼。对于我们来说,虽然思路是一步到位,但是在具体编程过程中仍然遇到几个小坑,可见还需不断努力。

这已经是第8个Kata,眼看就要到一半了,说实话逐渐发现CodeKata系列并不是非常适合我们。究其原因,还是强度不够。这些练习对于初学者或者初级程序员来说确实可以起到开拓思路锻炼能力的作用,但是对于我们来说有些过于简单。

不过话说回来,收获还是有的,毕竟细节决定成败嘛,多写写代码总没坏处。更重要的是,这次练习让我们养成了每天做练习的习惯,等21个Kata全部做完后我们会选择更合适的练习,那才是真正见效的时候。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容