2014-10-28 84 views
0

我正在研究一个字谜程序,其中单词和给定长度的文本文件作为命令参数传递。只应该考虑给定长度的字形。该程序应该只打印最大集合中的单词。如果有几个同样大的集合,则应打印所有集合。我很困惑。 例如: 顷 屁股 耳朵 时代 RASE 烤焦 血清返回集合字典中最长的集合?

import sys 
from collections import defaultdict 
def main(): 
try: 
    if len(sys.argv) > 2: 
     filename = sys.argv[1] 
     global length 
     length = int(sys.argv[2]) 
     wordDict = readFile(filename) 
     print(wordDict) 
except IOError: 
    print("Error: file not found.") 
except NameError: 
    print("Error: a text file and a length are required.") 


def readFile(filename): 
    inFile = open(filename, "r") 
    try: 
     return readData(inFile) 
    finally: 
     inFile.close() 

def readData(inFile): 
    wd = defaultdict(set) 
    for line in inFile: 
     line = line.strip() 
     if length == len(line): 
      wd["".join(sorted(line))].add(line) 
    j = [k for k, v in wd.items() if len(v)==mx] 
    return j 
main() 
+0

你的随机'length'来自'readData'吗? – smac89 2014-10-28 02:20:40

+0

长度来自def main()中长度的命令行参数。我宣布它是全球性的,我知道有更好的方法来做到这一点。 – SolidusZero 2014-10-28 03:35:08

+0

如果您的问题得到解决,请接受答案。否则,什么不工作? – smac89 2014-10-28 03:41:37

回答

2

首先,你如何让某些迭代最大的东西吗?具有key参数的max函数指定您如何度量值。

你如何测量一组的长度?功能len

你如何得到一个字典中所有值的迭代?方法values(或2.x,itervalues)。

所以:

max(d.values(), key=len) 

例如:

>>> d = {'a': {'a'}, 
...  'art': {'art', 'rat', 'tar'}, 
...  'at': {'at', 'ta'}} 
>>> max(d.values(), key=len) 
{'art', 'rat', 'tar'} 

当然,如果有两个同等大集,你会得到一个任意。但是因为你只是要求“最大”,这似乎是一个合理的解释。


如果你想要所有同样最大的集合,有几种方法可以做到这一点。

一个明显的可能性是明确地做到这一点。考虑你如何实施max:只是检查每个值,如果它大于迄今为止见过的最大值,则它是新的最大值。 (这只是稍微复杂的key函数;它只是意味着你必须比较key(value) > key(biggest_value)。)现在,你将如何实现一个all_max函数?只要保留一个列表或一组同等大的最大值。如果每个新值都大于任何最大值,那么只有一个新值就有一个新列表;如果相等,则将其添加到现有列表中。

但是,如果你考虑一下,你可以再次使用相同的多重词典技巧:创建一个dict映射长度为该长度的集合。 (你确实需要一个小技巧:集合不可散列,但frozensets是。)然后,你只需选择最大的长度。当然,如果你不需要第一次查询以外的任何字典,存储它就浪费内存,但通常这些类型的东西会反复使用。

>>> length_d = defaultdict(set) 
>>> for value in d.values(): 
...  length_d[len(value)].add(frozenset(value)) 
>>> max(length_d) 
3 
>>> length_d[max(length_d)] 
{frozenset(['rat', 'art', 'tar'])} 

好的,在我的例子中没有特别令人兴奋,因为只有一个长度为3的集合,但你明白了。

如果你想要一些更简洁的东西,代价是性能上的一点点(它将是对数线性时间而不是线性时间),你总是可以按大小排序(sorted(d.values(), key=len, reverse=True)),然后迭代,直到你得到较小的值(例如,与itertools.takewhile)。

+0

我需要同样大的设置。如果说,我做最大=排序(最大(wd.values(),键= len)),我相信我必须比较它并测试是否有任何进一步的集合(值)是相等的?我很困惑。 – SolidusZero 2014-10-29 16:33:36

+0

@SolidusZero:让我更新答案。 – abarnert 2014-10-29 18:31:33