2012-05-18 11 views
16

¿Hay alguna forma en Java para encontrar el índice de un carácter que comience desde el final y teniendo length() como referencia como lo hacen otros idiomas?Java negative indexOf (contando desde el final [longitud()])

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

... en lugar de lo obvio

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

Gracias!

+1

¿Qué esperas que se devuelva para '" dabcd ".indexOf (" d ", - 0)'?(FYI, no necesita declarar una nueva Cadena cada vez; puede llamar a los métodos de Cadena directamente en un literal de Cadena) – rob

Respuesta

22

lastIndexOf(int ch) comenzará desde el final y buscar hacia atrás, volviendo el índice absoluto de la última ocurrencia. Luego, puedes restar ese número de la longitud del String y negarlo, si eso es lo que realmente quieres.

También puede usar lastIndexOf(int ch, int fromIndex) si desea buscar hacia atrás desde un índice en particular.

Para responder a su pregunta sobre qué sucede cuando pasa un número negativo, puede profundizar en el código fuente de la clase String. Como resultado, la implementación indexOf que finalmente se llamó restablece un negativo fromIndex valor a cero:

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

Volviendo a su segundo ejemplo:

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

... la implementación de un indexOf genérico que acepta un índice negativo y devuelve el índice negativo apropiado (si hay uno) es más complicado porque Java no distingue entre int0 y int-0 (ambos se representarán como 0), y porque String.indexOf ni mally devuelve -1 si no se encuentra la cadena de búsqueda. Sin embargo, puedes acercarte a lo que quieres. Tenga en cuenta que hay algunas advertencias:

  1. String.indexOf normalmente regrese -1 si no se encuentra la cadena de búsqueda. Pero debido a que -1 es un índice válido en nuestra nueva implementación, necesitamos definir un nuevo contrato. Integer.MIN_VALUE ahora se devuelve si no se encuentra la cadena de búsqueda.
  2. Porque no podemos probar para int-0, no podemos referirnos al índice del último carácter como -0. Por esa razón, usamos -1 para referirnos al índice del último carácter, y continuamos contando hacia atrás desde allí.
  3. Para mantener la coherencia con el elemento 2, los valores de retorno negativos también comienzan la cuenta atrás comenzando con -1 como el índice del último carácter.

El código podría simplificarse, pero intencionalmente lo he hecho prolijo para que pueda pasarlo fácilmente en un depurador.

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 
    } 
} 
4

sólo tiene que utilizar String.lastIndexOf() método:

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

Gracias, miré en la API pero pensé que tal vez me faltaba algo y JavaDoc no lo hace explique cómo se comporta con números negativos – Whimusical

+4

-1 - ¿Por qué no simplemente usa 'lastIndexOf'? – rjzii

+4

Esto imprime 3 no 0 – Raju

0

Desde aquí se puede revertir la cadena por cierto:

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

¡Gran enfoque! El único problema es que perderás el análisis de longitud porque en mi ejemplo si pudieras hacer un .reverseIndex ('.', 5) obtendrías un -1 para cualquier cadena.length() <5. Pero eso es algo menor – Whimusical

+0

No entiendo lo que quiere decir con '' perder el análisis de longitud ''. Entiendo que su método devuelve -1 cuando usa un índice fuera de límite en su método inverso pero el problema no se puede agregar en mi método. ¿Qué quieres que haga mi método? –

+0

Quiero decir que lo bueno de un reverseIndex sería que podrías tomar siempre una posición absoluta al revés, por lo que si no existe obtengo un -1, pero aquí nunca sucede. No puedo decir "Quiero la letra 3 lugares antes del carácter 14 mientras exista". Pero me gusta tu camino y creo que es el mejor recurso. – Whimusical