实现Java的indexOf方法(子串搜索)

时间:2016-04-11 20:06:57

标签: java string algorithm substring indexof

我只是第二学期的CS学生,无法使用任何众所周知的高效子串搜索算法。我需要使用以下方法签名实现indexOf方法:

int indexOf(String str, String pattern)返回第一个位置的索引,其中模式显示为str的子字符串。

这就是我的尝试:

首先,我使用签名indexOf(String str, char ch, int startIndex)创建了一个重载方法索引,该索引返回char的第一个位置的索引,否则返回-1。

 private int indexOf(String str, char ch, int startIndex) {
    for(int i = startIndex; i < str.length(); i++)
        if(str.charAt(i) == ch) return i;

    return -1;
}

现在我编写搜索子字符串(pattern)的方法。

private int indexOf(String str, String pattern) {
    int headIndex = indexOf(str, pattern.charAt(0), 0);
    int tailIndex = indexOf(str, pattern.charAt(pattern.length() - 1), 0);

    if(headIndex == -1 || tailIndex == -1) return -1; // no substring match

    while(true) {
        int j = 0;
        for(int i = headIndex; i <= tailIndex; i++)
            if(str.charAt(headIndex) != pattern.charAt(j++)) { //if substring does not match then compute a new head and tail Index
                headIndex = indexOf(str, pattern.charAt(0), headIndex);
                tailIndex = indexOf(str, pattern.charAt(pattern.length() - 1), tailIndex);
                j = 0;
                i = headIndex + 1;
                if(headIndex == -1 || tailIndex == -1) return -1;
                break;
            }

        if(headIndex >= 0) return headIndex;
    }
}

我相信我很接近,但indexOf("Hellolo", "lo")之类的电话会返回2而不是3.我试图弄清楚我的逻辑出错了,并需要帮助。

我不允许使用除长度之外的任何特殊字符串方法。

4 个答案:

答案 0 :(得分:1)

在您的代码中,您正在寻找单个字符的第一个索引而不是字符串。

int headIndex = indexOf(str, pattern.charAt(0), 0);

如果我们假设str = Hellolo"pattern = "lo",则上面的代码会查找l而不是lo

编辑:如果您想查找字符串"lo"的第一个出现,那么您必须将代码更改为

int headIndex = indexOf(str, pattern, 0);

答案 1 :(得分:0)

indexOf("Hellolo", "lo")返回2因为基于零的计数... 这里是doc

public int indexOf(int ch)
  

返回第一次出现的字符串中的索引   指定的字符。如果出现值为ch的字符   此String对象表示的字符序列,然后是索引   (以Unicode代码单位)返回第一个此类事件。对于   ch 的值,范围为0到0xFFFF(含)

答案 2 :(得分:0)

我只是以尽可能简单的方式编写代码。

package com.ggl.testing;

public class MyString {

    public static void main(String[] args) {
        MyString myString = new MyString();
        String string = "abcdefghij";
        String pattern = "defg";
        System.out.println(myString.indexOf(string, pattern));

        pattern = "ghij";
        System.out.println(myString.indexOf(string, pattern));

        pattern = "asdf";
        System.out.println(myString.indexOf(string, pattern));
    }

    public int indexOf(String string, String pattern) {
        int length = string.length() - pattern.length();
        for (int index = 0; index <= length; index++) {
            if (patternMatch(string, index, pattern)) {
                return index;
            }
        }

        return -1;
    }

    private boolean patternMatch(String string, int index, String pattern) {
        int i = index;
        for (int j = 0; j < pattern.length(); j++) {
            if (string.charAt(i) != pattern.charAt(j)) {
                return false;
            }
            i++;
        }

        return true;
    }

}

答案 3 :(得分:0)

int headIndex = indexOf(str, pattern.charAt(0));
int tailIndex = indexOf(str, pattern.charAt(pattern.length() - 1));

if(headIndex == -1 || tailIndex == -1) return -1; // no substring match

越野车 - &gt;考虑这种情况:

String str = "nevern";
String pattern = "vern";

我认为专注于头部char就足够了:

public class Search {


    static private int indexOf(String src, char ch, int startIndex) {
        for(int i = startIndex; i < src.length(); i++)
            if(src.charAt(i) == ch) return i;

        return -1;
    }

    static private int indexOf(String src, String pat) {
        int head_in_src = 0;

        while (-1 != (head_in_src = indexOf(src, pat.charAt(0), head_in_src))) {
            if (head_in_src + pat.length() > src.length() - head_in_src)
                return -1;
            boolean match = true;
            int offset = 0;
            for (; offset < pat.length(); offset++) {
                if (src.charAt(offset + head_in_src) != pat.charAt(offset)) {
                    match = false;
                    break;
                }
            }
            if (true == match)
                return head_in_src;
            head_in_src += offset;
        }
        return -1;
    }

    public static void main(String[] args) {
        String src = "ne-nevern-nevern";
        String pat = "ever";
        String pat1 = "ne";
        String pat2 = "vern";
        String pat3 = "everne";
        String pat4= "-ne-";
        String pat5= "ner";

        System.out.printf("src=%1$s, pat=%2$s, index=%3$d%n", src, pat, indexOf(src, pat));
        System.out.printf("src=%1$s, pat1=%2$s, index=%3$d%n", src, pat1, indexOf(src, pat1));
        System.out.printf("src=%1$s, pat2=%2$s, index=%3$d%n", src, pat2, indexOf(src, pat2));
        System.out.printf("src=%1$s, pat3=%2$s, index=%3$d%n", src, pat3, indexOf(src, pat3));
        System.out.printf("src=%1$s, pat4=%2$s, index=%3$d%n", src, pat4, indexOf(src, pat4));
        System.out.printf("src=%1$s, pat5=%2$s, index=%3$d%n", src, pat5, indexOf(src, pat5));
    }
}

输出:

src=ne-nevern-nevern, pat=ever, index=4
src=ne-nevern-nevern, pat1=ne, index=0
src=ne-nevern-nevern, pat2=vern, index=5
src=ne-nevern-nevern, pat3=everne, index=-1
src=ne-nevern-nevern, pat4=-ne-, index=-1
src=ne-nevern-nevern, pat5=ner, index=-1