首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Rabin-Karp算法寻找最长回文子串

用Rabin-Karp算法寻找最长回文子串
EN

Stack Overflow用户
提问于 2018-06-14 08:22:52
回答 1查看 2.3K关注 0票数 2

来自https://algs4.cs.princeton.edu/53substring/

15.最长回文子字符串。给定字符串s,查找最长的子字符串,即回文(或Watson-crick回文)。 解决方案:可以用后缀树或Manacher算法在线性时间内求解。这里有一个简单的解决方案,通常在实际时间运行。首先,我们描述了如何在线性时间中找到所有长度为L的回文子串:使用Karp迭代地形成长度L的每个子字符串的散列(及其反向),并进行比较。因为你不知道L,所以重复重复你对L的猜测,直到你知道最优的长度在L和2L之间。然后使用二进制搜索来找到确切的长度。

我不明白的是最后一部分。

因为你不知道L,所以重复重复你对L的猜测,直到你知道最优的长度在L和2L之间。

我怎么知道“最佳”长度是多少?

P.S.:最长回文子串的问题以前有人问过,但似乎唯一有用的问题是this,它也不使用Rabin。

编辑:这是我根据收到的答案编写的代码。

代码语言:javascript
复制
public static String longestPalindrome(String key) {
    int r = 256;
    long q = longRandomPrime();
    boolean lastFound;
    boolean found;
    int l = 2;

    do {
        lastFound = indexOfPalindromeOfGivenLength(key, l, r, q) >= 0;
        l *= 2;
        found = indexOfPalindromeOfGivenLength(key, l, r, q) >= 0;
    } while (l < key.length() && !(lastFound && !found));

    int left = l / 2;
    int right = l;

    while (left <= right) {
        System.out.printf("Searching for palindromes with length between: %d and %d%n", left, right);

        int i = indexOfPalindromeOfGivenLength(key, left, r, q);
        lastFound = i >= 0;
        int j = indexOfPalindromeOfGivenLength(key, right, r, q);
        found = j >= 0;

        if (lastFound && found) return key.substring(j, j + right);

        int x = left + (right - left) / 2;
        if (!found) right = x;
        else left = x;
    }

    return null;
}

private static int indexOfPalindromeOfGivenLength(String key, int l, int r, long q) {
    System.out.printf("Searching for palindromes with length: %d%n", l);

    for (int i = 0; i + l <= key.length(); i++) {
        String s1 = key.substring(i, i + l);
        long h1 = hash(s1, r, q);
        long h2 = hash(new StringBuilder(s1).reverse().toString(), r, q);

        if (h1 == h2) {
            System.out.printf("Found palindrome: %s of length: %d%n", s1, s1.length());
            return i;
        }
    }
    System.out.printf("No palindromes of length %d exist%n", l);
    return -1;
}
EN

回答 1

Stack Overflow用户

发布于 2018-06-14 11:16:27

一旦到达长度为L (长度为L的回文子串,而没有长度为2L的回文子字符串)的位置,您就知道最佳长度在L2L之间。

二,找到它,你用二进制搜索。首先尝试L + ceil(L/2) (如果有这个长度的回文子字符串),对L + ceil(L/2)2L做同样的操作,如果没有这个长度的回文子字符串,则在[L, L + ceil(L/2))中搜索。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50852865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档