Как подсчитать частоту повторяемости букв в файле?
Необходимо из текстового файла вывести в консоль частоту повторяемость букв в файле, например: а - 20, б - 32. Я смог реализовать только подсчет по строкам. Может сканером можно как-то сразу по всему тексту пройтись?
public final class Text {
public static final String RESOURCES_TXT = "./resources/txt/";
public static final char LETTERS[] = {'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о',
'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я'};
private Text() {
}
public static void getSumChars(String fileName) {
File file = new File(RESOURCES_TXT, fileName);
if (file.exists() && file.isFile()) {
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNext()) {
for (char ch = 'а'; ch <= 'я'; ch++) {
LETTERS[ch - 'а'] = ch;
}
int count = 0;
char letter;
String linesOfText = scanner.nextLine();
for (int i = 0; i < LETTERS.length - 1; i++) {
for (int j = 0; j < linesOfText.length(); j++) {
letter = linesOfText.toLowerCase().charAt(j);
if (letter == LETTERS[i]) {
count++;
}
}
System.out.println(LETTERS[i] + " - " + count);
count = 0;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ответы (2 шт):
Можно обойтись без класса Scanner и использовать возможности NIO.
Просто записать содержимое файла в строку:
String result = Files.readString(Path.of(fileName));
Имея содержимое файла в одной строке код вашего метода сокращается до:
public static void getSumChars(String fileName) {
try {
String result = Files.readString(Path.of(fileName));
for (char ch = 'а'; ch <= 'я'; ch++) {
LETTERS[ch - 'а'] = ch;
}
int count = 0;
char letter;
for (int i = 0; i < LETTERS.length - 1; i++) {
for (int j = 0; j < result.length(); j++) {
letter = result.toLowerCase().charAt(j);
if (letter == LETTERS[i]) {
count++;
}
}
System.out.println(LETTERS[i] + " - " + count);
count = 0;
}
} catch (IOException e) {
e.printStackTrace();
}
}
Счётчик букав сохраняется в Map. Зачем самому искать элемент счётчика для данной буквы, когда это может делать Map?
Файл перебирается посимвольно
Для удобства местами используется функциональщина из java 8
Чтобы не сортировать Map на выводе результата, то вместо HashMap можно подобрать реализацию, которая сортируется автоматически (TreeMap)
Map<Character, Integer> counters = new HashMap<>();
try (InputStreamReader reader = new InputStreamReader(
Files.newInputStream(Paths.get(RESOURCES_TXT, fileName)), "UTF-8")) {
int c = reader.read();
while (c != -1) {
counters.compute((char)c, (t, u) -> u != null ? u + 1 : 1);
// или так, если без учёта регистра
// counters.compute(Character.toLowerCase((char)c), (t, u) -> u != null ? u + 1 : 1);
c = reader.read();
}
}
counters.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach((t) -> {
System.out.println(t.getKey() + " - " + t.getValue());
});