【问题标题】:find couple of words which if deleting one letter will print the couple of words找到几个单词,如果删除一个字母将打印这两个单词
【发布时间】:2019-09-15 07:15:36
【问题描述】:

当给定一个字符串时,我需要找到一个字母不同的相似词。 "no" 和 "noc" 是一个字母不同的相似词,不使用库或短函数

例如: 如果我有字符串“car ucar nor or caar” 将打印: 车---优车 也不——或 汽车---汽车

我有这个代码: 我需要更改什么才能使代码正常工作? 我也不知道如何定义从 0 索引中的下一个单词开始的 j。 感谢您的帮助!

def Difference(s):
    list=s.split(" ")
    i=0
    countDigit=0
    for word1 in range(len(list)):
      for word2 in range(len(list)):
        if word1[i]==word1[j]:
            i+=1
            j+=1
            continue
    elif word1[i]!=word[j]:
             countDigit+=1
             if countDigit==1:
                 print(word1,"--- ",word2)
    else:
            break


    s="car ucar nor or caar"
    Difference(s)

【问题讨论】:

  • 这段代码有什么问题?
  • 请注意,您的倒数第二行中有双双引号;应该是“car ucar nor or caar”,而不是“”car ucar nor or caar””
  • @user3385217 你不是很清楚
  • 您需要在此处提供更多详细信息。我会建议一个规则列表和更多示例
  • @urban 现在更清楚了吗?

标签: python python-3.x algorithm python-2.7 list


【解决方案1】:

您可以使用这个function 来检查两个字符串是否是一次编辑。

为每对字符串调用此函数,如果返回TRUE,则打印这对字符串,否则将下一对字符串传递给此函数。

你将不得不在 Python 中转换这个算法,这将是一件容易的事!

【讨论】:

    【解决方案2】:

    如果我做对了,以下是一个好的开始:

    def letter_remove(from_str, target_str):
        """
        For each letter of from_str - remove it and check if it matches target_str
        """
        for i in range(len(from_str)):
            new_word = from_str[:i] + from_str[i+1:]
            if new_word == target_str:
                print(target_str,"--- ",from_str)
    
    def difference(s):
        list=s.split(" ")
        for word1 in list:
            for word2 in list:
                if word1==word2:
                    continue
    
                letter_remove(word2, word1)
                letter_remove(word1, word2)
    
    
    s="car ucar nor or caar"
    difference(s)
    

    这会给你:

    $ python2 ~/tmp/test.py
    ('car', '--- ', 'ucar')
    ('car', '--- ', 'caar')
    ('car', '--- ', 'caar')
    ('car', '--- ', 'ucar')
    ('or', '--- ', 'nor')
    ('or', '--- ', 'nor')
    ('car', '--- ', 'caar')
    ('car', '--- ', 'caar')
    

    观察:

    • 我们需要将 word1 与 word2 进行比较,反之亦然,因为从 word1 中删除一个字母可能会导致 word2
    • 结果需要去重

    更好的(也许)版本

    • 我们可以使用集合来保证集合中的元素是唯一的
    • 我们将集合中的每个组合添加为元组,而不是打印
    • 我们退回所有套装并在最后打印出来

    def letter_remove(from_str, target_str):
        """
        For each letter of from_str - remove it and check if it matches target_str
    
        Returns:
            A set of unique combinations found
        """
        results = set()
        for i in range(len(from_str)):
            new_word = from_str[:i] + from_str[i+1:]
            if new_word == target_str:
                # Sort words
                a, b = target_str, from_str
                results.add((target_str, from_str))
    
        return results
    
    def difference_set(s):
        list=s.split(" ")
        all_results = set()
        for word1 in list:
            for word2 in list:
                if word1==word2:
                    continue
    
                all_results.update(letter_remove(word2, word1))
                all_results.update(letter_remove(word1, word2))
    
        return all_results
    
    # This returns a set (unique elements) of the found differences
    s="car ucar nor or caar"
    sets = difference_set(s)
    for s in sets:
        print(s)
    

    上面的输出是

    $ python2 ~/tmp/test.py
    ('or', 'nor')
    ('car', 'caar')
    ('car', 'ucar')
    

    观察:

    • 上述算法效率非常低,因为它会为所有可能的字母删除创建太多字符串,我不建议将它用于很长的输入。更智能的算法可以比较单词中的每个字母并允许跳过一个不匹配的索引

    绝对更好的方法

    内嵌评论

    def letter_remove2(from_str, target_str):
        """
        For each letter of from_str - remove it and check if it matches target_str
    
        Returns:
            True: if the two strings can be matched by removing a character from one
        """
        skipped_a_letter = False
        i = 0
        j = 0
    
        # if they differ by more than a letter, then we do not accept them
        if abs(len(from_str) - len(target_str)) > 1:
            return False
    
        # Loop target's letters
        while i < len(target_str):
            if target_str[i] == from_str[j]:
                j += 1
                i += 1
                continue
    
            # If we have not already skipped a letter from from_str, skip this one
            # by increasing j but not i!
            if not skipped_a_letter:
                j += 1
    
                # Ensure we have not exceeded the length of from_str
                if len(from_str) <= j:
                    return False
    
                skipped_a_letter = True
                continue
    
            # If we reach here, it means that character do not match and we have
            # already attempted to skip a letter - no match after all
            return False
    
        # If we successfully loop, it means that we can match by removing a letter
        return True
    
    def difference_set(s):
        list=s.split(" ")
        all_results = set()
        for word1 in list:
            for word2 in list:
                if word1==word2:
                    continue
    
                if letter_remove2(word2, word1):
                    # Keep the target word first in the set since it will always
                    # be the shorter one
                    all_results.add((word1, word2))
    
                if letter_remove2(word1, word2):
                    all_results.add((word2, word1))
    
        return all_results
    

    输出:

    ('or', 'nor')
    ('car', 'caar')
    ('car', 'ucar')
    

    【讨论】:

    • 注意:这可以进一步优化以减少循环的数量......但我把这个留给你
    【解决方案3】:

    difflib 库可以为您提供帮助。 下面的代码将打印列表中所有相差一个字符的元素。 Diffib 提供了一种找到差异的有效方法。

    通过对列表进行嵌套迭代,您可以针对每个其他项目测试每个项目。

    列表推导将所有差异添加到列表中,然后计算差异 - 如果只有一个,则满足条件并打印字符串。

    
    def Differences(s):
        sl = s.split(" ")
        for t in sl: 
            for u in sl: 
                difflist = [diff for diff in difflib.ndiff(t,u) if diff[0] != ' '] 
                if len(difflist) == 1: 
                    print ("{}---{}".format(t,u)) 
    
    s = 'car ucar nor or caar'
    Differences(s)
    

    这将给出以下输出:

    car---ucar
    car---caar
    ucar---car
    nor---or
    or---nor
    caar---car
    

    【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多