重复但重叠的字符串的算法

时间:2012-07-15 07:34:57

标签: java algorithm

我需要编写一个方法,我给了一个字符串s,我需要将包含s的最短字符串作为连续的子字符串返回两次。

但是,s的两次出现可能会重叠。例如,

  • aba返回ababa
  • xxxxx返回xxxxxx
  • abracadabra返回abracadabracadabra

到目前为止,我的代码是:

import java.util.Scanner;

public class TwiceString {

    public static String getShortest(String s) {
        int index = -1, i, j = s.length() - 1;
        char[] arr = s.toCharArray();
        String res = s;

        for (i = 0; i < j; i++, j--) {
            if (arr[i] == arr[j]) {
                index = i;
            } else {
                break;
            }
        }

        if (index != -1) {
            for (i = index + 1; i <= j; i++) {
                String tmp = new String(arr, i, i);
                res = res + tmp;
            }
        } else {
            res = res + res;
        }

        return res;
    }

    public static void main(String args[]) {
        Scanner inp = new Scanner(System.in);
        System.out.println("Enter the string: ");
        String word = inp.next();

        System.out.println("The requires shortest string is " + getShortest(word));
    }
}

我知道我在算法级别而不是在编码级别上可能是错误的。我的算法应该是什么?

6 个答案:

答案 0 :(得分:9)

使用suffix tree。特别是,在为s构建树之后,转到表示整个字符串的叶子并向上走,直到看到另一个字符串结束标记。这将是最长后缀的叶子,也是s的前缀。

答案 1 :(得分:3)

正如@phs已经说过的,问题的一部分可以转换为“找到s的最长前缀,也是s的后缀,没有树的解决方案可能是这样的:< / p>

public static String getShortest(String s) {
    int i = s.length();
    while(i > 0 && !s.endsWith(s.substring(0, --i))) 
        ;
    return s + s.substring(i);
}

答案 2 :(得分:2)

一旦找到了你的索引,即使它是-1,你只需要将原始字符串附加到index + 1(因为索引是最后一个匹配的字符索引)的子字符串到结尾字符串。在String中有一个方法来获取这个子字符串。

答案 3 :(得分:2)

我认为你应该看看Knuth-Morris-Pratt算法,它使用的部分匹配表几乎就是你所需要的(并且它是一种非常好的算法;)

答案 4 :(得分:0)

如果您的输入字符串s"abcde",则可以轻松构建如下所示的正则表达式(注意缺少最后一个字符"e"!):

a(b(c(d)?)?)?$

并在字符串s上运行它。这将返回尾随重复子字符串的起始位置。然后,您只需附加缺失的部分(即s的最后N-M个字符,其中N是s的长度,M是匹配的长度),例如

aba
  ^ match "a"; append the missing "ba"
xxxxxx
 ^ match "xxxxx"; append the missing "x"
abracadabra
       ^ match "abra"; append the missing "cadabra"
nooverlap
--> no match; append "nooverlap"

答案 5 :(得分:-1)

根据我的理解,你想要这样做:

input: dog
output: dogdog
--------------
input: racecar
output: racecaracecar

所以我会这样做:

 public String change(String input)
{
    StringBuilder outputBuilder = new StringBuilder(input);

    int patternLocation = input.length();
    for(int x = 1;x < input.length();x++)
    {
        StringBuilder check = new StringBuilder(input);

        for(int y = 0; y < x;y++)
            check.deleteCharAt(check.length() - 1);

        if(input.endsWith(check.toString()))
        {
            patternLocation = x;
            break;
        }
    }

    outputBuilder.delete(0,  input.length() - patternLocation);

    return outputBuilder.toString();
}

希望这有帮助!