web-dev-qa-db-fra.com

Java négatif indexOf (à partir de la fin [longueur ()])

Y at-il un moyen en Java de fonder indexOf d’un caractère à partir de la fin et d’avoir length () comme référence comme le font les autres langages?

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

... au lieu de l'évidence 

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

Merci!

19
Whimusical

lastIndexOf(int ch) commencera à la fin et cherchera en arrière, en retournant l'index absolu de la dernière occurrence. Ensuite, vous pouvez soustraire ce nombre de la longueur de la chaîne et le nier, si c'est ce que vous voulez vraiment.

Vous pouvez également utiliser lastIndexOf(int ch, int fromIndex) si vous souhaitez effectuer une recherche en arrière à partir d'un index particulier.

Pour répondre à votre question sur ce qui se passe lorsque vous transmettez un nombre négatif, vous pouvez creuser dans le code source de la classe String. En fin de compte, l'implémentation indexOf qui est finalement appelée réinitialise à zéro la valeur fromIndex négative:

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

Revenons à votre deuxième exemple:

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

... implémenter un indexOf générique qui accepte un index négatif et renvoie l'index négatif approprié (le cas échéant) est plus compliqué car Java ne fait pas la distinction entre int0 et int-0 (les deux seront représentés par 0), et parce que String .indexOf renvoie normalement -1 si la chaîne de recherche n’est pas trouvée. Cependant, vous pouvez vous approcher de ce que vous voulez. Notez qu'il y a quelques mises en garde:

  1. String.indexOf renvoie normalement -1 si la chaîne de recherche n'est pas trouvée. Mais comme -1 est un index valide dans notre nouvelle implémentation, nous devons définir un nouveau contrat. Integer.MIN_VALUE est maintenant renvoyé si la chaîne de recherche n'est pas trouvée.
  2. Comme nous ne pouvons pas tester int-0, nous ne pouvons pas appeler l’index du dernier caractère sous le nom -0. Pour cette raison, nous utilisons -1 pour faire référence à l'index du dernier caractère et continuons à compter à partir de là.
  3. Pour des raisons de cohérence avec l'élément 2, les valeurs de retour négatives commencent également à compter à partir de -1 comme index du dernier caractère.

Le code pourrait être simplifié, mais je l’ai intentionnellement mis en mode verbeux afin que vous puissiez le parcourir facilement dans un débogueur.

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
    }
}
26
rob

Utilisez simplement la méthode String.lastIndexOf():

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

Vous pouvez facilement inverser la chaîne en passant:

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
0
alain.janinm