最长回文子字符串算法

回文字符串

递归实现

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个可能的 Java 程序实现。该程序采用了中心扩展算法,时间复杂度为 O(n^2)。 ```java import java.util.Scanner; public class LongestPalindrome { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); String longestPalindrome = longestPalindrome(s); System.out.println(longestPalindrome); } public static String longestPalindrome(String s) { if (s == null || s.length() < 1) { return ""; } int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > end - start) { start = i - (len - 1) / 2; end = i + len / 2; } } return s.substring(start, end + 1); } private static int expandAroundCenter(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { left--; right++; } return right - left - 1; } } ``` 该程序先读入字符串 `s`,然后调用 `longestPalindrome` 方法,返回最长回文字符串。该方法首先判断 `s` 是否为空或长度小于 1,如果是,则返回空字符串。 接着,用两个指针分别从字符串的左右两端开始向中间扩展,检查以当前字符为中心的奇数长度回文和以当前字符和下一个字符为中心的偶数长度回文。用 `Math.max` 方法比较两种回文的长度,如果当前回文长度大于之前找到的最长回文长度,更新起始和结束位置。 最后,返回起始和结束位置之间的字符串,即最长回文字符串

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值