我需要编写一个方法,我给了一个字符串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));
}
}
我知道我在算法级别而不是在编码级别上可能是错误的。我的算法应该是什么?
答案 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();
}
希望这有帮助!