Подсчет частоты букв алфавита в некоторых строках текста

Я попробовал эту программу, но она распечатала только частоту некоторых букв. Может ли кто-нибудь сказать мне, что я сделал неправильно? Любая помощь будет принята с благодарностью. С уважением, Куанг Фам

Вот что у меня получилось при запуске программы. Добро пожаловать в программу подсчета букв. Пожалуйста, введите несколько строк текста, затем точку и возврат. Вычисление занимает некоторое время. . . * 1: Четыре балла и семь лет назад наши предки * 2: породили на этом континенте новую нацию, * 3: зачатую в свободе и посвященную * 4: утверждение, что все люди созданы равными. Буква Частота a 13 c 6 e 19 g 2 i 9 k 0 m 1 o 15 q 1 s 6 u 5 w 1 y 2

import java.util.Scanner ;
/**
 *      The Letter Counter program counts the frequency of the letters of the 
 * alphabet in some lines of text.  After a period and a return, the computer
 * displays the frequency.
 *
 * @author Quang Pham
 * @version Module 8, Homework Project 2, 4/1/20
 * 
 *    Algorithm:
 *    
 *    1. User enters multiple lines of text.
 *    2. The program will read in the lines of text and display a list of all the 
 *       letters that occur in the text, with the number of times the letter occurs.
 *    3. The last line of input should be ended with a period, which serves as a 
 *       sentinel value.
 *    
 *    Problem description:
 *         Write a program that will read in multiple lines of text from the user 
 *    and display a list of all the letters that occur in the text, along with the 
 *    number of times each letter occurs.
 *
 *         The last line of input from the user should end with a period, which will 
 *    serve as a sentinel value.  Once the last line has been entered, the counts
 *    for all letters entered by the user should be listed in alphabetical order as 
 *    they are output.  Use an array of base type int of length 28, so that each 
 *    indexed variable contains the count of how many letters there are.  Array 
 *    indexed variable 0 contains the number of a’s, array indexed variable 1 contains
 *    the number of b’s and so forth.  Allow both uppercase and lowercase letters as
 *    input, but treat uppercase and lowercase versions of the same letter as being equal.
 *
 *    Hints: You might find it helpful to define a "helper" method that takes a character
 *    as an argument and returns an int value that is the correct index for that character,
 *    such as ‘a’ returning 0, ‘b’ returning 1, and so forth.  Note that you can use a 
 *    typecast to change a char to an int, like (int) letter.  This will not get the 
 *    number you want, but if you subtract (int) 'a', you will then have the right index. 
 *    Allow the user to repeat this task until the user says she or he is finished.
 *
 *    A dialog may look something like the following
 *
 *    Enter several lines of text to analyze. (Copy and paste to save time.)  When done,
 *    end a line with a period and press return.
 *    1: Four score and seven years ago our forefathers 
 *    2: brought forth upon this continent a new nation, 
 *    3: conceived in liberty, and dedicated to the  
 *    4: proposition that all men are created equal.
 *
 *    Here's the counts of characters:
 *    a: 13
 *    b: 2
 *    c: 6
 *    d: 7
 *    e: 19
 *    f: 4
 *    g: 2
 *    h: 6
 *    i: 9
 *    l: 4
 *    m: 1
 *    n: 14
 *    o: 15
 *    p: 3
 *    q: 1
 *    r: 12
 *    s: 6
 *    t: 15
 *    u: 5
 *    v: 2
 *    w: 1
 *    y: 2
 *
 *         Again, you can submit a single class for this project which contains your main
 *    method and any helper methods where you feel they can be used.
 *
 *    Along with the file containing your program, submit three print screens or screen 
 *    snips, each with several lines of text entered by the user, and the count for each
 *    character (a-z).
 */
public class LetterCounter
{
    public static void main(String[] args) {
        int frequency = 0 ;
        char character = ' ' ;
        String linesOfText = " " ; 

        char[] alphabet = new char[28] ; // new alphabet array        
        for(char ch = 'a'; ch <= 'z'; ++ch)// fills alphabet array with the alphabet
        {
            alphabet[ch-'a']=ch ;
        } 

        System.out.println("Welcome to the Letter Count program.") ; 
        System.out.println("Please enter some lines of text followed by a period and a return.") ;
        Scanner keyboard = new Scanner(System.in) ;
        linesOfText = keyboard.nextLine() ;
        System.out.println("Letter          Frequency") ;
        for (int i = 0; i < alphabet.length; i++) 
        {   frequency = 0 ;
            for (int j = 0; j < linesOfText.length(); j++) {
                character = linesOfText.charAt(j) ;
                if (character == alphabet[i]) {
                    frequency++ ;
                }
            }

            System.out.println(alphabet[i] + "\t\t" + frequency) ;
            i++;
        }
    }
}

person Quang    schedule 29.03.2020    source источник
comment
Имейте в виду, что n != N   -  person bakero98    schedule 29.03.2020
comment
Похоже, вы делаете только одну строку текста.   -  person NomadMaker    schedule 29.03.2020


Ответы (6)


Вы спросили, что вы сделали не так. Ну, вы очень близки, и вы сделали только две вещи неправильно.

  1. Эта строка char[] alphabet = new char[28] должна быть 26.
  2. Посмотрите на следующий код из вашей программы.
 for (int i = 0; i < alphabet.length; i++) 
        {   frequency = 0 ;
            for (int j = 0; j < linesOfText.length(); j++) {
                character = linesOfText.charAt(j) ;
                if (character == alphabet[i]) {
                    frequency++ ;
                }
            }

            System.out.println(alphabet[i] + "\t\t" + frequency) ;
            i++;
        }

В первом цикле вы увеличиваете i, используя i++, но вы также увеличиваете его в конце после оператора печати. Последний нужно удалить.

Несколько наблюдений

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

int count[] = new int[26];

скажем, вы найдете букву c == 'i'.

count[c - 'a']++; ///increments the count for letter i.
person WJS    schedule 29.03.2020
comment
Большое спасибо! Очень наблюдателен! Я удалил второй i++ и получил правильный ответ! Теперь, чтобы остановить программу после того, как она встретит точку. - person Quang; 29.03.2020

вы увеличиваете параметры цикла for и в конце цикла пропускаете буквы

for (int i = 0; i < alphabet.length; i++) 
        {   frequency = 0 ;
            for (int j = 0; j < linesOfText.length(); j++) {
                character = linesOfText.charAt(j) ;
                if (character == alphabet[i]) {
                    frequency++ ;
                }
            }

            System.out.println(alphabet[i] + "\t\t" + frequency) ;
            //righ here you shouldn't do this i++;
        }
person JRowan    schedule 29.03.2020

Я понимаю, что это ваша домашняя работа, но вот решение, которое было создано с нуля.

У нас есть метод с именем requestInput, который принимает объект Scanner и список строк и будет продолжать запрашивать ввод до тех пор, пока одна из строк не будет содержать «.».

Когда у нас есть все строки, мы перебираем каждую из них и создаем массив символов. Для каждого символа в массиве мы используем Character#toLowerCase, чтобы убедиться, что каждый используемый символ находится в нижнем регистре.

Затем мы используем метод index(character), чтобы определить, по какому индексу в массиве находится символ. Если оно отрицательное или превышает 25, мы просто пропускаем его, так как это не буква. Мы могли бы использовать Character.isLetter, но это не обязательно. Затем мы увеличиваем значение индекса в массиве относительно индекса, который мы вычислили.

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

   public static void main(String[] args) {
        System.out.println("Welcome to the Letter Count program.");
        System.out.println("Please enter some lines of text followed by a period and a return.");

        List<String> input = requestInput(new Scanner(System.in), new ArrayList<>());

        int[] occurrences = occurrences(input);

        int indexOfA = 'a';

        int indexOfZ = 'z';

        for (int letter = 'a'; letter <= indexOfZ; letter++) {
            int index = letter - indexOfA;

            int occurrencesOfLetter = occurrences[index];

            if (occurrencesOfLetter == 0) {
                continue;
            }
            System.out.println(String.format("%s: %s", (char) letter, occurrencesOfLetter));
        }
    }

    private static List<String> requestInput(Scanner scanner, List<String> input) {
        String line = scanner.nextLine();

        input.add(line);

        if (line.contains(".")) {
            return input;
        }

        return requestInput(scanner, input);
    }

    private static int[] occurrences(List<String> input) {
        int[] occurrences = new int[26];

        for (String line : input) {
            int[] occurrencesInLine = occurrences(line);

            for (int index = 0; index < occurrencesInLine.length; index++) {
                occurrences[index] += occurrencesInLine[index];
            }
        }
        return occurrences;
    }

    private static int[] occurrences(String line) {
        int[] occurrences = new int[26];

        char[] chars = line.toCharArray();

        for (char character : chars) {
            char characterLowercase = Character.toLowerCase(character);

            int index = index(characterLowercase);

            if (index < 0 || index > occurrences.length - 1) {
                continue;
            }
            occurrences[index]++;
        }
        return occurrences;
    }

    private static int index(char character) {
        return character - 'a';
    }
person Jason    schedule 29.03.2020
comment
Большое спасибо! Вы показали мне, как обнаружить часового периода. - person Quang; 30.03.2020

Две основные ошибки:

  1. вы увеличиваете i дважды: один раз в цикле и снова внутри цикла с i++, поэтому вы считаете только a, c, e и т. д.
  2. вы обрабатываете только первую строку ввода; добавить внешний цикл, который зацикливается на сканере

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

person Bohemian♦    schedule 29.03.2020

Только для удовольствия... решение реактивного потока:

    Flowable<Character> flowable = Flowable.generate( emitter -> {

        // Assuming ASCII:
        char c = (char)System.in.read();

        if ( c == '.' ) {
            emitter.onComplete();
        }
        else if ( Character.isLetter( c )) {
            emitter.onNext( c );
        }
    } );

    flowable.groupBy( Character::toUpperCase )
        .concatMapSingle( group -> group.count()
                .map( count -> String.format( "%s:%d ", group.getKey(), count )))
        .sorted()
        .blockingSubscribe( System.out::print );

Выход:

Four scrore
etc etc.
C:3 E:3 F:1 O:2 R:3 S:1 T:2 U:1 
person TrogDor    schedule 29.03.2020

Привет WJS и всем! Я исправил программу для дополнительного i++, и она, кажется, работает, но у меня все еще есть проблемы с "." часовой. Вот как это выглядит сейчас.

import java.util.Scanner ;
/**
 *      The Letter Counter program counts the frequency of the letters of the 
 * alphabet in some lines of text.  After a period and a return, the computer
 * displays the frequency.
 *
 * @author Quang Pham
 * @version Module 8, Homework Project 2, 4/1/20
 * 
 *    Algorithm:
 *    
 *    1. User enters multiple lines of text.
 *    2. The program will read in the lines of text and display a list of all the 
 *       letters that occur in the text, with the number of times the letter occurs.
 *    3. The last line of input should be ended with a period, which serves as a 
 *       sentinel value.
 *    
 *    Problem description:
 *    
 *         Write a program that will read in multiple lines of text from the user 
 *    and display a list of all the letters that occur in the text, along with the 
 *    number of times each letter occurs.
 *
 *         The last line of input from the user should end with a period, which 
 *    will serve as a sentinel value.  Once the last line has been entered, the 
 *    counts for all letters entered by the user should be listed in alphabetical 
 *    order as they are output.  Use an array of base type int of length 28, so 
 *    that each indexed variable contains the count of how many letters there are.
 *    Array indexed variable 0 contains the number of a’s, array indexed variable
 *    1 contains the number of b’s and so forth.  Allow both uppercase and 
 *    lowercase letters as input, but treat uppercase and lowercase versions of
 *    the same letter as being equal.
 *
 *    Hints: You might find it helpful to define a "helper" method that takes a 
 *    character as an argument and returns an int value that is the correct index 
 *    for that character, such as ‘a’ returning 0, ‘b’ returning 1, and so forth.
 *    Note that you can use a typecast to change a char to an int, like (int) 
 *    letter.  This will not get the number you want, but if you subtract (int)
 *    'a', you will then have the right index.  Allow the user to repeat this
 *    task until the user says she or he is finished.
 *
 *    A dialog may look something like the following
 *
 *    Enter several lines of text to analyze. (Copy and paste to save time.)  When
 *    done, end a line with a period and press return.
 *    1: Four score and seven years ago our forefathers 
 *    2: brought forth upon this continent a new nation, 
 *    3: conceived in liberty, and dedicated to the  
 *    4: proposition that all men are created equal.
 *
 *    Here's the counts of characters:
 *    a: 13
 *    b: 2
 *    c: 6
 *    d: 7
 *    e: 19
 *    f: 4
 *    g: 2
 *    h: 6
 *    i: 9
 *    l: 4
 *    m: 1
 *    n: 14
 *    o: 15
 *    p: 3
 *    q: 1
 *    r: 12
 *    s: 6
 *    t: 15
 *    u: 5
 *    v: 2
 *    w: 1
 *    y: 2
 *    
 *    JFK's inaugural quotation:  “And so, my fellow Americans: ask not what your
 *    country can do for you – ask what you can do for your country.” 
 *    
 *    MLK's Washington speech:  I have a dream that one day this nation will rise up and 
 *    live out the true meaning of its creed: “We hold these truths to be 
 *    self-evident, that all men are created equal.” 
 *
 *         Again, you can submit a single class for this project which contains your
 *    main method and any helper methods where you feel they can be used.
 *
 *    Along with the file containing your program, submit three print screens or 
 *    screen snips, each with several lines of text entered by the user, and the 
 *    count for each character (a-z).
 */
public class LetterCounter
{
    public static void main(String[] args) {
        int frequency = 0 ;
        char character = ' ' ;
        String linesOfText = " " ;
        int letterTotal = 0 ;

        char[] alphabet = new char[26] ; // new alphabet array        
        for(char ch = 'a'; ch <= 'z'; ++ch)// fills alphabet array with the alphabet
        {
            alphabet[ch-'a']=ch ;
        } 

        System.out.println("Welcome to the Letter Count program.") ; 
        System.out.println("Please enter some lines of text followed by a period and a return.") ;
        Scanner keyboard = new Scanner(System.in) ;
        linesOfText = keyboard.nextLine() ;

        System.out.println("Letter          Frequency") ;
        for (int i = 0; i < alphabet.length; i++) 
        {   frequency = 0 ;
            for (int j = 0; j < linesOfText.length(); j++) {
                character = linesOfText.charAt(j) ;
                if (character == alphabet[i]) {
                    frequency++ ;
                }
            }
            System.out.println(alphabet[i] + "\t\t" + frequency) ;
            letterTotal += frequency ;
        }
        System.out.println("Total number of letters:  " + letterTotal + ".") ;

        if (linesOfText.equals(".")) //Period sentinel is detected
        {
            System.out.println("Entry finished.") ;
            System.exit(0) ;
        }
    }
}
person Quang    schedule 29.03.2020