2010-04-02 25 views

risposta

13

Si può fare la matematica semplice con caratteri in Java così:

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

uscita volontà 0.

+3

Nota che quelle devono essere caratteri, non stringhe.Le virgolette singole sono importanti. – Thilo

+0

Questo restituirà valori fasulli per i caratteri al di fuori del dominio. Il codice è fragile. –

+1

"Ciò restituirà valori fasulli per i caratteri al di fuori del dominio.". Così sarà l'equivalente C. – Thilo

20

Utilizzare il metodo indexOf su un oggetto String. Ad esempio,

"ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf('F')

rendimenti 5.

+2

Ehi, bel trucco :) –

+3

Se non si richiedono i controlli di intervallo, 'F' - 'A' è più veloce, però. – Thilo

+0

Non dimenticare di tenere conto di casi di errore - se indexOf restituisce -1, che significa che è stato dato un personaggio non nella stringa (in questo caso, qualcosa oltre una lettera maiuscola). – Etaoin

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

@Stefan, che è una soluzione terribile, dal momento che si sta cercando in modo lineare attraverso l'alfabeto. Certo, è un tempo costante perché hai un alfabeto di dimensioni fisse, ma è inutilmente lento. –

+4

Inoltre, -1 per il downvoting di tutti gli altri. Questo è semplicemente odioso. –

+0

Quindi utilizzare una mappa del carattere per il valore numerico. Questa soluzione richiede 26 confronti di caratteri (13 in media), rispetto a una chiamata ad hashcode, quindi ci sono minori risparmi nella migliore delle ipotesi in termini di velocità. –

2

L'uscita vi aspettate è solo l'offset di una lettera maiuscola rispetto al 'A'. Quindi basta sottrarre il valore Unicode di 'A' dal valore unicode della lettera di cui è necessario l'offset.

esempio: 'B' - 'A' = 1

+0

Leggi i miei commenti sopra. Questo codice è intrinsecamente sbagliato. –

+0

@Stefan: Applicherò quanto sopra solo per le lettere maiuscole. Non per nessun carattere. – codaddict

+3

"Inherently wrong" è un po 'forte. Presume che l'input sia compreso nell'intervallo corretto, ma non c'è nulla di sbagliato in questo. – Thilo

1

Ecco diversa implementazione che viene eseguito in tempo logaritmico:

Classe

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

Unit Test

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

in realtà il punto debole delle altre soluzioni qui è che esse implicano la creazione stringa

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 
} 

ora è possibile utilizzare la funzione ordinale per ottenere l'offset qui. per esempio. Alphabet.L.ordinal();

Tuttavia, dato che suppongo avete a che fare con le funzioni, qui è una definizione più utile

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(); 
    }  
} 

Note: a differenza di altre lingue, è possibile dichiarare un enum in un suo file esattamente come una classe. In realtà le enumerazioni come mostrato sopra possono contenere anche campi e metodi, i campi sono creati staticamente e sono molto difficili da violare. Infatti, l'uso di un enum con solo metodi e variabili locali e un singolo tipo di enum chiamato INSTANCE è il modo consigliato per creare un singleton in quanto è infrangibile anche per riflessione.

Si consiglia di pensare a scivolare una chiamata toUpperCase() in là anche se non si sta controllando le chiamate alla funzione

Se stai cercando di creare più dinamico il tuo alfabeto, piuttosto che utilizzare un alfabeto predefinito, dovresti esaminare le mappe

Problemi correlati