• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help with a Programming assignment  RSS feed

 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!
I'm fairly new to java I'm taking a beginner online course and I'm stuck on an assignment. Frankly, I have no idea what to do and how to solve it. Any help would be appreciated.

BTW: The section related to this is the basics of java strings

Write a program that prompts the user to input a string of words, then counts and displays the number of times each letter in the alphabet appears in the string. It is not necessary to distinguish between uppercase and lowercase letters. Your output should be formatted as follows:
Letter A count = xx
Letter B count = xx

....
Letter Z count = xx
 
Paul Ngom
Ranch Hand
Posts: 355
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Deron,
Start by a basic program that accepts a
user input and you could develop from
there. Post what you have written. You
could use the Scanner class for that.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

We do not give out complete solutions; what we will happily do however is have a look at your attempt and help you learn from it and improve it.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Ngom wrote: . . . You could use the Scanner class for that.
I think we may be at too early a stage even to suggest things like Scanner.
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the program I know how to have the user type in a word but the problem is how I would count the occurrences of each letter in the word and display it.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deron Brown wrote:For the program I know how to have the user type in a word but the problem is how I would count the occurrences of each letter in the word and display it.

There is a method in the String class for getting a char at a specific location. You will need a for loop to iterate through the String to get each character.
For the moment, just try creating a for loop that prints out each character of the String on a new line.
If you have any problems, post the code (UseCodeTags) and tell us precisely what the problem is.
Once you've got that working we can look at how to count the characters.
 
Paul Ngom
Ranch Hand
Posts: 355
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deron,
After you have saved you input in a String
variable. One way to solve your problem
is to use .split method on the string so as
to save it in an array. You could then scan
the array and count the occurences of the
various letters of the alphabet. You can
save the alphabet letters in a two dimensional
array with a column for the letters and
another for the counts.
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Is this the right way to save the input in a string variable?
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
did it work? One of the greatest things about programming is you can just try stuff and see.

Note: I would generally not write this much code before compiling and testing. I'd write one line, and then maybe another to test it. I'd start with just this:


of course, I'd need the rest of the code to wrap up the main method, but seriously...write as little as possible before you compile and re-test.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deron Brown wrote:char a = Input.getChar("Please type in a word");

Why are you asking for a word but only reading in a single character ?
I don't know what the type of your Input variabe is, but doesn't it have a method for reading a whole word or even a whole line ?
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Ngom wrote:use .split method on the string so as
to save it in an array. You could then scan
the array

Wouldn't it be easier to just iterate over the String and ignore the non alphabetic characters.
If you use split you will have to have a regex to split on non-alphabetic characters which introduces another complexity.

Paul Ngom wrote:You can
save the alphabet letters in a two dimensional
array with a column for the letters and
another for the counts.

Or use a single dimension int array and calculate the index of the element to increment using the character value.
 
Paul Ngom
Ranch Hand
Posts: 355
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Or use a single dimension int array and calculate the index of the element to increment using the character value.

The letters run from A to Z.

Letter A count = xx
Letter B count = xx

....
Letter Z count = xx

I think he will then need another single dimension array to keep the 26 alphabet letters.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Ngom wrote:

Or use a single dimension int array and calculate the index of the element to increment using the character value.

The letters run from A to Z.

That's why I said calculate the index.
'A' - 'A' = 0
'B' - 'A' = 1
'C' - 'A' = 2
'D' - 'A' = 3
'E' - 'A' = 4
etc
 
Paul Ngom
Ranch Hand
Posts: 355
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

That's why I said calculate the index.
'A' - 'A' = 0
'B' - 'A' = 1
'C' - 'A' = 2
'D' - 'A' = 3
'E' - 'A' = 4
etc

I still do not get your point and i don't know how you will get the output that Deron provided in his first post. But i hope he understands you.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are (at least) three parts to this program:

1) getting the input from the user
2) processing a string to get the information we care about
3) outputting the information in the format desired.

Joanne was giving a hint on part 2 only. Read the string, character by character. Use an int array with 26 elements. If you find an 'A', then increment the value in the 0th position. If you find a 'B', increment the value in the 1st position...up to finding a 'Z', and incrementing the value in the 25th position. If you find a non-alphabetic, ignore it.

and of course, we need to account somehow for 'A' and 'a', etc.

Once you have the data, you can worry about getting the output as desired.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As every programming task, this is a simple matter of getting the data input, processing it and outputting the information required...

Problems like these are made simple by forgetting about programming language and focusing on how can it be done... or you can know what language you are going to implement the solution to your problem with and translate as you go along...

Example:
- I know I have to get a line of text from the user, count each occurrence of a letter and print the information... hmmmmm
- I will need to store the text to process it so I will need a string variable and store the information in there -> String text;
- What class can I use to get input from the user... I'll check the API docs or try a google search... ooo I can do this -> System.console().readLine("Enter a line of text: ");

Following along with this logical thought process you will seamlessly solve your problem...

Since you are going to be dealing with a lot of characters the Character class will be of much value in this situation... check it out
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok thanks for all of your help! but my problem is that right now when the user types in a word, only the first letter is saved because when I display it only the first letter is shown
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In order to help you pinpoint the error you will need to post a snippet of the code you are working with...
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nevermind I've solved it by having the user enter in a string not a variable of type char. This is what I've got so far
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was told that a very simple solution that I could use to solve this problem would be " Use "for" loops to go thru each character of str and compare it to
letter 'a' to letter 'z', you need if-else if-...else structure to do this. For each "if" case, you could count the letter." Though much more work I feel that with my experience it might just be it
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What if I told you that you only need one if statement to solve your problem by using the Character class...

You got an array of 26 int slots to keep a running count of letter occurrences...
You loop through the input string and test each character checking if its a letter... if(here is the one if) its a letter increment the correct slot in the array
Print the information after the loop statement
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:What if I told you that you only need one if statement to solve your problem by using the Character class...

You got an array of 26 int slots to keep a running count of letter occurrences...
You loop through the input string and test each character checking if its a letter... if(here is the one if) its a letter increment the correct slot in the array
Print the information after the loop statement


That sounds great but any way you could like "dumb this down"
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its like putting pieces of puzzles together... The String class has a method charAt(int) that return a char... The Character class has a method isLetter(char) that return boolean...

Put these to classes to collaborate and you get:


This is done to eliminate a slew of if-else branches and to make sure its a letter and not a digit
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:Its like putting pieces of puzzles together... The String class has a method charAt(int) that return a char... The Character class has a method isLetter(char) that return boolean...

Put these to classes to collaborate and you get:


This is done to eliminate a slew of if-else branches and to make sure its a letter and not a digit


Thanks! but how does this differentiate between different letter and increment accordingly?
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you take into consideration that a character (char) is really an integer encoded within a character set to represent characters then it will become clear... take for instance the character 'a' has the integer value of 97...

With this information it can be seen that if you perform the expression 'a' - 'a' you will get 0 since it will be promoted to type int in the expression... therefore array['a' - 'a']++ == array[0]++
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:If you take into consideration that a character (char) is really an integer encoded within a character set to represent characters then it will become clear... take for instance the character 'a' has the integer value of 97...

With this information it can be seen that if you perform the expression 'a' - 'a' you will get 0 since it will be promoted to type int in the expression... therefore array['a' - 'a']++ == array[0]++


So I've attempted like a combination of this and the long method and this is how it turned out so far but the string.charAt is preventing it from compiling and I can't figure out why.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are getting an error because you are suppose to call the charAt(int) method on str and not string as string was not declared in your code
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well I changed it to str but it still doesn't compile
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey pal, I'm heading out so I can no longer assist you at this present time... I'm sure someone else will come to your aid...

Also you are comparing incomparable types... you cannot compare a char with a string -> if (string.charAt(ab) == "a")
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome again.
No. Don't use ifs. You woiuld end up with dreadful repeated code: twenty‑six lots of it.
Move most of that code out of the main method. You will start You will obviously have to write a LetterCount class. This is a hint for a start:-I think you were using an int[] as counts. The print statements are only there to confirm you have reached the methods successfully and you can delete them once you get the app working.

Now stop guessing and do things bit by bit. Go through the word letter by letter and print out the individual letters. Get it to read CAMPBELL and print
C
A
M
P
B
E
L
L
Once you do that you know that you can get at the indiviudal letters and print them. Don't try counting until you have bit working. When you have go that far ask again.

By the way: you should but the [/code] part of the code tags after the code. I have corrected it in your posts to date.
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks you guys for all of your suggestions but I went with Rico Felix's method and this is what I got so far. The if line that he told me to put in is preventing the whole thing from compiling I'm not really sure why. Can someone critique this.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey pal, I'm back at ya... I see that you have done a great deal of figuring out the technique for reducing the slew of if-else constructs

However your code will never compile if you use an identifier that was not declared in your code so, if (Character.isLetter(string.charAt(k)) will not work because string is the culprit... its suppose to be str

Another mistake that you are making is differentiating between character and string literals... a character is enclosed in single quotes 'a' while a string is within double quotes "a", they a not the same... you cannot minus a string from a string...

To clear up now... the idea is that a character when used in an expression, is promoted to type int so you can perform arithmetic on them... since there are 26 letters in our alphabet the logic is simple which is to transform the character to either capital or common case and minus to end up in the correct index within the array to increment...

If we know that 'a' = 97 then if the character was 'B' which is equal to 66, transform it to 'b' which will be equal to 98 and subtract it from 'a' to end up in index 1 and so forth for each letter found...

Or you can go the other was around knowing that 'A' = 65 then if the character was 'c' which is equal to 99 transform it to 'C' which will be equal to 67 and subtract it from 'A' to end up in index 3 since (67 - 65 = 3) == ('C' - 'A' = 3)
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:Hey pal, I'm back at ya... I see that you have done a great deal of figuring out the technique for reducing the slew of if-else constructs

However your code will never compile if you use an identifier that was not declared in your code so, if (Character.isLetter(string.charAt(k)) will not work because string is the culprit... its suppose to be str

Another mistake that you are making is differentiating between character and string literals... a character is enclosed in single quotes 'a' while a string is within double quotes "a", they a not the same... you cannot minus a string from a string...

To clear up now... the idea is that a character when used in an expression, is promoted to type int so you can perform arithmetic on them... since there are 26 letters in our alphabet the logic is simple which is to transform the character to either capital or common case and minus to end up in the correct index within the array to increment...

If we know that 'a' = 97 then if the character was 'B' which is equal to 66, transform it to 'b' which will be equal to 98 and subtract it from 'a' to end up in index 1 and so forth for each letter found...

Or you can go the other was around knowing that 'A' = 65 then if the character was 'c' which is equal to 99 transform it to 'C' which will be equal to 67 and subtract it from 'A' to end up in index 3 since (67 - 65 = 3) == ('C' - 'A' = 3)


So I've made the changes you suggested but the if line is still preventing it from compiling I'll put a screenshot of the error message and code
Problem.png
[Thumbnail for Problem.png]
The Error message and code
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One important skill you must also acquire while programming is understanding the compilers error messages... what it says is that there are unmatched parentheses in your code... you need to add another ) to close the if statement condition
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:One important skill you must also acquire while programming is understanding the compilers error messages... what it says is that there are unmatched parentheses in your code... you need to add another ) to close the if statement condition


Thanks I've got it compiling but when I run it and input a word containing only the two letters I've put in to test it, it doesn't work.
Problem.png
[Thumbnail for Problem.png]
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've deliberately left you to run it to see the error message... what you are seeing is array access error... the expression that you have placed for the subscript is working out to a negative number since 'a' = 67 and 'k' = 107 if you do the maths that is equal to -10 which is an unacceptable subscript for an array
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rico Felix wrote:I've deliberately left you to run it to see the error message... what you are seeing is array access error... the expression that you have placed for the subscript is working out to a negative number since 'a' = 67 and 'k' = 107 if you do the maths that is equal to -10 which is an unacceptable subscript for an array


Wait I thought that K is the letter at that specific part of the string because of if (Character.isLetter(str.charAt(k)))
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Find out about the % operator.
Look at the letters in ASCII as in this Unicode Chart. Note the last digit in the numbers for A a B b etc etc.
Work out what will happen if you use % 0x20. I chose that particular ASCII chart because it uses hex numbers and the last digits show a pattern, which is not obvious in decimal. 0x20 is 32 in decimal.

If you get that to work it will work beautifully for ASCII letters (English only) and you will get horrible errors for things like ß in German or é in French. Also note you will get A=1 and a=1 up to Z=26 z=26 and those numbers are 1 too high for a 26‑element array so you will need a − 1 somewhere.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you take the time to read the thread carefully you would not be making such silly assumptions...

If you look at a string internally lets use "Java"... its represented by a character array so it translates to the following:

['J'] ['a'] ['v'] ['a']
-0 ---1---2---3

What you do when you invoke charAt(int) on a string object is ask for a character at the index given... so if I say "Java".charAt(1) it will give me the character 'a' since its at index 1

Now look at your code and take into consideration that you are performing the invocations within a loop using the variable k as an index... Re-read the thread with the guidelines giving and I'm sure you'll approach the problem more logically achieving the results you're working for
 
Deron Brown
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've tried switching it up but in an hour I've accomplished next to nothing
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!