Почему мы используем string.charAt (index) - 'a' в Java? - PullRequest
0 голосов
/ 31 августа 2018
public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = br.readLine();
    int[] arr = new int[26];
    for(int i=0;i<s.length();i++)
        arr[s.charAt(i)-'a']++;

    int odds = 0;
    for(int i=0;i<26;i++)
        if(arr[i]%2!=0)
            odds++;

    if(odds%2==1 || odds==0)
        System.out.println("First");
    else
        System.out.println("Second");

}

Я видел этот фрагмент кода и нашел эту часть запутанной. Итак, не могли бы вы сказать мне, почему мы используем это и каково значение «а» в этом? -> arr [s.charAt (i) - 'a'] ++;

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Этот код создает гистограммный счетчик для каждой буквы алфавита. Попробуйте напечатать символ, такой как 'a', следующим образом:

System.out.println((int)'a'); // Output: 97

Каждый char имеет соответствующее значение Unicode в диапазоне от 0 до 65 535. Вычитание 'a' масштабирует каждую букву в алфавите до диапазона 0-26, который соответствует «корзинам» в массиве arr. Вот пример:

System.out.println('z' - 'a'); // Output: 25 (the last bucket in the array)
System.out.println('a' - 'a'); // Output: 0 (the first bucket in the array)

Второй цикл в коде проверяет четность каждого счетчика, чтобы определить, какие из них нечетные. Наконец, окончательная печать условно проверяет, совпадает ли общее количество букв с нечетным числом вхождений. Если эта сумма равна 0 или сама нечетна, выведите "First", иначе "Second".

Попробуйте этот код с любым символом за пределами от a до z или с заглавной буквой. Он потерпит крах, потому что ASCII-представление символа не соответствует размеру массива, и вы получите IndexOutOfBoundsException.

Вот пример программы, показывающей, как строится гистограмма, и преобразует ее выходные данные в буквы путем сложения:

class Main {
    public static void main(String[] args) {
        String s = "snuffleupagus";
        int[] arr = new int[26];

        for (int i = 0; i < s.length(); i++) {
            arr[s.charAt(i)-'a']++;
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.println((char)(i + 'a') + ": " + arr[i]);
        }
    }
}

Выход:

a: 1
b: 0
c: 0
d: 0
e: 1
f: 2
g: 1
h: 0
i: 0
j: 0
k: 0
l: 1
m: 0
n: 1
o: 0
p: 1
q: 0
r: 0
s: 2
t: 0
u: 3
v: 0
w: 0
x: 0
y: 0
z: 0

И repl для экспериментов.

0 голосов
/ 31 августа 2018

arr состоит из массива int размером 26, который также является количеством букв английского алфавита. Все, что делает этот цикл, - это подсчет частоты букв, представленных через их индекс в алфавите, arr[0] - 'a', arr[1] - 'b' и т. Д.

Технически это можно объяснить просто. s.charAt(i) возвращает экземпляр char в указанной позиции i. char также может быть представлен как байт в Java. Затем вычитание получает значение ASCII (представленное как byte), равное 'a', из текущего символа в i. Итак, в итоге вы получите 'a' - 'a' == 0, 'b' - 'a' == 1 и т. Д.

Обратите внимание, что это, вероятно, не лучший способ подсчета символов, поскольку строка может содержать не только строчные буквы, например заглавные буквы и многие другие символы.

...