Python:搜索单词中的最长回文和单词/字符串中的回文

时间:2013-06-20 15:16:50

标签: python palindrome

所以这里是我写的一个代码,用于查找单词中的回文(检查单词中是否包含单词本身的回文) 条件:字符之间的空格被计算,不被忽略 例如:但是大号是回文,但从技术上讲,由于涉及空间而现在不是。这就是标准。

基于以上所述,以下代码通常应该有效。您可以尝试使用不同的测试来检查此代码是否存在任何错误。

def pal(text):
    """

    param text: given string or test
    return: returns index of longest palindrome and a list of detected palindromes stored in temp
    """
    lst = {}
    index = (0, 0)
    length = len(text)
    if length <= 1:
        return index
    word = text.lower()  # Trying to make the whole string lower case
    temp = str()
    for x, y in enumerate(word):
        # Try to enumerate over the word
        t = x
        for i in xrange(x):
            if i != t+1:
                string = word[i:t+1]
                if string == string[::-1]:
                    temp = text[i:t+1]
                    index = (i, t+1)
                    lst[temp] = index
    tat = lst.keys()
    longest = max(tat, key=len)
    #print longest
    return lst[longest], temp

这是一个已经不复存在的版本。我的意思是我试图从中间开始并通过从头开始迭代并通过检查它们是否是相等的字符来检查字符的每个较高和较低的索引来检测回文。如果他们是那么我正在检查它是否像一个常规的回文检查回文。 这就是我所做的

def pal(t):
    text = t.lower()
    lst = {}
    ptr = ''
    index = (0, 0)
    #mid = len(text)/2
    #print mid
    dec = 0
    inc = 0
    for mid, c in enumerate(text):
        dec = mid - 1
        inc = mid + 1
        while dec != 0 and inc != text.index(text[-1]):
            print 'dec {}, inc {},'.format(dec, inc)
            print 'text[dec:inc+1] {}'.format(text[dec:inc+1])
            if dec<0:
                dec = 0
            if inc > text.index(text[-1]):
                inc = text.index(text[-1])
            while text[dec] != text[inc]:
                flo = findlet(text[inc], text[:dec])
                fhi = findlet(text[dec], text[inc:])
                if len(flo) != 0 and len(fhi) != 0 and text[flo[-1]] == text[fhi[0]]:
                    dec = flo[-1]
                    inc = fhi[0]
                    print ' break if'
                    break
                elif len(flo) != 0 and text[flo[-1]] == text[inc]:
                    dec = flo[-1]
                    print ' break 1st elif'
                    break
                elif len(fhi) != 0 and text[fhi[0]] == text[inc]:
                    inc = fhi[0]
                    print ' break 2nd elif'
                    break
                else:
                    dec -= 1
                    inc += 1
                    print ' break else'
                    break
            s = text[dec:inc+1]
            print ' s {} '.format(s)
            if s == s[::-1]:
                index = (dec, inc+1)
                lst[s] = index
            if dec > 0:
                dec -= 1
            if inc < text.index(text[-1]):
                inc += 1
    if len(lst) != 0:
        val = lst.keys()
        longest = max(val, key = len)
        return lst[longest], longest, val
    else:
        return index

findlet()有趣:

def findlet(alpha, string):
    f = [i for i,j in enumerate(string) if j == alpha]
    return f

有时它有效:

pal('madem')
dec -1, inc 1,
text[dec:inc+1] 
 s m 
dec 1, inc 3,
text[dec:inc+1] ade
 break 1st elif
 s m 
dec 2, inc 4,
text[dec:inc+1] dem
 break 1st elif
 s m 
dec 3, inc 5,
text[dec:inc+1] em
 break 1st elif
 s m 
Out[6]: ((0, 1), 'm', ['m'])

pal('Avid diva.')
dec -1, inc 1,
text[dec:inc+1] 
 break 2nd if
 s avid div 
dec 1, inc 3,
text[dec:inc+1] vid
 break else
 s avid  
dec 2, inc 4,
text[dec:inc+1] id 
 break else
 s vid d 
dec 3, inc 5,
text[dec:inc+1] d d
 s d d 
dec 2, inc 6,
text[dec:inc+1] id di
 s id di 
dec 1, inc 7,
text[dec:inc+1] vid div
 s vid div 
dec 4, inc 6,
text[dec:inc+1]  di
 break 1st elif
 s id di 
dec 1, inc 7,
text[dec:inc+1] vid div
 s vid div 
dec 5, inc 7,
text[dec:inc+1] div
 break 1st elif
 s vid div 
dec 6, inc 8,
text[dec:inc+1] iva
 break 1st elif
 s avid diva 
dec 8, inc 10,
text[dec:inc+1] a.
 break else
 s va. 
dec 6, inc 10,
text[dec:inc+1] iva.
 break else
 s diva. 
dec 4, inc 10,
text[dec:inc+1]  diva.
 break else
 s d diva. 
dec 2, inc 10,
text[dec:inc+1] id diva.
 break else
 s vid diva. 
Out[9]: ((0, 9), 'avid diva', ['avid diva', 'd d', 'id di', 'vid div'])

根据我提出的标准/条件:

pal('A car, a man, a maraca.')
dec -1, inc 1,
text[dec:inc+1] 
 break else
 s  
dec -1, inc 3,
text[dec:inc+1] 
 s a ca 
dec 1, inc 3,
text[dec:inc+1]  ca
 break if
 s a ca 
dec 2, inc 4,
text[dec:inc+1] car
 break else
 s  car, 
dec 3, inc 5,
text[dec:inc+1] ar,
 break else
 s car,  
dec 1, inc 7,
text[dec:inc+1]  car, a
 break 1st elif
 s a car, a 
dec 4, inc 6,
text[dec:inc+1] r, 
 break 1st elif
 s  car,  
dec 5, inc 7,
text[dec:inc+1] , a
 break 1st elif
 s ar, a 
dec 2, inc 8,
text[dec:inc+1] car, a 
 break 1st elif
 s  car, a  
dec 6, inc 8,
text[dec:inc+1]  a 
 s  a  
dec 5, inc 9,
text[dec:inc+1] , a m
 break else
 s r, a ma 
dec 3, inc 11,
text[dec:inc+1] ar, a man
 break else
 s car, a man, 
dec 1, inc 13,
text[dec:inc+1]  car, a man, 
 s  car, a man,  
dec 7, inc 9,
text[dec:inc+1] a m
 break else
 s  a ma 
dec 5, inc 11,
text[dec:inc+1] , a man
 break else
 s r, a man, 
dec 3, inc 13,
text[dec:inc+1] ar, a man, 
 break if
 s   
dec 8, inc 10,
text[dec:inc+1]  ma
 break if
 s  
dec 6, inc 4,
text[dec:inc+1] 
 break 1st elif
 s r 
dec 3, inc 5,
text[dec:inc+1] ar,
 break else
 s car,  
dec 1, inc 7,
text[dec:inc+1]  car, a
 break 1st elif
 s a car, a 
dec 9, inc 11,
text[dec:inc+1] man
 break else
 s  man, 
dec 7, inc 13,
text[dec:inc+1] a man, 
 break if
 s  
dec 5, inc 2,
text[dec:inc+1] 
 break 1st elif
 s c 
dec 1, inc 3,
text[dec:inc+1]  ca
 break if
 s a ca 
dec 10, inc 12,
text[dec:inc+1] an,
 break 1st elif
 s , a man, 
dec 4, inc 13,
text[dec:inc+1] r, a man, 
 break 1st elif
 s  car, a man,  
dec 11, inc 13,
text[dec:inc+1] n, 
 break 1st elif
 s  man,  
dec 7, inc 14,
text[dec:inc+1] a man, a
 s a man, a 
dec 6, inc 15,
text[dec:inc+1]  a man, a 
 s  a man, a  
dec 5, inc 16,
text[dec:inc+1] , a man, a m
 break else
 s r, a man, a ma 
dec 3, inc 18,
text[dec:inc+1] ar, a man, a mar
 break else
 s car, a man, a mara 
dec 1, inc 20,
text[dec:inc+1]  car, a man, a marac
 break else
 s a car, a man, a maraca 
dec 12, inc 14,
text[dec:inc+1] , a
 break 1st elif
 s an, a 
dec 9, inc 15,
text[dec:inc+1] man, a 
 break if
 s  
dec 7, inc 2,
text[dec:inc+1] 
 break 1st elif
 s c 
dec 1, inc 3,
text[dec:inc+1]  ca
 break if
 s a ca 
dec 13, inc 15,
text[dec:inc+1]  a 
 s  a  
dec 12, inc 16,
text[dec:inc+1] , a m
 break 1st elif
 s man, a m 
dec 8, inc 17,
text[dec:inc+1]  man, a ma
 break 1st elif
 s a man, a ma 
dec 6, inc 18,
text[dec:inc+1]  a man, a mar
 break 1st elif
 s r, a man, a mar 
dec 3, inc 19,
text[dec:inc+1] ar, a man, a mara
 s ar, a man, a mara 
dec 2, inc 20,
text[dec:inc+1] car, a man, a marac
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 14, inc 16,
text[dec:inc+1] a m
 break 1st elif
 s man, a m 
dec 8, inc 17,
text[dec:inc+1]  man, a ma
 break 1st elif
 s a man, a ma 
dec 6, inc 18,
text[dec:inc+1]  a man, a mar
 break 1st elif
 s r, a man, a mar 
dec 3, inc 19,
text[dec:inc+1] ar, a man, a mara
 s ar, a man, a mara 
dec 2, inc 20,
text[dec:inc+1] car, a man, a marac
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 15, inc 17,
text[dec:inc+1]  ma
 break 1st elif
 s a ma 
dec 13, inc 18,
text[dec:inc+1]  a mar
 break 1st elif
 s r, a man, a mar 
dec 3, inc 19,
text[dec:inc+1] ar, a man, a mara
 s ar, a man, a mara 
dec 2, inc 20,
text[dec:inc+1] car, a man, a marac
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 16, inc 18,
text[dec:inc+1] mar
 break 1st elif
 s r, a man, a mar 
dec 3, inc 19,
text[dec:inc+1] ar, a man, a mara
 s ar, a man, a mara 
dec 2, inc 20,
text[dec:inc+1] car, a man, a marac
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 17, inc 19,
text[dec:inc+1] ara
 s ara 
dec 16, inc 20,
text[dec:inc+1] marac
 break 1st elif
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 18, inc 20,
text[dec:inc+1] rac
 break 1st elif
 s car, a man, a marac 
dec 1, inc 21,
text[dec:inc+1]  car, a man, a maraca
 break 1st elif
 s a car, a man, a maraca 
dec 19, inc 21,
text[dec:inc+1] aca
 s aca 
dec 21, inc 23,
text[dec:inc+1] a.
 break else
 s ca. 
dec 19, inc 23,
text[dec:inc+1] aca.
 break else
 s raca. 
dec 17, inc 23,
text[dec:inc+1] araca.
 break else
 s maraca. 
dec 15, inc 23,
text[dec:inc+1]  maraca.
 break else
 s a maraca. 
dec 13, inc 23,
text[dec:inc+1]  a maraca.
 break else
 s , a maraca. 
dec 11, inc 23,
text[dec:inc+1] n, a maraca.
 break else
 s an, a maraca. 
dec 9, inc 23,
text[dec:inc+1] man, a maraca.
 break else
 s  man, a maraca. 
dec 7, inc 23,
text[dec:inc+1] a man, a maraca.
 break else
 s  a man, a maraca. 
dec 5, inc 23,
text[dec:inc+1] , a man, a maraca.
 break else
 s r, a man, a maraca. 
dec 3, inc 23,
text[dec:inc+1] ar, a man, a maraca.
 break else
 s car, a man, a maraca. 
dec 1, inc 23,
text[dec:inc+1]  car, a man, a maraca.
 break else
 s a car, a man, a maraca. 
Out[8]: ((13, 16), ' a ', ['', ' a ', 'c', ' ', 'aca', 'ara', 'r'])

有时,它根本不起作用:

    pal('madam')
    dec -1, inc 1,
    text[dec:inc+1] 
     s m 
    dec 1, inc 3,
    text[dec:inc+1] ada
     break 1st elif
     s m 
    dec 2, inc 4,
    text[dec:inc+1] dam
     break 1st elif
     s m 
    dec 3, inc 5,
    text[dec:inc+1] am
     break 1st elif
     s m 
    Out[5]: ((0, 1), 'm', ['m'])

现在考虑女士是一个非常好的回文它应该有效,并且有许多情况我没有测试自己找出它没有检测到的其他合法的回文。

Q1:为什么有时候没有检测到?

Q2:我想优化我的第二个代码。有什么输入吗?

问题3:有什么比我的第一代码更有效的代码有哪些更好的方法呢?

17 个答案:

答案 0 :(得分:15)

你的解决方案对我来说似乎有点复杂。只需查看所有可能的子串并单独检查它们:

def palindromes(text):
    text = text.lower()
    results = []

    for i in range(len(text)):
        for j in range(0, i):
            chunk = text[j:i + 1]

            if chunk == chunk[::-1]:
                results.append(chunk)

    return text.index(max(results, key=len)), results

text.index()只会找到第一次出现最长的回文,所以如果你想要最后一回,请将其替换为text.rindex()

答案 1 :(得分:1)

以下函数返回给定字符串中包含的最长回文。它只是略有不同,因为它使用了this answer中建议的itertools。抽象组合生成是有价值的。它的时间复杂度显然仍然是立方的。它可以根据需要进行调整,以返回索引和/或回文列表。

import itertools

def longest_palindrome(s):
    lp, lp_len = '', 0
    for start, stop in itertools.combinations(range(len(s)+1), 2):
        ss = s[start:stop]  # substring
        if (len(ss) > lp_len) and (ss == ss[::-1]):
            lp, lp_len = ss, len(ss)
    return lp

答案 2 :(得分:1)

下面是我为同一问题编写的代码。它可能并没有真正优化过,但是却像魅力一样。对于初学者来说也很容易理解

CSSStyleSheet

答案 3 :(得分:0)

这可以通过一个窗口将它悬停在单词上来识别,由于我们只对找到最长的回文感兴趣,我们可以从单词本身的大小开始窗口大小,并通过检查所有可能性来逐渐减小它被窗口覆盖的块。当我们找到第一个回文块时,我们可以停止算法,该块也是给定单词中最长的回文块。

word = input("Word:").lower()
window_size = len(word)
found = False
while window_size > 1 and not found:
    start = 0
    while start <= len(word) - window_size and not found:
        window = word[start:start+window_size]
        if window[::-1] == window:
            print("Longest Palindrome :" , window)
            found = True
        start += 1
    window_size -= 1

答案 4 :(得分:0)

a = "xabbaabba"  # Provide any string

count=[]
for j in range(len(a)):
    for i in range(j,len(a)):
        if a[j:i+1] == a[i:j-1:-1]:      
            count.append(i+1-j)

print("Maximum size of Palindrome within String is :", max(count))

答案 5 :(得分:0)

如果你喜欢递归解决方案,我写了一个递归版本。它也很直观。

def palindrome(s):
  if len(s) <= 1:
    return s
  elif s[0] != s[-1]:
    beginning_palindrome = palindrome(s[:-1])
    ending_palindrome = palindrome(s[1:])
    if len(beginning_palindrome) >= len(ending_palindrome):
      return beginning_palindrome
    else:
      return ending_palindrome
  else:
    middle_palindrome = palindrome(s[1:-1])
    if len(middle_palindrome) == len(s[1:-1]):
        return s[0] + middle_palindrome + s[-1]
    else:
        return middle_palindrome

答案 6 :(得分:0)

这是一个可用于查找最长的回文子串的代码:

string = "sensmamstsihbalabhismadamsihbala"
string_shortener = ""
pres = 0
succ = 3
p_temp=0
s_temp=0
longest = ""
for i in range(len(string)-2):
    string_shortener = string[pres:succ]
    if(string_shortener==string_shortener[::-1]):
       p_temp = pres
       s_temp = succ
       for u in range(1000):
           p_temp-=1
           s_temp +=1
           string_shortener = string[p_temp:s_temp]
           if(string_shortener == string_shortener[::-1]):
                if len(string_shortener)>len(longest):
                    longest = string_shortener
            else:
                break
    pres+=1
    succ+=1
print(longest)

答案 7 :(得分:0)

inputStr = "madammmdd"
outStr = ""
uniqStr = "".join(set(inputStr))
flag = False
for key in uniqStr:
   val = inputStr.count(key)
   if val % 2 !=0:
      if not flag:
         outStr = outStr[:len(outStr)/2]+key+outStr[len(outStr)/2:]
         flag=True
      val-=1
   outStr=key*(val/2)+outStr+key*(val/2)
print outStr

答案 8 :(得分:0)

我在这个字符串参数&#39;中将函数名称设为maxpalindrome(s)。此函数将返回尽可能长的回文子字符串和子字符串的长度...

def maxpalindrome(s):
if len(s) == 1 or s == '':
    return str(len(s)) + "\n" + s
else:
    if s == s[::-1]:
        return str(len(s)) + "\n" + s
    else:
        for i in range(len(s)-1, 0, -1):
            for j in range(len(s)-i+1):
                temp = s[j:j+i]
                if temp == temp[::-1]:
                    return str(len(temp)) +"\n"+temp

答案 9 :(得分:0)

这是P. Norvig出色的在线课程Design of Computer Programs采取的另一种简洁明了的方法。它迭代字符串中的所有字符,并尝试将字符串“增长”为左右两种。

def longest_sub_palindrome_slice(text):
    "Return (i,j) such that text[i,j] is the longest palindrome in text"
    if text == '': return (0, 0)
    def length(slice): a,b = slice; return b-a
    candidates = [grow(text, start, end)
                 for start in range(len(text))
                 for end in (start, start + 1)]
    return max(candidates, key=length)

def grow(text, start, end):
    "Start with a 0- or 1- length palindrome; try to grow a bigger one"
    while (start > 0 and end < len(text)
           and text[start-1].upper() == text[end].upper()):
        start -= 1; end += 1
    return (start, end)

答案 10 :(得分:0)

value ="Madamaaamadamaaaacdefgv"
longestPalindrome =""
lenght =0;
for i in range(len(value)):
        for j in range(0, i):
            array = value[j:i + 1]
            if (array == array[::-1] and len(longestPalindrome) < len(array)):
                longestPalindrome =array
print(longestPalindrome)

答案 11 :(得分:0)

Python 3解决方案:(不是最快的)

class Solution:
    def longestPalindrome(self, s: str) -> str:

        if s == "":
            return ""
        if len(s) == 1: 
            return s
        if len(s) == 2:
            if s == s[::-1]:
                return s
            else:
                return s[0]


        results = []

        for i in range(len(s)):
            for j in range(0, i):
                chunk = s[j:i + 1]

                if chunk == chunk[::-1]:
                    results.append(chunk)
        if results:       
            return max(results, key=len)
        else:
            return s[0]

答案 12 :(得分:0)

s='stresseddesserts'
out1=[]
def substring(x):
    for i in range(len(x)):
        a=x[i:]
        b=x[:-i]
        out1.append(a)
        out1.append(b)
        
    return out1

for i in range(len(s)):
    substring(s[i:])    
final=set([item for item in out1 if len(item)>2])
final
palind={item:len(item) for item in final if item==item[::-1]}
print(palind)
sorted(palind.items(),reverse=True, key=lambda x: x[1])[0]

{'tresseddessert':14,'seddes':6,6,'esseddesse':10,'esse':4,4,'stresseddesserts':16,'resseddesser':12,'eded':4,4,'sededdess': 8}

('stresseddesserts',16)

答案 13 :(得分:-1)

我使用蛮力检查每个可能的子字符串是否为回文并更新找到的最长长度。 leetcode 上有更快的实现,包括动态编程

导入 java.util.List; 导入 java.util.ArrayList;

// 这种方法有效,但在 leet 代码上有更快的实现 // 可以在main方法中测试回文字符串,输出到终端

类解决方案{

public static void main (String [] args ) {
 
    Solution test = new Solution();
    
// can test strings for palindromes here
    System.out.println(     test.longestPalindrome( "abcdracecarabcd"   ));
    System.out.println(     test.longestPalindrome( "ottoracecar"   )); 
    System.out.println(     test.longestPalindrome( "a"   ));
    System.out.println(     test.longestPalindrome( "123otto123"   ));
    System.out.println(     test.longestPalindrome( "" ));
    System.out.println(     test.longestPalindrome( "" ));
    
}


public String longestPalindrome(String s) {
  
    List<Pair> pairs =  new ArrayList<Pair>();
    String currentHighest = "";
    
    
    // generate List of all possible subStrings (start character, and end character); there are n(n-1)/2 pair combinations.
    for (int i=0;i<=s.length();i++){
        int l = i;
        for (int j=i+1; j <= s.length(); j++) {
            int r = j;
            pairs.add(new Pair(l,r));
        }
    }
    
    
    // check if each possible substring is a palindrom and update the currentHighest found  
    for(Pair p: pairs) {
     //   System.out.println("start: " + p.L + " end: " + p.R);
        if (s.substring(p.L, p.R).equals( new StringBuffer(s.substring(p.L, p.R)).reverse().toString())) {
            if (s.substring(p.L, p.R).length() > currentHighest.length())  currentHighest = s.substring(p.L, p.R);
        }
    }
    
    return currentHighest;

}

// inner class to define a Pair
    class Pair {
        int L;
        int R;
        Pair (int l, int r){
             this.L = l;
             this.R = r;
          }
     }

}

答案 14 :(得分:-1)

def longestPalindrome(s):
        temp = ""
        for i in range(len(s)):
            for j in range(len(s)-1,i-1,-1):
                if s[i] == s[j]:
                    m = s[i:j+1]
                    if m == m[::-1]:
                        if len(temp) <= len(m):
                            temp = m
        return temp

答案 15 :(得分:-2)

我必须同意解决方案似乎很复杂,我认为最好的解决方案是,在子序列中找到最大的回文,(考虑中间的字符,例如'character'中最大的回文应该是carac)是:< / p>

def find_char_backwards(a, c):
for i in range(len(a) - 1, -1,-1):
    if a[i] == c:
        index=i
        return True, index

return False, 0

def longest_palindorme(a):
if len(a) < 2:
    return a
else:
    c=a[0]
    (exist_char,index) = find_char_backwards(a[1:],c)
    if exist_char:
        palindrome=[c] + longest_palindorme(a[1:index+1]) + [c]
    else:
        palindrome=[]
    rest_palidorme=longest_palindorme(a[1:])

if len(palindrome)>len(rest_palidorme):
    return palindrome
else:
    return rest_palidorme

如果a是数组,则此解决方案使用递归和动态编程

答案 16 :(得分:-3)

使用嵌套循环:

for x in range(len(body)):
    for y in range(len(body)):
    ...