最长回文子字符串算法

回文字符串

递归实现

def is_palindrome(s):
    if len(s) <= 1:
        return True
    else:
        return s[0] == s[-1] and is_palindrome(s[1:-1])

(众所周知,写递归的函数,需要 1 个基本情况,作为终止。还需要 1 个递归情况。

关于回文字符串的判断,基本情况是,为 1 个字符或空字符 '' ,即 len(s) <= 1 的情况。

对于递归的情况,可以这样判断:先判断首尾的字符是否相同,即 s[0] == s[-1] ,然后判断除去首尾字符以外的字符,即 is_palindrome(s[1:-1]) 。)

参考文献:
1. 10. 练习:回文 - 《计算机科学导论》学习笔记(22) - 课程 22: 如何拥有无穷力量;
2. 10. 练习:回文 - 课程 22: 如何拥有无穷力量 - 《计算机科学导论》 - 优达学城。

非递归实现

(回文字符串的非递归实现)

def iter_palindrome(s):
    for i in range(0, len(s) / 2):
        if s[i] != s[-(i+1)]:
            return False
    return True

(请注意 for 循环里面的 if 语句的判断, s[i] != s[-(i+1)] 比较的是从外往内遍历、首尾字符是否相等,如果不相等则立即返回 False 。如果遍历到了中间,仍然没有返回 False ,这时会退出循环,即整个字符串就是回文字符串。

这里,也隐含了对于空字符串和单个字符的判断,如果是这两种情况,不会进入循环,会直接返回 True 。)

参考文献:
1. 11. 递归 Vs 迭代 - 《计算机科学导论》学习笔记(22) - 课程 22: 如何拥有无穷力量;
2. 11. 递归 Vs 迭代 - 课程 22: 如何拥有无穷力量 - 《计算机科学导论》 - 优达学城。


回文子字符串

我的代码:

def h2(text):
        text = text.lower()
        for i in range(len(text)):
                for j in range(i+1, len(text)-i-1):
                        if text[i:j] != text[i:j:-1]:
                                continue
                        else:
                                return (i, j)
print h2('racecar')
print h2('Racecar')
print h2('Racecarr')
print h2('Race carr')
print h2('something rac e car going')
print h2('xxxxx')
print h2('Mad am I ma dam.')

我的代码,基于这样的想法:检测1个长字符串中,从左到右的每1个子字符串,是否为回文字符串。例如,对于’racecar’,检测r、ra、rac、race……,第2轮检测a、ac、ace、acec等等,直至检测完所有可能的子字符串。

但是我的代码,测试不通过。

Peter的原始代码经我简单调整后:

def longest_subpalindrome_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)

Peter的原始代码:

def longest_subpalindrome_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)

def test():
    L = longest_subpalindrome_slice
    assert L('racecar') == L('Racecar') == L('RacecarX') == (0, 7)

参考文献:
1. https://blog.csdn.net/qq_33528613/article/details/79431135。

你可能感兴趣的:(算法)