2016-11-14 120 views
2

编写下面的代码以获取列表/集合和字符串,如果我能够将字符串拆分为列表中的两个单词,则返回。我知道我很接近,我只是无法得到比较权利或什么。将元组与元组进行比较

例如

wordBreakEasy("snowfall", ("apple", "fall", ..., "snow")) 

将返回True

def wordBreakEasy(str1, wordset): 
    wordset1 = set(wordset) 
    breakup = ['%s %s' % (str1[:i], str1[i:]) for i in range(1, len(str1))] 
    newlist = [] 
    for x in breakup: 
    newlist.append((x.split())) 
    wordset2 = set(map(tuple, newlist)) 

    for wordset2 in wordset1: 

这是我不知道该去哪里的地方。

+0

只是为了双检的示例; '“雪花”'不会返回True,因为''flake''不在单词集中,对吗? –

回答

2

添加您的词对元组,而不是作为一个空间分隔的单个字符串,然后筛选上是你wordset1集的子集元组名单:

breakup = [(str1[:i], str1[i:]) for i in range(1, len(str1))] 
present = [tup for tup in breakup if not wordset1.issuperset(tup)] 

我用set.issuperset() method这里;如果参数iterable中的所有元素都存在于集合中,它将返回True,所以如果它返回True,仅当元组中存在两个元素时。

只有然后结合的话成一个字符串:

newlist = [' '.join(tup) for tup in present] 

您不需要这些中介名单,真的;你只需要找到,如果有任何这样元组是您函数返回True一个子集:

breakup = ((str1[:i], str1[i:]) for i in range(1, len(str1))) 
return any(wordset1.issuperset(tup) for tup in breakup) 

我转身breakup成发电机表达;如果你能在早期找到一个匹配的单词对,就不需要建立整个列表。只要其中一个迭代值为真,any() function就会返回True。因为这也是一个生成器表达式,所以这个对单词对进行测试,直到找到匹配。

演示:

>>> def wordBreakEasy(str1, wordset): 
...  wordset1 = set(wordset) 
...  breakup = ((str1[:i], str1[i:]) for i in range(1, len(str1))) 
...  return any(wordset1.issuperset(tup) for tup in breakup) 
... 
>>> wordBreakEasy("snowfall", ("apple", "fall", "...", "snow")) 
True 
>>> wordBreakEasy("snowflake", ("apple", "fall", "...", "snow")) 
False 
+0

你的印刷是真是假?我刚刚结束了退出代码0.我知道,愚蠢的问题。试图全神贯注地说出我的头。其实只是通读你最近的编辑。现在全部清楚!这需要17个大拇指。 thx –

+0

@KelvinDavis:函数*返回一个布尔值。如果您打算输出该值,请添加'print()'。 –

0

这里是itertools.combinations

def word_break(s, words): 
    return (s in map("".join, itertools.combinations(words , 2)) or 
      s in map("".join, itertools.combinations(words[::-1] , 2))) 

word_break('snowfall', ['fall', 'green', 'white', 'cheese', 'snow']) 

+1

尝试在单词中包含1000个单词的算法。 :) –

+0

:)确实,但它仍然是一个很好的解决方案,当len(words)<3000 –