Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
Java 用Rabin-Karp算法寻找最长回文子串_Java_String_Algorithm_Data Structures_Rabin Karp - Fatal编程技术网

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

Java 用Rabin-Karp算法寻找最长回文子串,java,string,algorithm,data-structures,rabin-karp,Java,String,Algorithm,Data Structures,Rabin Karp,从 15。最长回文子串。给定一个字符串s,查找最长的 是回文(或Watson-crick回文)的子字符串 解决方案:可以使用后缀树或 马纳彻算法。这里有一个简单的解决方案,通常在 线性时间。首先,我们描述如何找到所有回文 线性时间中长度正好为L的子字符串:使用Karp Rabin 迭代形成长度为L的每个子字符串的哈希(及其 相反),并进行比较。既然你不认识我,就不断地加倍努力 猜测L,直到你知道最佳长度在L和2L之间。然后 使用二进制搜索查找确切的长度 我不明白的是最后一部分 既然你不认识我,你

15。最长回文子串。给定一个字符串s,查找最长的 是回文(或Watson-crick回文)的子字符串

解决方案:可以使用后缀树或 马纳彻算法。这里有一个简单的解决方案,通常在 线性时间。首先,我们描述如何找到所有回文 线性时间中长度正好为L的子字符串:使用Karp Rabin 迭代形成长度为L的每个子字符串的哈希(及其 相反),并进行比较。既然你不认识我,就不断地加倍努力 猜测L,直到你知道最佳长度在L和2L之间。然后 使用二进制搜索查找确切的长度

我不明白的是最后一部分

既然你不认识我,你就不断地加倍猜测我直到你 知道最佳长度在L和2L之间

我如何知道什么是“最佳”长度

旁白:最长回文子串的问题以前有人问过,但唯一有用的是,它也没有使用拉宾·卡普

编辑: 这是我根据收到的答案得出的代码

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;
}
public静态字符串longestPalindrome(字符串键){
int r=256;
长q=长随机素数();
发现布尔值;
布尔发现;
int l=2;
做{
lastFound=IndexOfAlindromeofGivenLength(键,l,r,q)>=0;
l*=2;
found=IndexOfAlindromeofGivenLength(键,l,r,q)>=0;
}而(l=0;
if(lastFound&&found)返回key.substring(j,j+right);
int x=左+(右-左)/2;
如果(!found)right=x;
左=x;
}
返回null;
}
私有静态int IndexOfAlindromeofGivenLength(字符串键,int l,int r,long q){
System.out.printf(“搜索长度为:%d%n”,l)的回文);

对于(int i=0;i+l,当你到达
l
时,你就知道最佳长度在
l
2L
之间


两个使用二进制搜索找到它。首先尝试
L+ceil(L/2)
如果有此长度的回文子串,则对
L+ceil(L/2)
2L
执行相同的操作,同样,如果没有此长度的回文子串,则在
[L,L+ceil(L/2)]中搜索

您搜索长度为L的回文子串,每次都加倍L,直到搜索失败。然后您知道真正的答案在失败长度和上次成功长度之间。您可以使用二进制搜索来找到它。@n.m.请参阅下面的注释或上面的代码。终止条件有意义吗?请参阅我的编辑。您可以吗我没有提到二进制搜索的终止条件,但经过一番思考后,我想到当两个边界都返回回文时,搜索应该终止。例如,使用字符串
Forgekskeefor
,存在长度
8
的回文(
eeksskee
),以及长度
10
geekskeg
)。搜索终止并返回
geekskeg
作为最长回文。