1

I'm a beginner in Java. I just want to count the occurrences of every word from a text file. The input format is just like:

A B
A C
C A
B C

Here is what I have done so far:

public static void main (String[] args) throws FileNotFoundException
{
    Scanner inputFile = new Scanner(new File("test.txt"));
    while (inputFile.hasNextLine()) {
        String line = inputFile.nextLine();
        System.out.println(line);
        // above is the first part, to read the file in
        // below is the second part, try to count
        Map<String, Integer> counts = new HashMap<>();
        for (String word : line) {
            Integer count = counts.get(word);
            counts.put(word, count == null ? 1 : count + 1);
        }
        System.out.println(counts);
    }
}

The expect result would be like :

A 3
B 2
C 3

I got the first and second parts on google, but don't know how to combine those. Any suggestion would be helpful.

gd1
  • 11,300
  • 7
  • 49
  • 88
user3631848
  • 433
  • 1
  • 6
  • 14

6 Answers6

4

You cant iterate through a String (variable line) using a for-each loop. You need to first split it into words as follows:

   String[] words = line.split(" ");
   for(String word : words) {
    // do something
   }

Also there seems to be a bug in the code. The Map for managing the count needs to be present outside the while loop, otherwise the counting will be local to a particular line. Change the code as follows :

public static void main (String[] args) throws FileNotFoundException
{
 Scanner inputFile = new Scanner(new File("test.txt"));
 Map<String, Integer> counts = new HashMap<>();
 while (inputFile.hasNextLine()) {
    String line = inputFile.nextLine();
    System.out.println(line);
    // above is the first part, to read the file in
    // below is the second part, try to count

    String[] words = line.split(" ");
    for (String word : words) {
        Integer count = counts.get(word);
        counts.put(word, count == null ? 1 : count + 1);
    }

  } // end of while

  System.out.println(counts);
}
Kakarot
  • 4,252
  • 2
  • 16
  • 18
2

You need to read the words, and not only the lines.

Since the default delimiter in Scanner splits each word properly, you can try:

while (inputFile.hasNext()) {
    String word = inputFile.next();
    // do the same as before with word
}
gd1
  • 11,300
  • 7
  • 49
  • 88
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
1

inputFile.nextLine() returns a String containing the words of the current line. What you want to do is to split that into an array of Strings (your words) and then iterate on them. Take a look at String.split()

Community
  • 1
  • 1
mastaH
  • 1,234
  • 3
  • 15
  • 30
1
 Scanner inputFile = new Scanner(new File("C:/Test/test.txt"));
   Map<String, Integer> counts = new HashMap<>();
    while (inputFile.hasNextLine()) {
        String line = inputFile.nextLine();         
        for (String word : line.split(" ")) {
            Integer count = counts.get(word);
            counts.put(word, count == null ? 1 : count + 1);
        }

    }
    System.out.println(counts);

Using the JAVA 7 Files API you can achieve it as follows

public static void main(String[] args) throws IOException{
    List<String> allLines = Files.readAllLines(Paths.get("C:/Test/test.txt"), Charset.defaultCharset());
    Map<String,Integer> charCount = new HashMap<String,Integer>();
    for(String line:allLines){
        String[] characters = line.split(" ");
        for(String charac:characters){
            Integer currentCount = charCount.get(charac);
            charCount.put(charac, currentCount == null ? 1 : currentCount + 1); 
        }
    }
    System.out.println(charCount);
}
Pratik Shelar
  • 3,154
  • 7
  • 31
  • 51
1

This will work. Note that the scanner takes each word as opposed to each line.

public static void main (String[] args) throws FileNotFoundException 
{
    Scanner scanner = new Scanner("A B C D A A B C C");
    Map<String, Integer> words = new HashMap<>();
    String word;

    // Loop through each word instead of each line
    while (scanner.hasNext()) {
        word = scanner.next();

        // If the HashMap already contains the key, increment the value
        if (words.containsKey(word)){
            words.put(word, words.get(word) + 1);
        }
        // Otherwise, set the value to 1
        else {
            words.put(word, 1);
        }        
    }

    // Loop through the HashMap and print the results
    for(Entry<String, Integer> entry : words.entrySet()) {
        String key = entry.getKey();
        Integer value = entry.getValue();

        System.out.println(key + ": " + value);
    }
}
user184994
  • 17,791
  • 1
  • 46
  • 52
  • java:21: error: method containsKey in interface Map cannot be applied to given types; if (words.containsKey()){ ^ required: Object found: no arguments reason: actual and formal argument lists differ in length where K,V are type-variables: K extends Object declared in interface Map V extends Object declared in interface Map src/cc/openhome/jacob/KGGseqPPI/my5.java:31: error: cannot find symbol for(Entry entry : selects.entrySet()) { ^ symbol: class Entry location: class my5 – user3631848 May 14 '14 at 13:13
  • Sorry, just checked and it was littered with errors... Just updated and it works perfectly. – user184994 May 14 '14 at 21:55
  • Still doesn't work. There is something wrong with for(Entry.....) Should I import something else ? – user3631848 May 15 '14 at 03:53
  • @user3631848 You need to import java.util.Map.Entry – user184994 May 15 '14 at 06:24
  • thanks, this one works. I just imported java.util.* at before. I didn't know still have to import java.util.Map.Entry – user3631848 May 15 '14 at 06:41
1

You can get single word using StringTokenizer. it can divide words in term of token and it facilitates many feature to handle string.

String msg = "http://192.173.15.36:8084/";
    StringTokenizer st = new StringTokenizer(msg, "://.");

we can also get different varieties of token of string using regular expression via StringTokenizer.

The full solution is working to get count number of words from file.

public static void main(String[] args) {

    Scanner inputFile;
       Map<String, Integer> words = new HashMap<String, Integer>();
    try {
        inputFile = new Scanner(new File("d:\\test.txt"));
        while (inputFile.hasNextLine()) {
            //SringTokenize is automatically divide the string with space.

             StringTokenizer tokenizer = new StringTokenizer(inputFile.nextLine());
                while (tokenizer.hasMoreTokens()) {
                    String word=tokenizer.nextToken();
                    // If the HashMap already contains the key, increment the value
                    if (words.containsKey(word)){
                        words.put(word, words.get(word) + 1);
                    }
                    // Otherwise, set the value to 1
                    else {
                        words.put(word, 1);
                    } 
                }

        }

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

     // Loop through the HashMap and print the results
    for(Entry<String, Integer> entry : words.entrySet()) {
        String key = entry.getKey();
        Integer value = entry.getValue();

        System.out.println(key + ": " + value);
    }
}
Ramgau
  • 420
  • 2
  • 6
  • 16