【问题标题】:Am I oversimplifying the concept of " if a string is one edit away"?我是否过度简化了“如果一个字符串是一次编辑”的概念?
【发布时间】:2020-12-08 01:38:33
【问题描述】:

我一直在做大量的算法学习和实践,我遇到了一个问题(在这里总结)“给定两个字符串,如果字符串是一个编辑就返回 True(通过删除、插入, 或替换字符)。如果不是,则返回 False。”

我通过比较两个字符串并计算 string1 中的字母数量来解决这个问题,而不是 string2 中的字母数量。如果缺少一个以上的字母,则返回 False。

这是我的 Python 代码:

def oneAway(string1, string2):
    string1 = string1.lower()
    string2 = string2.lower()
# counts the number of edits required
    counter = 0
    for i in string1:
        if i not in string2:
            counter += 1
    if counter > 1:
       return False
    else:
        return True

我想听听其他人解决这个问题的方法,如果我过度简化了这个概念,请指出。

【问题讨论】:

  • 如果你打电话给oneAway('abcde', 'edcba')会发生什么?这些肯定不相同,并且有很多编辑分开?
  • 考虑两个字符串具有相同字符但排列不同的情况。在字符串超过 1 次编辑的情况下,您的算法将返回 True。
  • 对你们俩:这是真的。当我最初想到它时,我没有意识到这一点。
  • 作为提示,问题是“字符串是否可以编辑?”意味着该方法应该是“首先找到编辑距离,然后将该数字与 1 进行比较”(如果是,问题将只是“编辑距离是多少?”)。您可以逐个字符比较字符串,一旦发现差异,您可以进行一次编辑(提示:检查字符串长度),然后确保其余字符串相同,即需要 0 次额外编辑.
  • @thatotherguy 我喜欢这种方法。谢谢你的回复

标签: python string algorithm edit


【解决方案1】:

为什么在两个字符串上都调用.lower()?根据问题,oneAway('abc', 'ABC') 应该是 False。

以其他 cmets 为基础,如何:

def oneAway(s1, s2):
    i, j = 0, 0
    mistake_occurred = False
    
   
    while i < len(s1) and j < len(s2):
        if s1[i] != s2[j]:
            if mistake_occurred:
                return False
            mistake_occurred = True 
        i += 1
        j += 1
             
    if mistake_occurred and (i != len(s1) or j != len(s2)):
        return False
    if i < len(s1) - 1 or j < len(s2) - 1:
        return False
    
    return True

【讨论】:

  • oneAway('A','BA') 返回 False
【解决方案2】:

您必须专门检查每个编辑操作:

def isOneEdit(A,B):
    # replacing one char
    if len(A) == len(B) and sum(a!=b for a,b in zip(A,B)) == 1:
        return True
    # inserting one char in A to get B
    if len(A) == len(B)-1 and any(A==B[:i]+B[i+1:] for i in range(len(B))):
        return True
    # removing one char (like inserting one in B to get A)
    if len(A) == len(B)+1: 
        return isOneEdit(B,A)
    return False

print(isOneEdit("abc","abd"))   # True - replace c with d

print(isOneEdit("abd","abcd"))  # True - insert c 

print(isOneEdit("abcd","abd"))  # True - delete c

print(isOneEdit("abcde","abd")) # False

或者,您可以将两个字符串的公共前缀和后缀的大小与最长的长度进行比较:

def isOneEdit(A,B):
    if abs(len(A)-len(B))>1: return False
    commonPrefix = next((i for i,(a,b) in enumerate(zip(A,B)) if a!=b),len(A))
    commonSuffix = next((i for i,(a,b) in enumerate(zip(reversed(A),reversed(B))) if a!=b),len(B))
    editSize     = max(len(A),len(B)) - (commonPrefix+commonSuffix) 
    return editSize <= 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多