Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找最接近字符串的回文_Python_Algorithm_Palindrome - Fatal编程技术网

Python 查找最接近字符串的回文

Python 查找最接近字符串的回文,python,algorithm,palindrome,Python,Algorithm,Palindrome,我正试图编写一个python程序来查找与单词最接近的回文。我可以向字符串的任何部分添加字母,从字符串的任何部分删除字母,或更改字符串任何部分的字母。我一直在考虑使用levenshtein距离来找出文章中两个单词之间所需的最小编辑次数。但我不知道如何通过编程找到需要最少编辑次数的回文。我试图实现的目标的一些示例: palindrome('hello') = 'ollo' #you can remove the h and then turn the e into an o, giving a pa

我正试图编写一个python程序来查找与单词最接近的回文。我可以向字符串的任何部分添加字母,从字符串的任何部分删除字母,或更改字符串任何部分的字母。我一直在考虑使用levenshtein距离来找出文章中两个单词之间所需的最小编辑次数。但我不知道如何通过编程找到需要最少编辑次数的回文。我试图实现的目标的一些示例:

palindrome('hello') = 'ollo'
#you can remove the h and then turn the e into an o, giving a palindrome in 2 steps
levenshtein('hello',palindrome('hello')) = 2

palindrome('test') = 'tet'
#you can remove the s to get a palindrome
levenshtein('test',palindrome('test')) = 1

palindrome('tart') = 'trart'
#adding an r or removing the r produces a palindrome, but both solutions only require 1 edit so either would be acceptable.
levenshtein('tart',palindrome('tart')) = 1

我能够使用链接文章中的levenshtein代码来查找两个字符串之间的距离。我需要帮助编写一个palindrome()函数,该函数接受一个字符串并返回与该字符串最接近的回文

这是我的DFS实现。它只搜索到字长为2的
距离,因为如果超过这个距离,它会变得很琐碎(除了一个字母外,删除所有字母,将每个字母更改为相同的)

它找到所有的回文到这个距离限制,并按距离排序

import time
word = "hello"
visited_cost = {}       # to keep track of non-palindromes we've considered
palindrome_cost = {}    # to store actual palindromes we've found


def find_palindrome(w, dist=0 ):
    # Don't go on forever
    if len(w) == 0 or len(w) > len(word) + 2 or dist > len(word) - 2:
        return []

    # Don't retry potential palindromes that we've tried before
    global visited_cost
    if w in visited_cost:
        if dist >= visited_cost[w]:
            return []
    visited_cost[w] = dist

    # check if we've found a palindrome
    if (reverse(w)) == w:
        if w in palindrome_cost:
            palindrome_cost[w] = min(palindrome_cost[w], dist)
        else:
            palindrome_cost[w] = dist
        return [w]

    palindromes = []
    if len(w) > 1:
        for x in drop_one(w):
            palindromes += find_palindrome(x, dist+1)
        for x in add_one(w):
            palindromes += find_palindrome(x, dist+1)
        for x in change_one(w):
            palindromes += find_palindrome(x, dist+1)
        return palindromes


# For a word w, gives all possible words obtained by dropping one letter
def drop_one(w):
    return [w[:i]+w[i+1:] for i in range(len(w))]


# For a word w, gives all possible words obtained by inserting a capital X
# at any position in the word. Of course "X" could be any letter
def add_one(w):
    return [w[:i]+"X"+ w[i:] for i in range(len(w))]


# For a word w, gives all possible words obtained by changing one letter 
# to another letter occurring in the word
def change_one(w):
    return [w[:i] +j +  w[i + 1:] for i in range(len(w)) for j in w]


def reverse(s):
    return "".join(reversed(s))

t0 = time.time()
results = set(find_palindrome(word))
s = sorted(results, key = lambda x: palindrome_cost[x])

for x in s:
    print x, palindrome_cost[x]
print "Found %i palindromes based on '%s' in %.3f seconds" %\
       (len(results), word, time.time() - t0)
输出:

ollo 2
olllo 2
elle 2
heleh 2
hllh 2
oeleo 2
hlllh 2
[...]
Found 46 palindromes based on 'hello' in 0.065 seconds

在最坏的情况下,您应该能够从字符串的任何一个字母子字符串构造回文。也许从这里开始,在原始字符串o中的字母之间迭代,将o分为两部分o1和o2,要么最小长度为两个字符。然后在两个片段之间进行序列比对,将插入或删除的惩罚(编辑距离)指定给这两个片段。将编辑距离和类型与子字符串o1和o2的长度进行比较,以确定如何构造回文。感谢您的帮助,这可能是重复的。我试图在while循环中实现此函数,该循环从命令行读入单词,并在未定义变量单词时出错。以t0=time.time()开头的最后几行必须在函数定义之后吗?