允许indexOf在Java中多次检查匹配

时间:2011-07-13 21:54:21

标签: java arrays string indexof

我目前正在为一个类创建一个项目来创建一个TextLine类,该类表示必须表示为字符数组的一行文本。我不允许通过间接或直接以任何方式使用字符串类来表示TextLine对象,但是,我可以使用它来处理参数。

对于其中一个方法,我应该接受一个字符串作为参数的参数,该参数也是TextLine对象的一个​​片段,然后返回此TextLine中片段第一次出现的索引位置,或-1,如果找不到片段。

现在,我正在尝试找出indexOf方法,但我的问题是我的方法只检查一次起点。因此,如果TextLine对象的字母第一次与片段的字母不匹配,但在对象中的其他位置存在另一个匹配,则该方法不检查该起始点。

例如,假设我输入penplay作为TextLine,然后我输入play作为片段。很明显,TextLine中出现了play,但是我的indexOf方法的作用是,它检查索引0处的penplay中的第一个p,然后继续查看以下字母是否与播放长度匹配,如果是没有,它返回-1。知道如何让算法继续寻找另一个起点吗?

这就是我的代码:

public int indexOf(String fragment){

char[] temp = fragment.toCharArray();

int j = 0;
for(int i = 0; i < someText.length; i++){
    while(someText[i] == temp[j]){

        for(j = 1; j < temp.length; j++){
            if(temp[j] != someText[i+j]){
                return -1;
            }
        }

        return i;

    }
}

return -1;

}

3 个答案:

答案 0 :(得分:4)

当你没有必要的时候,你就是第一个角色。基本上你需要说:

  • 对于每个潜在的首发角色......
    • 整个fragment是否匹配,从候选位置开始?

类似于:

// Only deal with *viable* starting points
for (int i = 0; i < someText.length - temp.length; i++) {
    boolean found = true;
    for (int j = 0; j < temp.length && found; j++) {
        if (temp[j] != someText[i + j]) {
            found = false;
        }
    }
    if (found) {
        return i;
    }
}
return -1;

这可以通过提取内循环来重构:

for (int i = 0; i < someText.length - temp.length; i++) {
    if (textMatches(temp, i)) {
        return i;
    }
}
return -1;

...
// TODO: Javadoc to explain parameters :)
private boolean textMatches(char[] chars, int startingIndex) {
    for (int i = 0; i < chars.length; i++) {
        if (chars[i] != someText[i + startingIndex]) {
            return false;
        }
    }
    return true;
}

答案 1 :(得分:1)

您设置它的方式似乎适合作为一种doesStringExistAtIndex(j, fragment)函数。因为如果第一个索引处不存在该字符串,则返回-1,您可以执行以下操作:

//assuming that "this" is the subject that you are searching in
public int indexOf(String fragment){
  for(int i=0; i<this.length; ++i){
    if(doesStringExistAtIndex(i, fragment))
      return i;
  }
  return -1;
}

答案 2 :(得分:0)

不确定这是否是你想要的,但我基本上写了一个indexOf方法。我做了一些测试,它似乎在我做的一些测试中工作得很好。当然,它看起来会有所不同,因为我想让测试变得更容易,但如果您决定使用它,它应该是30秒或更少的转换。

public int indexOf(String fragment, String source)
{
    char[] temp = fragment.toCharArray();
    char[] someText = source.toCharArray();

    outer : for(int i = 0; i <= someText.length - temp.length;i++) //stops looping because why loop after the fragment is longer than the source we have left when its impossible to find
    {
        if(someText[i] == temp[0]) //if the first characters are the same
        {
            int q = 0;
            while(q < temp.length) //loop through the fragment
            {
                if(someText[i+q] != temp[q]) //if the characters are not the same, stop, and go to the next character of the source. Don't return anything
                {
                    continue outer; //continues the loop labeled 'outer' (e.g. outer : for(...) )
                }
                q++; //increment index since they both match
            }
            return i; //fragment and some part of the source matched since it reached here. Return the index of the first character
        }
    }
    return -1; //reached here because nothing was found :( return -1
}

编辑0 添加了行注释