元组部分习题

练习 12-3

编写一个函数 most_frequent,接收一个字符串并按照频率的降序打印字母。

  1 import random
  2 
  3 def most_frequent(s):
  4     hist = make_histogram(s)
  5 
  6     t = []
  7     for x, freq in hist.iteritems():
  8         t.append((freq, x))
  9 
 10     t.sort(reverse=True)
 11 
 12     res = []
 13     for freq, x in t:
 14         res.append(x)
 15 
 16     return res
 17 
 18 
 19 def make_histogram(s):
 20     hist = {}
 21     for x in s:
 22         hist[x] = hist.get(x, 0) + 1
 23     return hist
 24 
 25 
 26 def read_file(filename):
 27     return open(filename).read()
 28 
 29 if __name__ == '__main__':
 30     s = read_file('words.txt')
 31     t = most_frequent(s)
 32     for x in t:
 33         print x
练习 12-4

1 编写一个程序从文件中读入一个单词列表,并打印出所有是回文的单词集合。

2 修改前一个问题的程序,让它先打印最大的回文集合,再打印第二大的回文集合,以此类推。

3 在Scrabble 拼字游戏中,一个“bingo”代表你自己架子上全部7个字母和盘上的一个字母组合成一个8字母单词。哪一个8字母单词可以生成最多的bingo?

1 def signature(s):
  2     t = list(s)
  3     t.sort()
  4     t = ''.join(t)
  5     return t
  6 
  7 
  8 def all_anagrams(filename):
  9     d = {}
 10     for line in open(filename):
 11         word = line.strip().lower()
 12         t = signature(word)
 13 
 14         if t not in d:
 15             d[t] = [word]
 16         else:
 17             d[t].append(word)
 18     return d
 19 
 20 
 21 def print_anagram_sets(d):
 22     for v in d.values():
 23         if len(v) > 1:
 24             print len(v), v
 25 
 26 
 27 def print_anagram_sets_in_order(d):
 28     t = []
 29     for v in d.values():
 30         if len(v) > 1:
 31             t.append((len(v), v))
 32 
 33     t.sort()
 34 
 35     for x in t:
 36         print x
 37 
 38 
 39 def filter_length(d, n):
 40     res = {}
 41     for word, anagrams in d.iteritems():
 42         if len(word) == n:
43             res[word] = anagrams
 44     return res
 45 
 46 
 47 if __name__ == '__main__':
 48     d = all_anagrams('words.txt')
 49     print_anagram_sets_in_order(d)
 50 
 51     eight_letters = filter_length(d, 8)
 52     print_anagram_sets_in_order(eight_letters)

练习 12-5

两个单词,如果可以通过交换两个字母将一个单词转化为另一个,就成为”置换对“;例如:”converse“和”conserve“。编写一个程序查找字典中所有的置换对。提示:不要测试所有的单词对,也不要测试所有可能的交换。

  1 from anagram_sets import *
  2 
  3 def metathesis_pairs(d):
  4     for anagrams in d.itervalues():
  5         for word1 in anagrams:
  6             for word2 in anagrams:
  7                 if word1 < word2 and word_distance(word1, word2) == 2:
  8                     print word1, word2
  9 
 10 
 11 def word_distance(word1, word2):
 12     assert len(word1) == len(word2)
 13 
 14     count = 0
 15     for c1, c2 in zip(word1, word2):
 16         if c1 != c2:
 17             count += 1
 18 
 19     return count
 20 
 21 
 22 if __name__ == '__main__':
 23     d = all_anagrams('words.txt')
 24     metathesis_pairs(d)

练习 12-6

一个英文单词,当逐个删除它的字母时,仍然是英文单词。这样的单词中最长的是什么?

首先,字母可以从两头或者中间删除,但你不能重排字母。每次你去掉一个字母,则得到另一个英文单词。如果一直这么做,最终会得到一个字母,它本身也是一个英文单词——可以从字典上找到的。我想知道这样的最长的单词是什么,它有多少字母?

我会给你一个普通的例子,Sprite。你从sprite开始,取出一个字母,从单词内部取,取走r,这样我们就剩下单词spite,接着我们取走结尾的e,剩下spit,接着取走s,我们剩下pit,it,i。

编写一个程序来找到所有这样可缩减的单词,然后找到最长的一个。

 1 def make_word_dict():
  2     """Reads the words in words.txt and returns a dictionary
  3     that contains the words as keys."""
  4     d = dict()
  5     fin = open('words.txt')
  6     for line in fin:
  7         word = line.strip().lower()
  8         d[word] = word
  9 
 10     # have to add single letter words to the word list;
 11     # also, the empty string is considered a word.
 12     for letter in ['a', 'i', '']:
 13         d[letter] = letter
 14     return d
 15 
 16 
 17 """memo is a dictionary that maps from each word that is known
 18 to be reducible to a list of its reducible children.  It starts
 19 with the empty string."""
 20 
 21 memo = {}
 22 memo[''] = ['']
 23 
 24 
 25 def is_reducible(word, word_dict):
 26     """If word is reducible, returns a list of its reducible children.
 27 
 28     Also adds an entry to the memo dictionary.
 29 
 30     A string is reducible if it has at least one child that is 
 31     reducible.  The empty string is also reducible.
 32 
 33     word: string
 34     word_dict: dictionary with words as keys
 35     """
 36      # if have already checked this word, return the answer
 37     if word in memo:
 38         return memo[word]
 39 
 40     # check each of the children and make a list of the reducible ones
 41     res = []
 42     for child in children(word, word_dict):
43         t = is_reducible(child, word_dict)
 44         if t:
 45             res.append(child)
 46 
 47     # memoize and return the result
 48     memo[word] = res
 49     return res
 50 
 51 
 52 def children(word, word_dict):
 53     """Returns a list of all words that can be formed by removing one letter.
 54 
 55     word: string
 56 
 57     Returns: list of strings
 58     """
 59     res = []
 60     for i in range(len(word)):
 61         child = word[:i] + word[i+1:]
 62         if child in word_dict:
 63             res.append(child)
 64     return res
 65 
 66 
 67 def all_reducible(word_dict):
 68     """Checks all words in the word_dict; returns a list reducible ones.
 69 
 70     word_dict: dictionary with words as keys
 71     """
 72     res = []
 73     for word in word_dict:
 74         t = is_reducible(word, word_dict)
 75         if t != []:
 76             res.append(word)
 77     return res
 78 
 79 
 80 def print_trail(word):
 81     """Prints the sequence of words that reduces this word to the empty string.
 82 
83     If there is more than one choice, it chooses the first.
 84 
 85     word: string
 86     """
 87     if len(word) == 0:
 88         return
 89     print word,
 90     t = is_reducible(word, word_dict)
 91     print_trail(t[0])
 92 
 93 
 94 def print_longest_words(word_dict):
 95     words = all_reducible(word_dict)
 96 
 97     # use DSU to sort by word length
 98     t = []
 99     for word in words:
100         t.append((len(word), word))
101     t.sort(reverse=True)
102 
103     # print the longest 5 words
104     for length, word in t[0:5]:
105         print_trail(word)
106         print '\n'
107 
108 
109 if __name__ == '__main__':
110     word_dict = make_word_dict()
111     print_longest_words(word_dict)

运行结果为:

complecting completing competing compting comping coping oping ping pig pi i

twitchiest witchiest withiest withies withes wites wits its is i

stranglers strangers stranger strange strang stang tang tag ta a

staunchest stanchest stanches stances stanes sanes anes ane ae a

restarting restating estating stating sating sting ting tin in i

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值