Рассчитать частоту символов в строке (Java, Performance) - PullRequest
2 голосов
/ 17 марта 2019

Проблема

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

Код

import java.util.Scanner;
public class Letters {
    public static void main(String[] args) {
        @SuppressWarnings("resource")
        Scanner sc = new Scanner(System.in);
        char[] c = {'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'};
        int[] f = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        System.out.println("Enter a string.");
        String k = sc.nextLine();
        String s = k.toUpperCase();
        s = s.trim();
        int l = s.length();
        System.out.println("Checking string = " + s);
        char ch;
        for (int i = 0; i < l; i++) {
            ch = s.charAt(i);
            for (int j = 0; j < c.length; j++) {
                if (ch == c[j]) {
                    f[j]++;
                }
            }
        }
        System.out.println("Char\tFreq");
        for (int i = 0; i < c.length; i++) {
            if (f[i] != 0) {
                System.out.println(c[i] + "\t" + f[i]);
            }
        }
    }
}

Ответы [ 5 ]

2 голосов
/ 17 марта 2019

Вам не нужно явно инициализировать 26 записей в вашем частотном массиве (значение по умолчанию равно нулю);Вам также не нужно хранить таблицу символов (достаточно знать смещение).То есть ваш код может полностью исключить c и вычислять каждую букву;как,

Scanner sc = new Scanner(System.in);
int[] f = new int[26];
System.out.println("Enter a string.");
String orig = sc.nextLine();
String k = orig.trim().toUpperCase();
System.out.println("Checking string = " + orig);
for (char ch : k.toCharArray()) {
    f[ch - 'A']++;
}
System.out.println("Char\tFreq");
for (int i = 0; i < f.length; i++) {
    if (f[i] != 0) {
        System.out.println((char) ('A' + i) + "\t" + f[i]);
    }
}
0 голосов
/ 17 марта 2019

Есть много способов решить проблему, я бы посоветовал вам следовать тому, который вы легко понимаете. Мое решение ниже в основном инициализирует массив из 26 для подсчета частоты всех символов.

Важная часть:

Каждый алфавит будет иметь значение ASCII, поэтому, приведя тип, вы в конечном итоге получите целочисленное значение, а затем вычтя 65 (для заглавных букв) , вы получите индекс массива для хранения частоты соответствующий символ.

Ваш модифицированный код Java

import java.util.Scanner;
public class Letters{
    public static void main(String[] args) {
        @SuppressWarnings("resource")
        Scanner sc = new Scanner(System.in);
        int[] f = new int[26];
        System.out.println("Enter a string.");
        String k = sc.nextLine();
        String s = k.toUpperCase();
        s = s.trim();
        int l = s.length();
        System.out.println("Checking string = " + s);
        char ch;
        for (int i = 0; i < l; i++) {
            ch = s.charAt(i);

            //This will give the ASCII value of the character i.e. ch
            int temp=(int)ch;
            if(temp>=65 && temp<=90){
              //subtract 65 to get index 
              //add 1 to increase frequency 
              f[temp - 65]+=1;
            }

        }
        System.out.println("Char\tFreq");
        for (int i = 0; i < 26; i++) {
            if (f[i] != 0) {
                //Add 65 to get respective character
                System.out.println((char)(i+65) + "\t" + f[i]);
            }
        }
    }
}

Например:

f [0] для «A»

f [1] для «B»

....

f [25] для 'Z'

(помните, индекс начинается с 0)

Таким образом, вы можете исключить внутренний цикл for и получить частоту с одним целочисленным массивом.

0 голосов
/ 17 марта 2019

Если у нас есть строки типа «romeo@alphacharlie.com», то пример с freqArr [c - 'A'] ++ не будет работать.Вы можете попробовать использовать это.

private static int[] decodeFrequency(char[] array) {
    int[] freqArr = new int[127];
    for ( char c : array ) {
        freqArr[(int)c]++;
    }
    return freqArr;
}
0 голосов
/ 17 марта 2019

Вы можете найти частоту символов в строке, написав

String.length() - String.replaceAll("character", "").length();
0 голосов
/ 17 марта 2019

Вы избегаете внутреннего цикла, используя тот факт, что буквы A-Z появляются последовательно в ASCII. Таким образом, вам не нужно искать символ в массиве c, просто рассчитайте индекс. Смотрите код ниже:

for (int i = 0; i < l; i++) {
    char ch = s.charAt(i);
    if (ch >= 'A' && ch <= 'Z') {
        int j = (int)(ch - 'A'); // j will be in the range [0, 26)
        f[j]++;
    } 
}

Мы можем избавиться от массива c также аналогично.

for (int i = 0; i < 26; i++) {
    if (f[i] != 0) {
        System.out.println((char)('A' + i) + "\t" + f[i]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...