0

"I want to find and print the occurrence of each character of given string and i have build my own logic but there is some problem.for example if i gave input as 'JAVA'. the output that my program produce will be

J 1
A 2
V 1
A 1

Expected output :

    J 1
    A 2
    V 1

i doesn't want to print A again. I hope you all get it what is the problem in my code."

import java.util.Scanner;

public class FindOccuranceOfCharacter {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String x;
    Scanner input = new Scanner(System.in);
    System.out.println("Enter a string");
    x = input.nextLine();
    x = x.toUpperCase();
    int size = x.length();
    for(int i =0;i<size;i++) {
        int count=1;
        char find = x.charAt(i);

        for(int j=i+1;j<size;j++) {
            if(find == x.charAt(j)) {
                count++;
            }
        }

        System.out.printf("%c\t%d",x.charAt(i),count);
        System.out.println();       
    }
}

}

Ankesh Pandey
  • 137
  • 1
  • 15
  • 1
    What part of your code tries to prevent `A` from being printed again? – Scott Hunter Jul 24 '19 at 19:22
  • Hi, if you'd like to create a frequency map for the string, perhaps try https://stackoverflow.com/questions/6712587/how-to-count-frequency-of-characters-in-a-string – IronMan Jul 24 '19 at 19:25
  • For the internal loop use `int j=0;` and it will work but I must say this is very inefficient solution you can use one for loop on each character and use `Map` key as characer, value as count and check on each key if key exist in map increase count and another loop to print map contents – Youans Jul 24 '19 at 19:28

3 Answers3

4

The reason your code prints the way it does is that your loop prints each character (and subsequent matches) for a given index. You really need to store the character and counts in a data structure with one loop, and then display the counts with a second. A LinkedHashMap<Character, Integer> is perfect for your use case (because it preserves key insertion order, no additional logic is needed to restore input order). Additional changes I would make include using String.toCharArray() and a for-each loop. Like,

Map<Character, Integer> map = new LinkedHashMap<>();
for (char ch : x.toUpperCase().toCharArray()) {
    map.put(ch, map.getOrDefault(ch, 0) + 1);
}
for (char ch : map.keySet()) {
    System.out.printf("%c\t%d%n", ch, map.get(ch));
}

Which I tested with x equal to JAVA and got (as requested)

J   1
A   2
V   1
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
1

This is not an optimal solution, but I have tried to change your code as little as possible:

public static void main(String args[]) {
    Scanner input = new Scanner(System.in);
    System.out.println("Enter a string");
    // use a StringBuilder to delete chars later on
    StringBuilder x = new StringBuilder(input.nextLine().toUpperCase());
    for(int i=0;i<x.length();i++) {
        int count=1;
        char find = x.charAt(i);

        // go through the rest of the string from the end so we do not mess up with the index
        for(int j=x.length()-1;j>i;j--) {
            if(find == x.charAt(j)) {
                count++;
                // delete counted occurences of the same char
                x.deleteCharAt(j);
            }
        }

        System.out.printf("%c\t%d",x.charAt(i),count);
        System.out.println();       
    }
}

My more preferred Java stream would look like this:

input.nextLine().toUpperCase().chars()
        .mapToObj(i -> (char) i)
        .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
        .forEach((k, v) -> System.out.println(k + "\t" + v));
Matthias
  • 7,432
  • 6
  • 55
  • 88
1

Using hashMap it's easy to accumulate the number of occurrences and you can easily print iterating the HashMap.

This is the code:

public class FindOccuranceOfCharacter {

public static void main(String[] args) {

    String x;
    Scanner input = new Scanner(System.in);
    System.out.println("Enter a string");
    x = input.nextLine();
    HashMap<Character,Integer> occurance = new HashMap<Character,Integer>();

    x = x.toUpperCase();
    int size = x.length();
    for(int i =0;i<size;i++) {
        int count=1;
        char find = x.charAt(i);

        occurance.put(find, occurance.getOrDefault(find, 0) + 1);

    }

    for (Character key : occurance.keySet()) {
        Integer value = occurance.get(key);
        System.out.println("Key = " + key + ", Value = " + value);
    }   

}

Fabrizio R.
  • 117
  • 1
  • 14