Распечатать горизонтальную гистограмму для букв в файле. Как его масштабировать? Джава

Я хотел бы подсчитать количество букв в текстовом файле и нарисовать горизонтальную гистограмму. Тем не менее, самый длинный бар должен иметь длину 50 звезды. Это не проблема, когда у меня число меньше 50, но как его масштабировать, чтобы у меня все было на гистограмме?

Я придумал эту формулу: 50 - 50 * histogram[i] / maxnum где 50 максимальная длина стержня, histogram[i] это число случаев i-th буква в алфавите и maxnum это число, представляющее количество наиболее распространенных букв в моем файле.

int[] histogram = new int[26];     
String alphabeth = "abcdefghijklmnopqrstuvwxyz";

Вот как я строю гистограмму:

while((line = bfr.readLine()) != null){
     for (int i =0;i< line.length();i++){
          int index = alphabeth.indexOf(line.charAt(i));
          if (index != -1)
            histogram[index]++;  
     }
}

Я ищу maxval:

int maxnum = histogram[0];
        for (int p=1; p<histogram.length;p++){
            if (maxnum < histogram[p]){
                maxnum = histogram[p];
            }
        }

И вот как я это рисую:

for (int i=0; i<alphabeth.length(); i++){
            System.out.print(alphabeth.charAt(i) + " ");
            int count = histogram[i];
                for (int k=0; k<50-50*histogram[i]/maxval; k++){
                    System.out.print("*");
                }
        }

Это правильно?

2 ответа

Я не вижу смысла в 50-50. Вы не можете просто удалить первые 50?

Является ли гистограмма [i] или maxval типа float или double? Это необходимо для того, чтобы деление не возвращало целочисленное значение.

Кстати: вы должны действительно использовать скобки в вашей формуле. И, возможно, было бы неплохо рассчитать количество звездочек для отдельной печати и сохранить их в отдельной переменной, а не вычислять в заголовке цикла for.

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

     HashMap<Integer, Integer> alphabet = new HashMap<>();
     double totalChars = 0;
     for(int i = 0; i < 26; i++)
     {
         Random ran = new Random();
         int x = ran.nextInt(500) + 1; //create some random amount of char occurrences
         alphabet.put(i, x);
         totalChars += alphabet.get(i); //get the total char count
     }

     System.out.println("Total Chars: " + totalChars);
     for(int i = 0; i < 26; i++)
     {
         System.out.print(i + " [" + ((double)alphabet.get(i))/totalChars * 100 + "%]: ");
         for(int j = 0; j < ((double)alphabet.get(i))/totalChars * 100; j++)
         {
             System.out.print("*");
         }
         System.out.println();
     }

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

Выход:

Total Chars: 6898.0
0 [6.494636126413453%]: *******
1 [2.7544215714699916%]: ***
2 [3.0878515511742535%]: ****
3 [3.1603363293708324%]: ****
4 [4.914467961728037%]: *****
5 [1.7396346767178894%]: **
6 [0.8408234270803132%]: *
7 [4.450565381269933%]: *****
8 [3.102348506813569%]: ****
9 [1.0872716729486807%]: **
10 [6.668599594085242%]: *******
11 [7.060017396346767%]: ********
12 [3.0878515511742535%]: ****
13 [5.131922296317773%]: ******
14 [1.348216874456364%]: **
15 [5.131922296317773%]: ******
16 [2.638445926355465%]: ***
17 [1.290229051899101%]: **
18 [3.4067845752391994%]: ****
19 [1.6526529428819947%]: **
20 [7.089011307625398%]: ********
21 [6.364163525659612%]: *******
22 [5.682806610611771%]: ******
23 [5.769788344447666%]: ******
24 [5.030443606842563%]: ******
25 [1.0147868947521022%]: **
Другие вопросы по тегам