Win a copy of Building Blockchain Apps this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Liutauras Vilda
  • Knute Snortum
  • Bear Bibeault
Sheriffs:
  • Devaka Cooray
  • Jeanne Boyarsky
  • Junilu Lacar
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • salvin francis
Bartenders:
  • Tim Holloway
  • Piet Souris
  • Frits Walraven

Need assistance converting Pseudocode for a method into code

 
Ranch Hand
Posts: 52
1
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am currently trying to create a method to output a bar chart of * symbols to visually demonstrate the number of times a given word appears in a string. I.E. one extra asterisk for each time the word appears in the given string.

I have already coded a method using a hashmap to output the frequency of each word, like so:

hello world hello world hello world
This string contains 2 distinct words:
{world=3, hello=3}



As an example, I now want to output the following:

hello : ***
world: ***


I have written some pseudocode for this bar chart but don't know how to actually convert it into code:

/* public static String [][] barChart (map wordFrequencies){
       Map <String, String> barChart = new HashMap <String, String> ();
       for (String : wordFrequencies){
           while (length of barChart string < int (wordFrequencies)){
               barChart string = barChart string + "*";
           barChart String
           }
       }

       return barChart;
   }

   */


This is the working code for the wordFrequencies method (there are some bits that aren't relevant to wordFrequencies):


 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:Does it work correctly? Do you have a specific question?



My question is how to use the hashmap I created for wordFrequencies, which currently outputs {world=3, hello=3} , as an example, and create a method for outputting a "bar chart" of asterisks for the number of times each word appears in the string. The code
I have included does what it is supposed to at the moment. I have written some pseudocode as explained above for the barChart method but don't know how to cycle through each item in the hashmap and use it to create a new hashmap with asterisks inside it.

The final output for "hello world hello world hello world. this is me" should be something like:

hello: ***
world: ***
this: *
is: *
me *



I hope that is clear enough.
 
Carey Brown
Saloon Keeper
Posts: 6937
65
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Not sure why you'd want to return an array of arrays. If you want to hold the word and the plot, then I'd create a very small class that could hold those two things and create a list of them. A list of a simple string that contains both the word and plot would look something like this.


 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've had a think and I'm going to try and implement it within the method without returning anything, just because its easier to write for me at the moment.

The only error I'm getting now is with the variable frequency, which is where I'm trying to use the integers from the hashmap. Should I be using a different method to .keySet? This is the error I'm getting:

Type mismatch: cannot convert from element type String to int



on line 5 below

 
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why have you nested the two loops?
You are trying to get the frequencies out of the key set; surely you mean value set?
 
Bartender
Posts: 3776
154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Line 5 (and 5 and a half) should be:




Edit: I did not see your new code below, so this might not be relevant anymore.
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Why have you nested the two loops?
You are trying to get the frequencies out of the key set; surely you mean value set?



I have taken the second for loop out of the first for loop and used .values instead of .keySet . The output still doesn't look right:

the|
over|
quick|
lazy|
jumped|
brown|
dog|
fox|
*
*




Updated code:

 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:Line 5 (and 5 and a half) should be:




Edit: I did not see your new code below, so this might not be relevant anymore.



Sorry didn't see comment. Will try this.

UPDATE: This worked. Thank you
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Charles Ormond wrote:. . . The output still doesn't look right: . . .

Stop guessing and plan what you are going to do. You can make 1,000,000 guesses and some of them will be correct, but you want your code to work first time.
What you are doing wrong is by (still) having two loops, but you have dissociated the frequency counts from the words. Many words. Each one has a frequency. For that frequency, print a number of *s. That should let you work out which loop goes where. Piet has already told you what that looks like.
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another way to do it is, rather than having Integers as the “V”s in your Map, use Strings. Rather than incrementing the numbers, add a * to the appropriate String “V”.
 
Piet Souris
Bartender
Posts: 3776
154
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A frequencymap is shorter and more flexible. In java 11 you have a nice method:

With this, you can shorten OP's code to:


 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had forgotten about the repeat() method; that looks very useful in this instance.
 
Sheriff
Posts: 15043
252
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:
With this, you can shorten OP's code to:


Nice. I'd keep OP's name though:
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Piet Souris wrote:
With this, you can shorten OP's code to:


Nice. I'd keep OP's name though:




I've just tried this and am getting the error

The method repeat(Integer) is undefined for the type String

on the .repeat(count) method.

Why is count being considered as a string and not as an Integer?
 
Rancher
Posts: 4493
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
repeat() is Java 11 (I think).
So if you're on an earlier version then that would explain why you don't have it.

And the String in question in the error is "*".  That object does not have a repeat method.
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:repeat() is Java 11 (I think).
So if you're on an earlier version then that would explain why you don't have it.

And the String in question in the error is "*".  That object does not have a repeat method.



Don't think my version of Java is the problem as I am using the latest Java plugin for Visual Studio. Any workaround to using the repeat method then?
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Charles Ormond wrote:. . . I am using the latest Java plugin for Visual Studio. . . .

Find out how you can verify the version, please.
My suggestion of adding *s to a pre‑existing String (or using its concat() method) might help.
 
Junilu Lacar
Sheriff
Posts: 15043
252
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you're using an earlier version of Java (< 11) there are lots of ways to implement repeat.

I rather liked this one for Java 8:

 
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

One last thing I wanted to do with this hashmap code is to line up the words in the star chart so that they are all the same length. For example, if the user inputs "a hello hello world message", the output should look like

          a | *
     hello | * *
     world| *
message | *


I have tried to do this by creating a loop to check each word against longestWord, and add spaces at the start of the string until it is the same length as the longest word. The program runs but it isn't actually affecting the output at all. This is my loop, could you see what might be wrong with it?

 
Marshal
Posts: 6869
182
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It looks like the while-loop is inside the for-loop.  Why is that?
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:It looks like the while-loop is inside the for-loop.  Why is that?



Because otherwise word cannot be resolved to a variable, as it is defined with the for loop.
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've tried moving it out of the for loop but Java does not like my while loop Syntax at all:

 
Carey Brown
Saloon Keeper
Posts: 6937
65
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Instead of keeping track of which word is the longest, keep track of maxLength. You don't really need to know which word it is, only the length.

The compiler complains because that is not valid while()  loop syntax. It's a smashup of the enhanced for() loop which uses a semicolon. No such usage in while().
 
Carey Brown
Saloon Keeper
Posts: 6937
65
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To borrow Junilu's example:
You might even want to try this
 
Carey Brown
Saloon Keeper
Posts: 6937
65
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want the words to appear in sorted order you could replace HashMap with a TreeMap.
 
Charles Ormond
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:To borrow Junilu's example:
You might even want to try this



Sorry, I'm a bit confused about where you think I should put this line. I have changed longestWord to an int of maxLength.

 
Piet Souris
Bartender
Posts: 3776
154
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A tad simpler may be to define a format string, something like:

right after you determined the maxLength, and then print the output with System.out.format(format, word, nrOfStars).
 
Master Rancher
Posts: 259
13
Eclipse IDE C++ Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i gave you a cow piet, because i didn't know you can do formatting like this.
i thought you can only do formatting with printf.
 
Carey Brown
Saloon Keeper
Posts: 6937
65
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

S Fox wrote:i gave you a cow piet, because i didn't know you can do formatting like this.
i thought you can only do formatting with printf.


format(...) was actually the original method name but so many people were used to the C/C++ name of printf that they made a printf(...) method identical to format(...).
 
Knute Snortum
Marshal
Posts: 6869
182
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Charles Ormond wrote:


In order to find the maxLength, you have to loop through all the words.  Then you have to loop through them again to print them.  Right now you have the while-loop inside the loop to calculate the maxLength.  
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Charles Ormond wrote:. . . Because otherwise word cannot be resolved to a variable, as it is defined with the for loop.

Don't make your program structure fit the compiler errors. If you need a variable to have wider scope, give it wider scope.

I would have put a loop to count the *s inside the loop to find the frequencies.

It is often possible to obviate the need for loops with a Stream, but you still need to know how to write a loop.
 
Junilu Lacar
Sheriff
Posts: 15043
252
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet's answer already had a format String that did that for you. System.out.format("%-20s | %s%n", word, ...) will right left justify the word in a 20-character wide field. You can adjust that number as you like or build the format String with a calculated value.
 
Ranch Hand
Posts: 92
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have used your question for my own learning. I have split the code into two classes - WordCounter to give you a count of words in some text and a BarChart which will print word counts or counts of any object besides words.

As an aside, I have developed the WordCounter with TDD or test driven development. Its a weak attempt since I am new to TDD and I rarely practice it. You can see the tests which I have written to test my WordCounter. They also describe the features of the word counter, i.e. what it can do and can't do. Don't worry about the strange code in the tests. If you try to read them like they were plain english, then you might understand what I am trying to test. But, that is optional and I will share it in the next post.






Output : (a bit messed up, perhaps due to this website's formatter.)


one        : *
infinity    : *
three      : ***
two        : **


 
Tom Joe
Ranch Hand
Posts: 92
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The tests for WordCounter class. You can ignore these if it is too much for you.



Some more tests that occurred to me too late :
You can update the word counter to make these tests pass as an exercise. Keep only one failing test, make it pass. Then, add other failing test, make it pass. Repeat until all tests pass.


 
Knute Snortum
Marshal
Posts: 6869
182
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your contribution, Tom Joe.  Just a reminder that in the Beginning Java forum, we typically don't post complete solutions until the OP has posted theirs.  This gives the OP a chance to learn for themselves from the suggestions made.
 
Tom Joe
Ranch Hand
Posts: 92
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:Thanks for your contribution, Tom Joe.  Just a reminder that in the Beginning Java forum, we typically don't post complete solutions until the OP has posted theirs.  This gives the OP a chance to learn for themselves from the suggestions made.



Noted. I'll keep that in mind for future answers. Hopefully, this answer will show the OP a bit more than what they teach in most courses/books. I wish I had this many years ago, when I was struggling

PS - I am still struggling
 
What's wrong? Where are you going? Stop! Read this tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!