簡體   English   中英

查找列表中元素的最長公共前綴

[英]finding the longest common prefix of elements inside a list

我有一個序列print(lcp(["flower","flow","flight", "dog"]))應該返回fl 目前我可以讓它返回flowfl

我可以找到應該刪除ow的實例,並嘗試了不同的方法來刪除它們。 但是他們似乎遇到了語法問題,我似乎無法自己解決。

我非常感謝一些指導,或者我自己擁有解決這個問題的工具,或者從一個可行的建議解決方案中學習。

def lcp(strs):
    if not isinstance(strs, list) or len(strs) == 0:
        return ""

    if len(strs) == 1:
        return strs[0]

    original = strs[0]
    original_max = len(original)
    result = ""

    for _, word in enumerate(strs[1:],1):
        current_max = len(word)
        i = 0
        while i < current_max and i < original_max:
            copy = "".join(result)
            if len(copy) and copy[i-1] not in word:
#                 result = result.replace(copy[i-1], "")
#                 result = copy[:i-1]
                    print(copy[i-1], copy, result.index(copy[i-1]), i, word)
            if word[i] == original[i]:
                result += word[i]
            i += 1

    return result
        
print(lcp(["flower","flow","flight", "dog"])) # returns flowfl should be fl
print(lcp(["dog","car"])) # works
print(lcp(["dog","racecar","car"])) # works
print(lcp([])) # works
print(lcp(["one"])) # works

我研究了一個替代方案,它不能解決在同一個循環中刪除的問題,在最后添加一個計數器。 但是我的直覺表明它可以在 for 和 while 循環中解決,而不會增加代碼膨脹。

    if len(result) > 1:
        counter = {char: result.count(char) for char in result}
        print(counter)

我已經使用以下方法解決了這個問題。

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        N = len(strs)
        if N == 1:
            return strs[0]
        len_of_small_str, small_str = self.get_min_str(strs)
        ans = ""
        for i in range(len_of_small_str):
            ch = small_str[i]
            is_qualified = True
            for j in range(N):
                if strs[j][i] != ch:
                    is_qualified = False
                    break
            if is_qualified:
                ans += ch
            else:
                break
        return ans
        
    def get_min_str(self, A):
        min_len = len(A[0])
        s = A[0]
        for i in range(1, len(A)):
            if len(A[i]) < min_len:
                min_len = len(A[i])
                s = A[i]
                
        return min_len, s
                  

您可能需要重新表述您的目標。

根據您的描述,您不需要最長的公共前綴,而是大多數單詞與第一個相同的前綴。

您的問題之一是您的測試僅測試一個真實案例和四個邊緣案例。 做一些更真實的例子。

這是我的建議:我主要添加了 elif 來檢查我們是否在第一個字母上已經存在差異,然后丟棄條目。

它還覆蓋原始以基於公共前綴與下一個單詞重建字符串(如果有的話)

def lcp(strs):
    if not isinstance(strs, list) or len(strs) == 0:
        return ""

    if len(strs) == 1:
        return strs[0]

    original = strs[0]
    result = ""

    for word in strs[1:]:
        i = 0
        while i < len(word) and i < len(original) :
            if word[i] == original[i]:
                result += word[i]
            elif i == 0:
                result = original
                break
            i += 1
        
        original = result
        result = ""

    return original
        
print(lcp(["flower","flow","flight", "dog"])) # fl
print(lcp(["shift", "shill", "hunter", "shame"])) # sh
print(lcp(["dog","car"])) # dog
print(lcp(["dog","racecar","car"])) # dog
print(lcp(["dog","racecar","dodge"])) # do
print(lcp([])) # [nothing]
print(lcp(["one"])) # one

返回一組單詞共有的最長前綴。

def lcp(strs):
    if len(strs) == 0:
        return ""
    
    result = strs[0]

    for word in strs[1:]:
        for i, (l1, l2) in enumerate(zip(result, word)):
            if l1 != l2:
                result = result[:i]
                break
        else:
            result = result[:i+1]

    return result

結果:

>>> print(lcp(["flower","flow","flight"]))
fl
>>> print(lcp(["flower","flow","flight", "dog"]))

>>> print(lcp(["dog","car"]))

>>> print(lcp(["dog","racecar","car"]))

>>> print(lcp([]))

>>> print(lcp(["one"]))
one
>>> print(lcp(["one", "one"]))
one

暫無
暫無

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

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