我正在尝试解决这个String manipulation问题,我需要找到给定字符串的最小句点。
如果字符串可以通过连接另一个长度为k的字符串的一个或多个重复来形成,则称该字符串具有句点k。
例如,字符串“abcabcabcabc”具有句点3,因为它是由字符串“abc”的4次重复形成的。它还有6期(两次重复的“abcabc”)和12次(一次重复的“abcabcabcabc”)。这是我的代码:
public static int getPeriod(String str){
int len=str.length();
boolean flag=false;
int i;
for (i=0;i<len;i++){
String s=str.substring(0,i);
String tmp=str;
while(tmp.length()>0){
if(tmp.startsWith(s)){
tmp=tmp.substring(0,i);
flag=true;
}
else {
flag=false;
continue;
}
}
if (flag==true)
break;
}
return i;
}
我通过循环原始字符串形成一个字符串s
,一次一个字符。之后,我正在检查原始字符串是否可以通过连接字符串s
任意次数而完全耗尽。
错误:
该方法始终返回0.
为什么会这样?
编辑:我的算法
让我们考虑输入字符串HoHoHo
First step: s=H
tmp= HoHoHo
tmp= oHoHo (after substringing tmp)
'o' isn't the same as s, so we increase i
Second step:s=Ho
tmp= HoHoHo
tmp= HoHo (after substringing tmp)
tmp= Ho (after substringing tmp)
tmp= "" (after substringing tmp)
Return the value of i, that is 2.
答案 0 :(得分:3)
while循环中的代码不正确,在第一次使用i=0
调用for循环时调用它,因此对tmp
变量的第一次赋值将其设置为空字符串,循环退出,你得到0.标志分配和continue
中的else
也不正确。
试试这个:
public static int getPeriod(String str) {
int len = str.length();
int i;
for (i = 1; i <= len/2; i++) {
String period = str.substring(0, i);
String tmp = str;
boolean flag = true;
while (flag && tmp.length() > 0) {
if (tmp.startsWith(period)) {
tmp = tmp.substring(i);
} else {
flag = false;
}
}
if (flag == true) {
return i;
}
}
return 0;
}
请注意,for
循环从1
开始并转到len/2
,因为您不想检查零长度期,并且不能有超过{的{ {1}}。
答案 1 :(得分:2)
在第一次循环迭代中,i == 0,因此s是“”(空字符串),并且在while
循环的第一次迭代之后tmp也是“”,因此tmp
也变为“”并退出所有循环。
答案 2 :(得分:1)
从i = 0开始将始终返回true,因为substring(0,0)将返回“”字符串并且tmp.startsWith(“”)始终为true。
首先你应该从1开始我,你也应该用continue
替换break
,因为continue
会继续你的while loop
,但你想做的是{{ 1}} continue
而不是while循环
以下是您的代码的一个版本:
for loop
答案 3 :(得分:0)
我知道这是一个老问题。使用Knuth的Prefix函数可以在线性时间内解决该问题。
public static int prefixFunction(final String needle)
{
//This code does not include input validation. Validate the input and return appropriate error message
int[] pf = new int[needle.length()];
for (int i = 1; i < needle.length(); i++)
{
int j = pf[i - 1];
while (j > 0 && needle.charAt(i) != needle.charAt(j)) j--;
if (needle.charAt(i) == needle.charAt(j)) ++j;
pf[i] = j;
}
int n = needle.length(), maxValue = pf[n - 1];
if(maxValue == 0 || n%(n-maxValue) != 0) return -1; //Not periodic
return needle.length() - maxValue;
}