Reputation: 157
"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();
}
}
}
Upvotes: 0
Views: 958
Reputation: 7521
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));
Upvotes: 1
Reputation: 126
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);
}
}
Upvotes: 1
Reputation: 201537
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
Upvotes: 4