Nelson
Nelson

Reputation: 65

How to count words in a Hashmap

I have pieced together this code, with a little help of course. The point of it is to take a users message and check the text file to see if any of the words in the message are also found in the text file (about 50 common English words). My problem is that I also would like to count the occurrence of each word in the message. I attempted to add an int counter but I am getting errors because I cannot count a string object with an integer. If I just add a counter into:

for (String userInput : message.split(" ")) 
{
    if (legalEnglishWords.contains(userInput)) 
    {
        System.out.println(userInput + " is an English word ");
        count++;
        System.out.println(userInput + " occurs " + counter + " times");
    }
}

I get an iteration for every word that passes the legal word test, leaving me with the output looking like

Please enter in a message: 
transformers are is is this

transformers occurs 0 times
are is an English word 
are occurs 1 times
is is an English word 
is occurs 2 times
is is an English word 
is occurs 3 times
this is an English word 
this occurs 4 times

As you can see the count is totally wrong and I display a word as many times as it occurs in the message. I would only like it to display once. I though about putting in an && to the above if statement to check if the word has already been printed, but I don't know what to put. I also do not know how to just count the individual words from the if statement, instead of counting every time the if statement is entered. So basically I need a little help counting individual words, while only displaying the "English" word once, alongside the number of times it occured at the end. I am still a bit new to java and understand all that is happening in my program and why. So if at all possible I would like to try and just augment this code to do what is necessary, instead of a total overhaul with things I potentially do not understand. Thank you all so much!

import java.io.*;
import java.util.HashSet;
import java.util.Scanner;

public class Affine_English3 
{       
        public static void main(String[] args) throws IOException
        {
              HashSet<String> legalEnglishWords = new HashSet<String>();
              Scanner file = new Scanner(new File("example.txt"));
              int counter = 0;

              while (file.hasNextLine())
              {
                  String line = file.nextLine();

                for (String word : line.split(" "))
                {
                    {
                        legalEnglishWords.add(word);
                    }
                }
              } 

                file.close();

                Scanner scan = new Scanner(System.in);
                System.out.println("Please enter in a message: ");
                String message = scan.nextLine();
                scan.close();

                for (String userInput : message.split(" ")) 
                {
                    if (legalEnglishWords.contains(userInput)) 
                    {
                        System.out.println(userInput + " is an English word ");
                        counter++;
                    }
                    System.out.println(userInput + " occurs " + counter + " times");
                }
        }
}   

This is a copy of my "Common English Word" text file

the he at but there  of was be not use and for can 
a on have all each to are from where which in by
is with line when do you his had your how that they
it i word said if this what an as or we she their

Upvotes: 2

Views: 10262

Answers (2)

sprinter
sprinter

Reputation: 27996

You are on the right path but you will need to alter the collections storing the data. If you want a count for each word then in java this requires a Map. A map maps a set of keys to a set of values - something like mapping names to ages. In your case you want to map words to counts.

So start with a map declared like:

Map<String, Integer> wordCounts = new HashMap<>();

Then each time you come across a word you can do something like:

if (!wordCounts.containsKey(word))
    wordCounts.put(word, 1);
else
    wordCounts.put(word, wordCounts.get(word) + 1);

If you are using Java 8 there is (arguably) more elegant syntax:

wordCounts.put(word, wordCount.getOrDefault(word, 0) + 1);

or

wordCounts.merge(word, 1, Integer::sum);

After you have processed all the text you can then print out the counts:

for (String word: wordCounts.keySet()) {
    System.out.println("Word " + word + " occurred " + wordCounts.get(word) + " times";
}

Upvotes: 6

Adrian Shum
Adrian Shum

Reputation: 40076

What you are trying to do is to keep track of count of each legal English word (defined in example.txt). So you need a Map instead of a Set.

In pseudo-code, it looks like:

Map<String, Integer> legalEnglishWord = new HashMap<>();
for each word in "exmample.txt" {
    legalEnglishWords.put(word, 0);
}

// handle input
for each word in inputMessage {
    if (legalEnglishWords.containsKey(word)) { 
        legalEnglishWords.put(word, legalEnglishWord.get(word) + 1);
    }
    // or simply
    legalEnglishWords.computeIfPresent( word, count -> return count+1);
}

// At this point, you have each legal words, and the appearances of 
// each legal word in the input message.

Upvotes: 1

Related Questions