简体   繁体   中英

java recursion find the last index of a character in a string

Here is what I have for method lastIndexOf , ch is the character to match, and str is the source string.

public static int lastIndexOf(char ch, String str) {
    // check for null string or empty string
    if (str.length() == 0 || str == null) {
        return -1;
    }

    int indexInRest = lastIndexOf(ch, str.substring(1));
    char first = str.charAt(0);

    // recursive call to find the last matching character
    if (first == ch) {
        return 1 + indexInRest; // this might not work properly
    } else
        return indexInRest;
}

If in my class' main method I call:

    System.out.println(lastIndexOf('r', "recurse"));
    System.out.println(lastIndexOf('p', "recurse"));

I got:

1
-1

The desired result is:

4
-1

Suggestion, please.

This must be homework because there would be no point to writing this method since String.lastIndexOf() exists in the API, and using recursion to do this going to be slow and use a lot of memory.

Here a hint. Right now your algorithm is chopping characters off the front ( substring(1) ) and comparing them. lastIndexOf() should start by removing characters at the back of the String looking for a match then quit when it finds one.

How about taking the functional approach..

public static int lastIndexOf(char ch, String str) {
    if (str.charAt(str.length() - 1) == ch) { return str.length() -1; }
    if (str.length() <= 1) { return -1; }
    return lastIndexOf(ch, str.substring(0, str.length() - 1));
}

为什么不像这样使用String.lastIndexOf

str.lastIndexOf(ch)

Use the String#lastIndexOf(int ch) implementation as a general guideline,

public int lastIndexOf(int ch) {
    return lastIndexOf(ch, value.length - 1);
}

public int lastIndexOf(int ch, int fromIndex) {
    if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
        // handle most cases here (ch is a BMP code point or a
        // negative value (invalid code point))
        final char[] value = this.value;
        int i = Math.min(fromIndex, value.length - 1);
        for (; i >= 0; i--) {
            if (value[i] == ch) {
                return i;
            }
        }
        return -1;
    } else {
        return lastIndexOfSupplementary(ch, fromIndex);
    }
}

private int lastIndexOfSupplementary(int ch, int fromIndex) {
    if (Character.isValidCodePoint(ch)) {
        final char[] value = this.value;
        char hi = Character.highSurrogate(ch);
        char lo = Character.lowSurrogate(ch);
        int i = Math.min(fromIndex, value.length - 2);
        for (; i >= 0; i--) {
            if (value[i] == hi && value[i + 1] == lo) {
                return i;
            }
        }
    }
    return -1;
}

And this,

lastIndexOf(ch, value.length - 1);

value is the target String as a character array.

First, you should change to:

if (str == null || str.length() == 0) {

Because a NPE could raise if str is null

Add a deep paramater to your code like this:

public static int lastIndexOf(char ch, String str, int deep) {

And increment its value every recursive call

int indexInRest = lastIndexOf(ch, str.substring(1), deep++);

then, in the return sentence, add deep to your returned value:

return 1 + indexInRest + deep; // this might not work properly

Call the function the first time with deep = 0 , or better yet, make the two parameter method lastIndexOf call the 3 parameters version of lastIndexOf with the deep parameter set to 0

You can also use Matcher in order to anticipate evolution of string analysis asked by your homework:

public int getlastMatch(String searchPattern,String textString) {
       int index = -1;
       Pattern pattern = Pattern.compile(searchPattern);
       Matcher matcher = pattern.matcher(textString);

       while(matcher.find()) {
               index = matcher.start();
       }
       return index;
   }

where textString may be your concerned character.

Thus returning the last occurence of a part of string within a string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM