簡體   English   中英

檢查是否可以使用提供的列表中的單詞將字符串拆分為句子

[英]Check if string can be splitted into sentence using words in provided list

我最近偶然發現了編碼任務,我一直在努力把它做好。 它是這樣的:


給定一個非空字符串s和一個包含非空單詞列表的列表word_list ,確定s可以被分割成一個或多個字典單詞的空格分隔序列。 您可以假設word_list不包含重復項,但每個單詞都可以使用多次。

例如,給定:

s = 'whataniceday'
word_list = ['a', 'what', 'an', 'nice', 'day']

返回True ,因為'whataniceday'可以細分為'what a nice day'


我想出了一個非常幼稚的解決方案,它適用於這個特定的例子,但是讓它失敗並不難,例如通過向word_list添加一個單詞, word_list中的其他單詞以(即['a', 'wha', 'what', 'an', 'nice', 'day'] )。 還有很多其他事情可能會弄亂我的解決方案,但無論如何這里是:

s = "whataniceday"
word_list = ["h", "a", "what", "an", "nice", "day"]

def can_be_segmented(s, word_list):
    tested_str = s
    buildup_str = ''

    for letter in tested_str:        
        buildup_str += letter

        if buildup_str not in word_list:
            continue

        tested_str = tested_str[len(buildup_str):]
        buildup_str = ''

    return bool(tested_str == '' and buildup_str == '')

print(can_be_segmented(s, word_list))

你們知道如何解決它嗎? 或者也許有更好的方法來解決這個問題?

>>> import re
>>> s = 'whataniceday'
>>> word_list = ['a', 'what', 'an', 'nice', 'day']
>>> re.match('^(' + '|'.join(f'({s})' for s in word_list) + ')*$', s)
<_sre.SRE_Match object; span=(0, 12), match='whataniceday'>

作為一個函數:

import re
def can_be_segmented(s, word_list):
    pattern = re.compile('^(' + '|'.join(f'({s})' for s in word_list) + ')*$')
    return pattern.match(s) is not None

使組不捕獲 ( (?:word)而不是(word)可能是一種優化,以便re.match不必跟蹤匹配的單詞,但我不打算計時。

如果您的單詞不僅僅是字母,您可能希望通過re.escape()傳遞它們(如f'({re.escape(s)})'而不是f'({s})' )。

如果您要混合大小寫並且希望它們匹配,則傳遞re.IGNORECASEre.I標志(如pattern.match(s, re.I)而不是pattern.match(s) )。

有關更多信息,請參閱re文檔

這是我的解決方案,為了簡潔和遞歸使用生成器表達式

s = "whataniceday"
word_list = ["h", "ani", "a", "what", "an", "nice", "day"]

def can_be_segmented(s, word_list):
    return s == "" or any(
        s.startswith(word) and can_be_segmented(s[len(word):], word_list)
        for word in word_list)

assert can_be_segmented(s, word_list)
assert not can_be_segmented("whataniannicday", word_list)

這段代碼指出,如果我們能找到一個單詞,字符串就可以被分割,這樣字符串就可以從這個單詞開始,而字符串的其余部分本身也可以被分割。

def can_be_segmented(s, word_list):

    # try every word in word_list
    for word in word_list:

        # if s is equal to a word, then success
        if s == word:
            return True

        # otherwise if s starts with a word, call ourselves recursively
        # with the remainder of s
        elif s.startswith(word):
            if can_be_segmented(s[len(word):], word_list):
                return True

    # we tried every possibility, failure
    return False

在評論中解釋

def contains(text, pattern):
    for i in range(len(text) - len(pattern)):
        found = True
 
        for j in range(len(pattern)):
            if text[i + j] != pattern[j]: # comparing each letter
                found = False
                break
 
        if found:
            return True
 
    return False


   
s = 'hatanicda'
word_list = ['a', 'what', 'an', 'nice', 'day']
match = []

for i in word_list:
    if contains(s, i) and len(i) > 3: # 3 since word has to be more than is/are/the to be meaningful 
        match.append(i)

print(bool(match))
False

[Program finished]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM