6
\$\begingroup\$

I wrote this function to find the index of the first substring. I was wondering if you can help me find some flaws or possibly help increase performance?

Example:

str = "happy" substr = "app"

index = 1

My code:

public static int subStringIndex(String str, String substr) {
    int substrlen = substr.length();
    int strlen = str.length();
    int j = 0;
    int index = -1;

    if (substrlen < 1) {
        return index;
    }
    else {
        for (int i = 0; i < strlen; i++) {              // iterate through main string
            if (str.charAt(i) == substr.charAt(j)) {    // check substring
                index = i - j;                              // remember index
                j++;                                    // iterate
                if (j == substrlen) {                   // when to stop
                    return index;
                }
            }
            else {
                j = 0;
                index = -1;
            }
        }
    }
    return index;
}
\$\endgroup\$
1
  • \$\begingroup\$ You can simplify that a great deal by not reassigning index at each step \$\endgroup\$ Commented Jan 9, 2014 at 2:14

5 Answers 5

4
\$\begingroup\$

You can get away without the index variable as you're reassigning it at each step of your loop anyway.

public static int subStringIndex(String str, String substr) {
    int substrlen = substr.length();
    int strlen = str.length();
    int j = 0;

    if (substrlen >= 1) {
        for (int i = 0; i < strlen; i++) {              // iterate through main string
            if (str.charAt(i) == substr.charAt(j)) {    // check substring
                j++;                                    // iterate
                if (j == substrlen) {                   // when to stop
                    return i - substrlen; //found substring. As i is currently at the end of our substr so sub substrlen
                }
            }
            else {
                j = 0;
            }
        }
    }
    return -1;
}
\$\endgroup\$
0
7
\$\begingroup\$

Just checking that you intend to be , you can do:

System.out.println("happy".indexOf("app"));

You did know that, right?

Or, if you want to reformat the 'signature' to match yours, it is:

public static int subStringIndex(String str, String substr) {
    return str.indexOf(substr);
}

There are a number of helper methods on String which will help:

\$\endgroup\$
1
  • \$\begingroup\$ I know there is a built in function but I wanted to solve the problem without it but thanks! \$\endgroup\$ Commented Jan 9, 2014 at 3:30
1
\$\begingroup\$

Actually there is a bug. Consider str="aaS" and substr="aS". At first iteration a and a are equal. At second iteration a and S are not equal, and it will skip it, however substr's first character is equal to it.

So it should be:

public static int subStringIndex(String str, String substr) {
    int substrlen = substr.length();
    int strlen = str.length();
    int j = 0;

    if (substrlen >= 1) {
        for (int i = 0; i < strlen; i++) {              // iterate through main string
            if (str.charAt(i) == substr.charAt(j)) {    // check substring
                j++;                                    // iterate
                if (j == substrlen) {                   // when to stop
                    return i - (substrlen - 1); //found substring. As i is currently at the end of our substr so sub substrlen
                }
            }
            else {
                i -= j;
                j = 0;
            }
        }
    }
    return -1;
}

Edit update:

Needed to subtract 1 from the String's length in order to pass the right answer.

\$\endgroup\$
0
\$\begingroup\$

Here is another version:

public static int indexOf(String original, String find) {

    if (find.length() < 1)
        return -1;

    boolean flag = false;
    for (int i = 0, k = 0; i < original.length(); i++) {
        if (original.charAt(i) == find.charAt(k)) {
            k++;
            flag = true;
            if (k == find.length())
                return i - k + 1;
        } else {
            k = 0;
            if (flag) {
                i--;
                flag = false;
            }
        }
    }

    return -1;
}
\$\endgroup\$
1
  • \$\begingroup\$ This is called a "code dump" some explanation of your changes would improve this answer \$\endgroup\$ Commented Feb 2, 2018 at 19:34
-2
\$\begingroup\$

My re-writing: clear and clean, yet efficient. There is no innovation in the algorithm. Just the way of the coding in more structural re-arrangement, trying to make the thought and steps easy to read and understand (comments are welcome):

static int subStringIndex( String str, String substring) {
    if (substring.length() < 1 )
        return -1;

    int L = str.length();
    int l = substring.length();
    int index = -1;

    for (int i = 0, j; i <= L-l; i++) {
    // if the remaining (L-i) is smaller than l, 
    // there won't be no enough length to contain the substring.
        for (j = 0; j < l; j++) {
            if (substring.charAt(j) != str.charAt(i+j) ) {
                    break;
            } 
        }
        // has it reached the end of the shorter string? 
        // if so, it means no non-equals encountered.
        if (j == l) {
            index = i;
            break;
        }
    }

    return index;
}
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome. Please if this is a different version as you say, then edit your answer to explain why it is better than the OP's one \$\endgroup\$ Commented Apr 2, 2018 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.