Reputation: 15
I tried this program but it only printed out the frequency of some letters. Could someone tell my what I did wrong? Any help would be greatly appreciated. Yours truly, Quang Pham
This is what I got in a run of the program. Welcome to the Letter Count program. Please enter some lines of text followed by a period and a return. It takes a some time to compute. . . * 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. Letter Frequency 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++;
}
}
}
Upvotes: 1
Views: 10676
Reputation: 15
Hi WJS and everybody! I fixed the program for the extra i++ and it seems to work, but I still have difficulty with the "." sentinel. This is how it looks now.
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) ;
}
}
}
Upvotes: 0
Reputation: 1029
Only for fun... the reactive stream solution:
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 );
Output:
Four scrore
etc etc.
C:3 E:3 F:1 O:2 R:3 S:1 T:2 U:1
Upvotes: 0
Reputation: 424983
Two basic mistakes:
i
twice: once in the loop, and again inside the loop with i++
, so you’re only counting a, c, e, etcYou may be interested to know you can do all counting, and even printing of results, in one line.
Upvotes: 0
Reputation: 40034
You asked what you did wrong. Well you are very close and you only did two things incorrectly.
char[] alphabet = new char[28]
should be 26. 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++;
}
In the first loop you increment i using i++
But you also increment it at the end after the print statement. The last one should be
removed.
Instead of searching for your character inside an inner loop, just use the character to index into your list and bump the count. For example:
int count[] = new int[26];
say an you find the letter c =='i'.
count[c - 'a']++; ///increments the count for letter i.
Upvotes: 0
Reputation: 5246
I understand this is your homework but here is a solution that was created from the ground up.
We have a method called requestInput that takes a Scanner object and a List of Strings and will keep requesting input until one of the lines contains ".".
Once we have all lines, we then iterate through each one of them and create a character array. For each character in the array we use Character#toLowerCase to ensure that every character we use is lowercase.
We then use the index(character) method to determine at what index in the array the character exists. If its negative or exceeds 25 we simply skip since it's a non-letter. We could use Character.isLetter but it's not necessary. We then increment the value at the index in the array relative to the index we calculated.
After that we use a simple for-loop to get every character in the alphabet and print the occurrences of each character.
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';
}
Upvotes: 0
Reputation: 7104
you are incrementing in your for loop parameters and at the end of the loop which is skipping letters
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++;
}
Upvotes: 1