• Post Reply Bookmark Topic Watch Topic
  • New Topic

Java Histogram Exercise  RSS feed

 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Write a method called  letterHist  that takes a string as a parameter and returns a histogram of the letters in the string. The zeroth element of the histogram should contain the number of a’s in the string (upper- and lowercase); the 25th element should contain the number of z’s. Your solution should only traverse the string once.
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sounds fun! What have you got so far? What part are you having trouble with?
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!
I've got this from a Java exercising book.
I tried utilizing the for loop to iterate to the integer array, but to iterate through every character I'm not sure what string method to chose that would traverse the string only once (string.charAt(i) or string.indexOf('letter', index)
Any suggestions?
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider that a String is just a character array and explore the String API to see if there's a way to get the char array for a given String. Then you would be able to iterate over that with a for loop.

Then consider from a particular character how you would determine the index of the target array to work with. (Hint: Each character has a numerical representation in the ascii table. In fact, a Java char is a Java int)

Then consider how you would maintain a count of each occurrence of each character.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Take note of Tim's hint about a char being a number; that means you can do arithmetic with it.
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you all for your help!
I've done it.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well done Do show us what you have got.
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dinu Claudiu wrote:Your solution should only traverse the string once.

Have a closer look at your solution. How many times you are traversing the String?
 
Norm Radder
Rancher
Posts: 2240
28
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another thing to check:  The English alphabet has 26 letters.  Your array has 25 slots.  Does your code work with the String: "aaabcxyzzz"?

Also the array index can be computed directly from a char:  theIndex = theChar - 'a';  // for lowercase letters
if theChar = 'a' the index is 0.  If theChar is 'b' the index is 1, etc
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah yes, good spot Norm.
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, my bad I was looking at the problem and saw that the 25th element should contain the number of z’s and with indexing starting from 0 it would be something like that, but you're right about that.
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you check how many times you are traversing the input String? Spoiler alert: It's more than once.

Can you see why?
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes, everytime the findletter method is invoked, so  should I iterate through the string in the histletter method then check for the letters?
 
Carey Brown
Saloon Keeper
Posts: 3323
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Modify histLetter() to something like this
No need for a 'count' variable, you can use the 'hist' array for that.
 
Dinu Claudiu
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Where can i put the string characters into so that I can access them in the histLetter?
 
Tim Cooke
Marshal
Posts: 4047
239
Clojure IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You don't need to put the string characters anywhere.

By default an int initialises to 0, so new int[26] creates an array of 26 zeros. Iterate through the String and increment the corresponding array index.

In essence, what Carey said.
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't directly go for final solution. Go step by step so you can trace what exactly being achieved. You can do this only in a method by just iterating String only once. Only have to deal with ASCII of each char of String.
Steps IMO
  • First write a simple method which extracts all character from String into char array and print appropriate message what they are capital letter or small letter or special character(user may enter special char so must check).
  • As you said char is 'A' or 'a'  considered same so use ascii values to convert them either in capital or small letter's ascii and print them to see you succeed or not.
  • Now what? think how would you relate incrementing the value of 0th, 1st .. 25th  index of array according to ascii as you have already been asked to do
  •  
    Campbell Ritchie
    Marshal
    Posts: 56546
    172
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Don't use the integer literals 65 and 97; those are error‑prone. Use 'A' and 'a' instead.
    You can reduce both capital letters and small letters to 'A'=1, 'a'=1, 'Z'=26 and 'z'=26 with a simple arithmetical trick, and then subtract 1 to get to the array index. That trick, unfortunately, probably only works for English text and will probably go wrong with letters like é, ß, or ç.
     
    Ganish Patil
    Ranch Hand
    Posts: 529
    19
    Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:Don't use the integer literals 65 and 97; those are error‑prone.
    would you please explain little more how? because I did this program & I also used integer literals in it 65 97 etc.
    That trick, unfortunately, probably only works for English text and will probably go wrong with letters like é, ß, or ç.
    For that we can check whether character is between 'A' to 'Z' or 'a' to 'z' then go for increment code else skip that special character and go for next character.What do you say? I did that in my program & entered those characters & it works fine.
     
    Tim Cooke
    Marshal
    Posts: 4047
    239
    Clojure IntelliJ IDE Java
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It's down to the fact that a Java char is a Java int. For example:

    yields
     
    Campbell Ritchie
    Marshal
    Posts: 56546
    172
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganish Patil wrote:. . . would you please explain little more how? because I did this program & I also used integer literals in it 65 97 etc.
    But one day you will write 67 and 95 or 64 and 96.
    c - 'a'
    etc.
    . . . For that we can check whether character is between 'A' to 'Z' or 'a' to 'z' then go for increment code . . .
    One of those letters is in common use in French: look here, and you find
    ç or ç
        small c, cedilla (ç or ç)
    The number 231 is 7 × 32 + 7, so what are you going to do with it? Ignore it and have François called Franois? Use it with % 32 and get 7 and put it in the same category as g/G? É would go in the same category as I. You can create a lookup table with a Map or a switch, but that is going to take much longer than this exercise merits. Simpler to stick to English text which does not usually have any diacritics.
     
    Ganish Patil
    Ranch Hand
    Posts: 529
    19
    Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:But one day you will write 67 and 95 or 64 and 96.
    Haha yes you're correct, changed my code.
    The number 231 is 7 × 32 + 7, so what are you going to do with it? Ignore it and have François called Franois? Use it with % 32 and get 7 and put it in the same category as g/G? É would go in the same category as I. You can create a lookup table with a Map or a switch, but that is going to take much longer than this exercise merits. Simpler to stick to English text which does not usually have any diacritics.
    Ohh I see, had no notion about this, then better stick to english text.
     
    Dinu Claudiu
    Greenhorn
    Posts: 10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Can someone show me their solving of the problem? Just for orientation purpose.
     
    Norm Radder
    Rancher
    Posts: 2240
    28
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here's a solution in pseudo code:
    loop through chars in String
    get next char
    convert char to array index;  For example:   theIndex = theChar - 'a'; // for lowercase characters
    add one to array element at index
    end loop
     
    Carey Brown
    Saloon Keeper
    Posts: 3323
    46
    Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I think you already have the various pieces in the responses.

    The Pseudo code

    the actual code

    The pseudo code needs some more details
     
    Dinu Claudiu
    Greenhorn
    Posts: 10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you want to know my improved solution :
     
    Carey Brown
    Saloon Keeper
    Posts: 3323
    46
    Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Excellent !!! Well done.
    Thanks for posting your revisions.
     
    Campbell Ritchie
    Marshal
    Posts: 56546
    172
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I have my own twist on that, but it only works for the 26 letters used in English:-
    hist[letter % 0x20 - 1]++;
    Remembering that 0x20 is 32 in decimal, can you work out how that works? No if-else required.
     
    Dinu Claudiu
    Greenhorn
    Posts: 10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    well, for every value of letter increment the corresponding element with the index being the rest from dividing letter to 32,minus 1,yeah that's a very good code given the fact that good code is easy readable code, thanks a lot! 
     
    Campbell Ritchie
    Marshal
    Posts: 56546
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    That's a pleasure
     
    Consider Paul's rocket mass heater.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!