1

I got a java question asked in an interview. Print distinct characters in a string and print stars (*) under each character which shows how many times the character repeated in that string.

For eg: my string is "GOOGLE", then the output should be

G O L E
* * * *
* *

I tried in java and I was able to create a HashMap which will store the Character and Number of repetitions in the string. But the HashMap is not based on the Insertion order of the string. Also I don't know what should be my next step. Can someone help me? Thanks in advance

public void myFunction(String str) {
    int length = str.length();
    HashMap<Character, Integer> hm = new HashMap<>();
    for(int i=0;i<length;i++){
        char ch = str.charAt(i);
        if(hm.containsKey(ch)){
            hm.put(ch, hm.get(ch)+1);               
        }
        else {
            hm.put(ch, 1);
        }


    }
        System.out.println(hm);
}

OUTPUT - Enter a String: 
GOOGLE
{E=1, G=2, L=1, O=2}
Sarath S Nair
  • 603
  • 2
  • 14
  • 29
  • You can found answers here : http://stackoverflow.com/questions/683518/java-class-that-implements-map-and-keeps-insertion-order Check especially LinkedHashMap – VLEFF Oct 02 '15 at 15:33
  • There is no need to use HashMap for something simple like this. It is relevant, but an overkill. A simple 1D array with 3 lines of codes will do. – user3437460 Oct 02 '15 at 15:44

2 Answers2

3

If you use a LinkedHashMap it will keep the order of the insertion. You can do something like this. Also add in a max variable since we will need it later when printing.

String input = "GOOGLE";
int max = 0;
LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
for (char c: input.toCharArray()){
    if (map.containsKey(c)){
        map.put(c, map.get(c) + 1);
    }else{
        map.put(c, 1);
    }
    max = Math.max(max, map.get(c));
}
System.out.println(map);

Output:

{G=2, O=2, L=1, E=1}

Then just iterate through how many lines you have to print and iterate through each character. Something like this should do the trick.

for (int i=0; i<=max; i++){
    for (char c: map.keySet()){
        if (i==0){
            System.out.print(c);
        }else if (i<= map.get(c)){
            System.out.print("*");
        }else{
            System.out.print(" ");
        }
    }
    System.out.println();
}

Output:

GOLE
****
** 
gonzo
  • 2,103
  • 1
  • 15
  • 27
0

That's a good start.

What I would do next is to change the HashMap to a LinkedHashMap so that we can maintain the order of the characters and add a long to know the maximum number of times a character appears. Thus I would change your current code to something like:

public void myFunction(String str) {
int length = str.length();
long maxOcurrences = 0;
LinkedHashMap<Character, Integer> hm = new LinkedHashMap<>();
for(int i=0;i<length;i++){
    char ch = str.charAt(i);
    long nextValue;
    if(hm.containsKey(ch)){
        nextValue = hm.get(ch)+1
        hm.put(ch, nextValue);               
    }
    else {
        nextValue = 1;
        hm.put(ch, nextValue);
    }

    if(nextValue > maxOcurrences)
    {maxOcurrences = nextValue;}


}
    System.out.println(hm);
}

Next I would print the characters in order by iterating through the LinkedHashMap. Something like:

for (Map.Entry<Character, Integer> entry : hm.entrySet()) {
    System.out.print(entry.getKey());
}
System.out.println();

Finally I would create a loop that iterates maxOcurrences times and prints a * if needed.

for(int i = 0; i < maxOcurrences; i++)
{
    //Iterate over each character again
    for (Map.Entry<Character, Integer> entry : hm.entrySet()) {
        if(entry.getValue() > i)
        {
            //Print Star
            System.out.print("*");
        }else{
            //Print space
            System.out.print(" ");
        }
        System.out.println();
    }
}
João Neves
  • 944
  • 1
  • 13
  • 18
  • You can just catch the case of the first line when iterating through the keys. That way you only have to iterate through the map once. – gonzo Oct 02 '15 at 16:07
  • @gonzo Thank you for the input! That's true but the difference isn't really that much and `if`s tend to be more cpu costly than extra loops without `if`s. – João Neves Oct 02 '15 at 16:21