Java negative indexOf (подсчет с конца [длина()])

Есть ли способ в Java найти indexOf из char, начиная с конца, и иметь длину() в качестве ссылки, как это делают другие языки?

   new String("abcd").reverseIndexOf("d"(,[4 or -0]))
or new String("abcd").indexOf("d",-0) // Should return a (-)1

... вместо очевидного

   new String("abcd").indexOf("d") - newString("abcd").length()     

Спасибо!

Ответы

Ответ 1

lastIndexOf(int ch) начнется с конца и начнет поиск назад, возвращая абсолютный индекс последнего вхождения. Затем вы можете вычесть это число из длины строки и отрицать его, если это то, что вы действительно хотите.

Вы также можете использовать lastIndexOf(int ch, int fromIndex), если вы хотите искать назад от определенного индекса.

Чтобы ответить на вопрос о том, что происходит, когда вы передаете отрицательное число, вы можете вставить исходный код для класса String. Как оказалось, реализация indexOf, которая в конечном итоге называется, сбрасывает отрицательное значение fromIndex в ноль:

static int indexOf(char[] source, int sourceOffset, int sourceCount,
                   char[] target, int targetOffset, int targetCount,
                   int fromIndex) {
if (fromIndex >= sourceCount) {
        return (targetCount == 0 ? sourceCount : -1);
}
    if (fromIndex < 0) {
        fromIndex = 0;
    }
    ...

Возвращаясь к вашему второму примеру:

"abcd".indexOf("d",-0)

... реализация универсального indexOf, который принимает отрицательный индекс и возвращает соответствующий отрицательный индекс (если он есть), более сложный, поскольку Java не различает int 0 и int -0 ( оба будут представлены как 0), и поскольку String.indexOf обычно возвращает -1, если строка поиска не найдена. Однако вы можете приблизиться к тому, что хотите. Обратите внимание, что есть несколько предостережений:

  • String.indexOf обычно возвращает -1, если строка поиска не найдена. Но поскольку -1 является допустимым индексом в нашей новой реализации, нам нужно определить новый контракт. Integer.MIN_VALUE теперь возвращается, если строка поиска не найдена.
  • Поскольку мы не можем проверить int -0, мы не можем ссылаться на индекс последнего символа как -0. По этой причине мы используем -1 для обозначения индекса последнего символа и продолжаем считать назад оттуда.
  • Для согласования с пунктом 2 отрицательные возвращаемые значения также начинают отсчет, начиная с -1 в качестве индекса последнего символа.

Код может быть упрощен, но я намеренно сделал его подробным, чтобы вы могли легко выполнить его в отладчике.

package com.example.string;

public class StringExample {

    public static int indexOf(String str, String search, int fromIndex) {
        if (fromIndex < 0) {
            fromIndex = str.length() + fromIndex; // convert the negative index to a positive index, treating the negative index -1 as the index of the last character
            int index = str.lastIndexOf(search, fromIndex);
            if (index == -1) {
                index = Integer.MIN_VALUE; // String.indexOf normally returns -1 if the character is not found, but we need to define a new contract since -1 is a valid index for our new implementation
            }
            else {
                index = -(str.length() - index); // convert the result to a negative index--again, -1 is the index of the last character 
            }
            return index;
        }
        else {
            return str.indexOf(str, fromIndex);
        }
    }

    public static void main(String[] args) {
        System.out.println(indexOf("abcd", "d", -1)); // returns -1
        System.out.println(indexOf("adbcd", "d", -2)); // returns -4
    }
}

Ответ 2

Просто используйте метод String.lastIndexOf():

String s = "abcd";
int rindex = s.lastIndexof('d');
System.out.println(rindex); // print 0

Ответ 3

Вы можете легко изменить строку:

String s="abcd";
StringBuilder reverseS = new StringBuilder(s).reverse();
System.out.println(reverseS.indexOf("d")); //print 0
System.out.println(reverseS.indexOf("a")); //print 3
System.out.println(reverseS.indexOf("d",1)); //print -1