2010-04-02 19 views

Respuesta

13

Puede hacer operaciones matemáticas simples con caracteres en Java, así:

System.out.println('A' - 'A'); 

dará salida a 0.

+3

Tenga en cuenta que esos deben ser caracteres, no cadenas.Las comillas simples son importantes. – Thilo

+0

Esto devolverá valores falsos para caracteres fuera del dominio. El código es frágil –

+1

"Esto devolverá valores falsos para caracteres fuera del dominio". Lo mismo hará el C equivalente. – Thilo

20

Utilice el método indexOf en un objeto String. Por ejemplo,

"ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf('F')

rendimientos 5.

+2

Oye, buen truco :) –

+3

Si no necesitas los controles de rango, 'F' - 'A' es más rápido. – Thilo

+0

No olvide dar cuenta de los casos de error - si indexOf devuelve -1, eso significa que recibió un carácter que no está en la cadena (en este caso, algo además de una letra mayúscula). – Etaoin

-1
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
return alphabet.indexOf(myChar); 
+2

@Stefan, esa es una solución terrible, ya que está buscando linealmente el alfabeto. Claro, es un tiempo constante porque tienes un alfabeto de tamaño fijo, pero es innecesariamente lento. –

+4

Además, -1 por vencer a todos los demás. Eso es simplemente desagradable. –

+0

Luego usa un mapa de caracteres para el valor numérico. Esta solución requiere 26 comparaciones de caracteres (13 en promedio), frente a una llamada a hashcode, por lo que hay ahorros menores en el mejor de los casos en términos de velocidad. –

2

La salida está esperando es sólo el offset de una letra mayúscula con respecto al 'A'. Así que solo resta el valor Unicode de 'A' del valor unicode de la letra cuyo desplazamiento es necesario.

ejemplo: 'B' - 'A' = 1

+0

Lee mis comentarios arriba. Este código es intrínsecamente incorrecto. –

+0

@Stefan: Aplicaré lo anterior solo para letras mayúsculas. No es para ningún char. – codaddict

+3

"Inherentemente incorrecto" es un poco fuerte. Asume que la entrada es del rango apropiado, pero no hay nada de malo en eso. – Thilo

1

Aquí es diferente aplicación que se ejecuta en el tiempo logarítmica:

Clase

import java.util.Arrays; 
import java.util.Collections; 

public class CharacterIndex { 
    private char[] characters = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; 
    public int index(char character) { 
     assert characters != null; 
     return Arrays.binarySearch(characters, Character.toUpperCase(character));     
    } 
} 

ensayo Unidad

import org.junit.Before; 
import org.junit.Test; 

import static junit.framework.Assert.assertEquals; 

public class CharacterIndexTest { 
    private CharacterIndex characterIndex; 
    @Before 
    public void createIndex() { 
     characterIndex = new CharacterIndex(); 
    } 
    @Test 
    public void testIndexOfLetterA() { 
     assertEquals(0, characterIndex.index('A')); 
     assertEquals(0, characterIndex.index('a')); 
    } 
    @Test 
    public void testNotALetter() { 
     assertEquals(-1, characterIndex.index('1')); 
    } 

} 
4

en realidad el punto de las otras soluciones aquí débil es que implican la creación cadena

public enum Alphabet { 
    A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z 
} 

ahora se puede utilizar la función ordinal para obtener la compensación aquí. p.ej. Alphabet.L.ordinal();

Sin embargo, ya que supongo que se trata de funciones, aquí es una definición más útil

public enum Alphabet { 
    A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; 

    public static int getNum(String targ) { 
     return valueOf(targ).ordinal(); 
    } 

    public static int getNum(char targ) { 
     return valueOf(String.valueOf(targ)).ordinal(); 
    }  
} 

Notas: a diferencia de otros idiomas, se puede declarar una enumeración en su propio archivo exactamente igual que una clase. De hecho, las enumeraciones que se muestran arriba también pueden contener campos y métodos, los campos están creados estáticamente y son muy difíciles de romper. De hecho, el uso de una enumeración con solo métodos y variables locales y un solo tipo de enumeración llamado INSTANCE es la forma recomendada de crear un singleton ya que es irrompible incluso por reflexión.

Es posible que desee pensar en el deslizamiento de una llamada toUpperCase() en allí también si no se está controlando las llamadas a la función

Si usted está buscando para crear más dinámicamente su alfabeto en lugar de utilizar un alfabeto predefinido, debe buscar en los mapas

Cuestiones relacionadas