1

I have the below program that counts the occurrence of a character in a string. For example, given a string - my name is stack overflow, I want the output to be

f 1 e 2 c 1 a 2 n 1 o 2 l 1 m 2 k 1 i 1 w 1 v 1 t 1 s 2 r 1 y 1

However, something seems to be wrong, and I am unable to figure out what. Also, please note - I do see a few programs posted in the past. Possible duplicate. But I would like help with my specific problem rather than using someone else' solution.

Here's the code:

//Count the occurence of a character in a string
package strings;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CharacterOccurenceInAString {
    private static Map<Integer, Character> str = new HashMap<Integer, Character>();
    private static List<Character> charList = new ArrayList<Character>();
    private static Character value;

    public static void main(String[] args) {
        BufferedReader br = null;
        String input = "";
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Please enter a string");
            input = br.readLine();
            charOccurence(input);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public static void charOccurence(String s) {        
        for (int i = 0; i < s.length(); i++) {
            // Don't include white spaces -         
            if (Character.isWhitespace(s.charAt(i))) {
                continue;
            } else {
                str.put(i, s.charAt(i));
                charList.add(s.charAt(i));
            }
        }
        for(Character val:str.values()){
                getCount(val);
        }
    }

    static boolean flag = false;
    public static int getCount(Character c) {
        int ct = 0;
        for (int i = 0; i < charList.size(); i++) {         
            c = charList.get(i);
            if (charList.contains(c)) {
                ct++;
                flag=false;
            }           
        }
        if(flag==false)
        {
        System.out.println(c + ":" + ct);
        }
        return ct;
    }
}

This is the output I get:

Please enter a string
my name is stack overflow
w:21
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21 
w:21
Community
  • 1
  • 1
  • 2
    What does "something seems to be wrong" mean? What is happening? – Joe F May 02 '13 at 21:00
  • it seems to me that you are overwritting the values in the hashtable for every letter, instead of incriminating the value. – Neil Locketz May 02 '13 at 21:02
  • Yes, Neil you are right. Can you please guide me on what I am doing wrong. Since I am new to Java, I am unable to figure out. –  May 02 '13 at 21:03

4 Answers4

1

In Guava:

Multiset<Character> occurrences = HashMultiset.create(
    Lists.charactersOf(CharMatcher.WHITESPACE.removeFrom("the string")));
sjr
  • 9,769
  • 1
  • 25
  • 36
0

If you want to get the character count, it will be much better if you do a Map< Character, Integer> rather than Map< Integer,Character>.

Map<Character, Integer> charCount = new HashMap<Character,Integer>();
for (int i = 0; i < s.length(); i++) {
    Integer count = charCount.get(s.charAt(i));
    if (count == null)
        count = 0;
    charCount.put(s.charAt(i), ++count);
}

This will get you a map of all characters to how many times they occur.

greedybuddha
  • 7,488
  • 3
  • 36
  • 50
0

To make this work with the bare minimum of change to your code:

public static int getCount(Character c) {
    int ct = 0;
    for (int i = 0; i < charList.size(); i++) {         
        //c = charList.get(i); //why were you doing this, this method takes the desired c as an input?
        if (charList.get(i).equals(c)) { //now it only incriments when that particular entry equals c, not if ANY entry matches c
            ct++;
            flag=false;
        }           
    }
    if(flag==false)
    {
    System.out.println(c + ":" + ct);
    }
    return ct;
}

In your version of getCount you go through the entire string adding one to ct EVERY TIME round the loop if the letter is anywhere in the string, you also change c within getCount which I don't think you should do.

This change doesn't make your code perfect, repeated letters lead to repeated (but correct) output but it should point you in the right direction

Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
  • Richtea - Perfect. Sorry, since I am just getting started with this forum, and my reputation is low, I can't mark your response *correct* –  May 02 '13 at 21:12
  • @user2341013 I'm fairly sure you can accept an answer at any reputation level, but fair enough – Richard Tingle May 02 '13 at 21:19
  • Sorry, I didn't know you can accept answer irrespective of your reputation. I just did :-) –  May 02 '13 at 21:24
  • Awesome thanks, and i'm giving your question a +1 mostly for self reporting of duplicate. I enjoy excessive honesty – Richard Tingle May 02 '13 at 21:26
-2

Instead of asking the experts I would recommend to first try to find mistake yourself by debugging your code in eclipse in step mode. You can step through each statement and see the values of variables as it steps through. It's fun and informative :)

j.i.t.h.e.s.h
  • 4,128
  • 2
  • 15
  • 7