2010-04-02 6 views

Odpowiedz

13

Można zrobić prostą matematykę ze znaków w Javie, a także:

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

wyjście będzie 0.

+3

Pamiętaj, że muszą to być znaki, a nie Ciągi.Pojedyncze cytaty są ważne. – Thilo

+0

To zwróci fałszywe wartości dla znaków spoza domeny. Kod jest delikatny. –

+1

"To zwróci fałszywe wartości dla znaków spoza domeny.". Podobnie będzie z ekwiwalentem C. – Thilo

20

Zastosowanie metody indexOf na obiekcie String. Na przykład,

"ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf('F')

powraca 5.

+2

Hej, miła sztuczka :) –

+3

Jeśli nie potrzebujesz kontroli zasięgu, "F" - "A" jest szybsze. – Thilo

+0

Nie zapomnij uwzględnić przypadków błędów - jeśli indexOf zwraca -1, oznacza to, że otrzymał znak nie w ciągu znaków (w tym przypadku coś poza wielką literą). – Etaoin

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

@Stefan, to straszne rozwiązanie, ponieważ przeszukujesz liniowo alfabetycznie. Oczywiście, jest to stały czas, ponieważ masz alfabet o stałej wielkości, ale jest on niepotrzebnie powolny. –

+4

Również, -1 za zaniedbanie wszystkich pozostałych. To po prostu nieprzyjemne. –

+0

Następnie użyj mapy postaci do wartości liczbowej. To rozwiązanie wymaga 26 porównań między znakami (średnio 13), w przeciwieństwie do wywołania hashcode, więc w najlepszym przypadku są niewielkie oszczędności. –

2

Wyjście spodziewasz się to dopiero offset z górnej litery względem 'A'. Dlatego po prostu odejmij wartość Unicode z 'A' od wartości Unicode litery, której przesunięcie jest potrzebne.

przykład: 'B' - 'A' = 1

+0

Przeczytaj moje komentarze powyżej. Ten kod jest z natury błędny. –

+0

@Stefan: Zastosuję powyższe tylko dla wielkich liter. Nie dla żadnego char. – codaddict

+3

"Z natury błędny" jest nieco mocny. Zakłada, że ​​dane wejściowe pochodzą z właściwego zakresu, ale nie ma w tym nic złego. – Thilo

1

Oto inna realizacja, która biegnie w czasie logarytmicznym:

klasy

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

Test jednostki

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

rzeczywiście słabym punktem innych rozwiązań jest to, że dotyczą one tworzenie ciąg

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 
} 

można teraz korzystać z funkcji porządkowej, aby uzyskać przesunięcie tutaj. na przykład Alphabet.L.ordinal();

Jednakże, ponieważ zakładam, że mamy do czynienia z funkcjami, tutaj jest bardziej przydatna definicja

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

Uwagi: w przeciwieństwie do innych języków, można zadeklarować enum w jego własnym pliku dokładnie tak samo jak klasa. Rzeczywiście, wyliczenia, jak pokazano powyżej, mogą również zawierać pola i metody, pola są statycznie tworzone i są bardzo trudne do złamania. W rzeczywistości użycie enum z tylko lokalnymi metodami i zmiennymi oraz pojedynczy typ wyliczeniowy o nazwie INSTANCE jest zalecanym sposobem tworzenia singletonu, ponieważ jest nie do złamania nawet przez odbicie.

Możesz myśleć o wsuwając toUpperCase() wywołanie tam też, jeśli nie są do kontrolowania połączeń z funkcją

Jeśli szukasz bardziej dynamicznie utworzyć alfabetu zamiast użyć gotowego alfabetu, powinieneś zaglądać na mapy

Powiązane problemy