簡體   English   中英

如何以可能使用庫函數的pythonic方式找到python中兩個字符串之間的最長公共后綴前綴?

[英]How to find the longest common suffix prefix between two strings in python in a pythonic way possibly using library functions?

假設我有兩個字符串, s1 = "1234"s2 ="34567" ,所以s1s2之間的最長公共后綴前綴是"34" 我想知道是否存在任何 pythonic 方法來真正快速地獲得這個匹配部分( "34" )。

我可以像下面這樣天真地做到這一點,但我很想知道是否有一個有趣的庫 function 或算法來完成這項工作。

s1 = "1234"
s2 = "34567"
length1 = len(s1) 
length2 = len(s2)

length = (length1 if length1<= length2 else length2)

for i in reversed(range(0, length)):
    if s1[-i - 1:] == s2[:i + 1]:
        print(s1[-i - 1:])
        break
    elif i > 0:
        continue
    else:
        print("no common suffix prefix")

Output:

34

我想要一些緊湊而智能的東西!

您的算法中的邏輯盡可能簡單,但您絕對可以壓縮符號。 例如,檢查大小為n的前綴與大小為n的后綴很簡單:

s1[-n:] == s2[:n]

您用來檢查字符串長度的三元運算符是

min(len(s1), len(s2))

范圍可以 go 自行向后。 range(x)的倒數是

range(x - 1, -1, -1)

您可以創建一個迭代器來檢查n的每個遞減值並返回第一個非零結果。 幸運的是,如果迭代器為空, next接受第二個參數表示默認值:

common = next((s2[:n] for n in range(min(len(s1), len(s2)) - 1, -1, -1) if s1[-n:] == s2[:n]), '')

那是強制性的單線。 一個更清晰的解決方案可能是:

def common_fix(s1, s2):
    steps = range(min(len(s1), len(s2)) - 1, -1, -1)
    return next((s2[:n] for n in steps if s1[-n:] == s2[:n]), '')

作為一項規則,將您的功能和打印分開。 獲取一個值,然后處理它(無論是通過打印還是其他方式)

以下是幾個替代實現:

您知道s1的后綴必須以s2[0]開頭。 所以使用s1.find(s[0])來尋找候選起點。 此外,可以使用s2.startswith()代替迭代s2 我不知道它是否更快,但意圖很明確。

def suffix_prefix_1(s1, s2):
    i = s1.find(s2[0])
    while i >= 0:
        if s2.startswith(s1[i:]):
            return s1[i:]

        i = s1.find(s2[0], i+1)

    return ''

如果您使用的是 Python 3.8,海象運算符允許您這樣編寫:

def suffix_prefix_1A(s1, s2):
    while (i := s1.find(s2[0])) >= 0:
        if s2.startswith(s1[i:]):
            return s1[i:]

    return ''

使用s1.endswith()可以完成同樣的事情:

def suffix_prefix_2(s1, s2):
    e= len(s2)
    while e > 0:
        if s1.endswith(s2[:e]):
            return s2[:e]
        e = s2.rfind(s1[-1], 0, e-1) + 1

    return ''

只是為了好玩,讓我們使用正則表達式:

import re

def suffix_prefix_3(s1, s2):
    match = re.search(f"^{'?'.join(s1)}", s2)
    return match[0] if match else ''

這有效:

s1="1234"
s2="34567"
for i in range(len(s1)):
    if s1[i] == s2[0]:
        if s1[i::] in s2[0:len(s1[i::])]:
            print(s1[i::])

for循環查找s1的長度。 然后它迭代該長度。 如果s1[i]等於s2的開始,它會檢查s1[i::]是否在s2中。 如果這是真的,它會打印出s1[i::]

暫無
暫無

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

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