计算某些文本行中字母表中字母的出现频率

Counting the frequency of letters of the alphabet in some lines of text

我试过这个程序,但它只打印出一些字母的出现频率。有人可以告诉我我做错了什么吗?任何帮助将不胜感激。 敬上, 广范

这是我在一个运行程序中得到的。 欢迎来到信件计数程序。 请输入几行文本,然后输入句点和 return。 计算需要一些时间。 . . * 1:四二十年前,七年前,我们的祖先 * 2:在这个大陆上诞生了一个新国家, * 3:孕育于自由,并致力于 * 4:人人生而平等的主张。 字母频率 一个 13 6 19 克2 我 9 0 米1 Ø 15 问题 1 小号 6 你5 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++;
        }
    }
}

您正在递增 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++;
        }

我知道这是你的功课,但这是一个从头开始创建的解决方案。

我们有一个名为 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';
    }

你问你做错了什么。好吧,你很接近,你只做错了两件事。

  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.

两个基本错误:

  1. 你递增了 i 两次:一次在循环中,另一次在循环中 i++,所以你只计算 a、c、e 等
  2. 您只处理第一行输入;添加一个在扫描器上循环的外循环

您可能有兴趣知道您可以在一行中完成所有计数,甚至打印结果。

纯属娱乐...反应流解决方案:

    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 

大家好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) ;
        }
    }
}