Java中允许indexOf多次检查匹配

发布于 2024-11-23 16:55:01 字数 895 浏览 2 评论 0原文

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

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

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

例如,假设我输入 penplay 作为 TextLine,然后输入 play 作为片段。显然,TextLine 中出现了 play,但我的 indexOf 方法所做的是,它检查索引 0 处的 penplay 中的第一个 p,然后继续查看后面的字母是否与 play 的长度匹配,如果没有,它返回-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;

}

I'm currently working on a project for a class to create a TextLine class that represents the a line of text that must be represented as an array of characters. I am not allowed to represent the TextLine object by using the string class indirectly or directly in any way, however, I can use it to work with the parameters.

For one of the methods, I am supposed to take in a string as an argument of a parameter, which is also a fragment to the TextLine object, and then return the index position of the first occurrence of the fragment in this TextLine, or -1, if the fragment is not found.

Right now, I'm trying to figure out the indexOf method, but my problem is that my method only checks for a starting point once. So if the letter of the TextLine object doesn't match the letter of the fragment the first time, but there is another match somewhere else in the object, the method doesn't check for that starting point.

For example, lets say I enter penplay as the TextLine, then I enter play as the fragment. Clearly, there is an occurrence of play in the TextLine, but what my indexOf method does, is that it checks the first p from penplay at index 0, then continues to see if the following letters match for the length of play, and if it doesn't, it returns -1. Any idea how I could allow the algorithm to keep searching for another starting point?

This is what I have for my code:

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;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

十年不长 2024-11-30 16:55:01

当没有必要时,您会对第一个字符进行特殊处理。基本上你需要说:

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

所以类似:

// 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;
}

You're special-casing the first character, when there's no need to. Basically you need to say:

  • For each potential starting character...
    • Does the whole of fragment match, starting at that candidate position?

So something like:

// 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;

This can be refactored by extracting the inner loop:

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;
}
贱贱哒 2024-11-30 16:55:01

您设置它的方式似乎适合作为一种 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;
}

The way you have it set up seems suitable as a kind of doesStringExistAtIndex(j, fragment) function. Since that returns -1 if the string doesn't exist at the first index, you could do something like this:

//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;
}
风吹过旳痕迹 2024-11-30 16:55:01

不确定这是否是您想要的,但我基本上编写了一个 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
}

EDIT 0 添加了行注释

Not sure if this is what you wanted, but I basically wrote up an indexOf method. I did some testing and it seemed to work just fine in some tests I did. Of course, its going to look different because I wanted to make testing easier, but it should be 30 seconds or less of converting if you decide to use it.

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
}

EDIT 0 Added line comments

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文