簡體   English   中英

如何在 Python 中定位兩個字符串之間的特定差異

[英]How to locate a specific difference between two strings in Python

我有一個字符串列表:

['oXoXXoo', 'oXXoooo', 'oooXooo']

這些是一個謎題的動作,其中一個釘子跳過相鄰的釘子。 列表中的第一項是開始狀態,最后一項是已解決的棋盤。

我正在嘗試以以下格式顯示解決棋盤所需的動作:

[ (4, L), (1, R) ]

其中索引 [4] 處的 peg 向左跳轉以進入第二個棋盤狀態,索引 [1] 處的 peg 向右跳轉以解決難題。 基本上我需要找到每個列表項之間的具體差異並根據它們返回一個元組列表。 我目前的偽代碼想法是:

find where oXX became Xoo
    path.add((index of the o+2, L))
find where XXo became ooX
    path.add((index of the X+2, R))

我也考慮過將字符串變成一個列表並使用 .difference 做一些事情,但我不確定從那里去哪里。 任何關於如何在 python 中比較字符串或列表的建議都歡迎!

如果我正確理解您的問題,這樣的事情可能會起作用:

l = ['oXoXXoo', 'oXXoooo', 'oooXooo']
path = []
for i in range(len(l) - 1):
    before = l[i]
    after = l[i+1]
    string_length = len(before)
    for j in range(string_length):
        if before[j] != after[j] and before[j] == "o":
            # It means that the peg went LEFT! (it jumped from j+2 to j)
            path.append((j+2,"L"))
            break
        if before[j] != after[j] and before[j] == "X":
            # It means that the peg went RIGHT! (it jumped from j to j+2)
            path.append((j,"R"))
            break
        
for p in path:
    print(p)

輸出:

(4,L)
(1,R)

檢查兩個連續字符串中不同的第一個元素就足夠了,然后我們都可以推斷掛鈎是向左還是向右以及原始掛鈎位置。

盡管它基於與 ИванКарамазов 下面的回答相同的觀察結果,但有一個相當簡單的實現。 只是為了給一些靈感(為了我自己優化東西的樂趣):

states = ['oXoXXoo', 'oXXoooo', 'oooXooo']
moves = []
for i, state1 in enumerate(states[:-1]):
    state2 = states[i+1]
    pos, char = next((i,a) for i, (a,b) in enumerate(zip(state1, state2)) if a != b)
    moves.append((pos, 'R') if char == 'X' else (pos + 2, 'L'))

# result
[(4, 'L'), (1, 'R')]

解釋

  • 只有兩個可能的選項 - LR
  • 每次移動只允許一個動作
  • 只有符號oX

這意味着你只需要得到

  1. 兩個狀態之間不同的第一個字符char的位置和
  2. 任一狀態下的charoX )的值。

(i,a) for i, (a,b) in enumerate(zip(state, state2)) if a != b)是一個生成器,它從兩個同步狀態生成元素加上當前索引 ( enumerate ) 如果字符不同。 next我們只迭代到第一個匹配,這使得它非常有效。

如果charo ,我們知道我們正在從oXXXoo (= L),在這種情況下,我們需要在右邊添加 2 個位置以獲得X在第一個狀態的原點。 如果 char 是X ,則移動是 R ,我們只返回pos

IIUC,您需要一個函數,它需要兩個字符串s1s2 ,並描述用於從s1s2的移動 - 或者換句話說

describe_move('XXoXXoo', 'oXXXXoo')應該返回(0, 'R')

您可以通過檢查('o', 'X')的位置並將移動識別為來自兩側的 2 個位置來編寫這樣的函數 -

def describe_move(s1, s2):
    move = list(zip(s1, s2))
    peg_final_index = move.index(('o', 'X'))
    peg_initial_index = (peg_final_index + 2) if move[peg_final_index + 2] == ('X', 'o') else (peg_final_index - 2)
    direction = 'L' if peg_initial_index > peg_final_index else 'R'
    return peg_initial_index, direction

s1 = 'oXoXXoo'
s2 = 'oXXoooo'

describe_move(s1, s2)
# (4, 'L')

describe_move(s2, 'oooXooo')
# (1, 'R')

describe_move('XXoXXoo', 'oXXXXoo')
# (0, 'R')

暫無
暫無

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

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