Trying to count occurence of each letter in String in Java - java

I am not able to get the correct occurrence of each letter present in the string. What is wrong with my code?
Code:
public class consecutiveCharacters {
public static String solve(String A, int B) {
HashMap<String, Integer> map = new HashMap<>();
for (int i=0;i<A.length();i++) {
Integer value = map.get(A.charAt(i));
if(value == null){
map.put(String.valueOf(A.charAt(i)),1);
}
else {
map.put(String.valueOf(A.charAt(i)),i+1);
}
}
System.out.println(map);
String text = "i feel good";
return text;
}
public static void main(String[] args) {
solve("aabbccd",2);
}
}
The output of the map should be:
{a=2, b=2, c=2, d=1}
Yet the output that the above code is giving is:
{a=1, b=1, c=1, d=1}

Using Map.merge() you can rid of checking this yourself:
Map<Character, Integer> map = new HashMap<>();
for( char c : A.toCharArray()) {
map.merge(c, 1, Integer::sum);
}
merge() takes 3 parameters:
A key which is the character in your case
A value to put for the key, which is 1 in your case
A merge bi-function to combine the new and existing values if the entry already existed. Integer::sum refers to Integer's method static int sum(int a, int b) which basically is the same as your value + 1.

I would use the following logic:
public static void solve(String A) {
Map<Character, Integer> map = new HashMap<>();
for (int i=0; i < A.length(); i++) {
char letter = A.charAt(i);
int count = map.get(letter) != null ? map.get(letter) : 0;
map.put(letter, ++count);
}
System.out.println(map); // prints {a=2, b=2, c=2, d=1}
}
public static void main(String[] args) {
solve("aabbccd");
}
The main changes I made were to switch to using a Map<Character, Integer>, since we want to keep track of character key counts, rather than strings. In addition, I tightened the lookup logic to set the initial count at either zero, in case a new letter comes along, or the previous value in the map, in case the letter be already known.

A more generic solution is to use Map<Character, Integer>:
public static void solve(String str) {
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i));
map.merge(ch, 1, Integer::sum);
}
System.out.println(map);
}
In case you have only English letter, then solution could be more memory effective:
public static void solve(String str) {
str = str.toLowerCase();
int[] letters = new int[26];
for (int i = 0; i < str.length(); i++)
letters[str.charAt(i) - 'a']++;
for (int i = 0; i < letters.length; i++)
if (letters[i] > 0)
System.out.format("%c=%d\n", 'a' + i, letters[i]);
}

The problem seems to be in this line map.put(String.valueOf(A.charAt(i)),i+1) where it is resetting the count every time it found a recurrence of a character. You need to get the previous count of a character if it recurred. Try changing the line to map.put(String.valueOf(A.charAt(i)),map.get(String.valueOf(A.charAt(i)))+1).
Also you can use Character directly as the key in your HashMap object, which will make the code much simpler. Hope the following code will be helpful:
public static String solve(String A, int B) {
HashMap<Character, Integer> count = new HashMap<>();
for(Character ch: A.toCharArray()){
if(count.containsKey(ch) == false){
count.put(ch, 0);
}
count.put(ch, count.get(ch)+1);
}
System.out.println(count);
String text = "i feel good";
return text;
}
// A = "aabbccd"
// count = {a=2, b=2, c=2, d=1}

The reason why it is not working is that you are putting a key of type String and you are trying to get using a character value.
The fastest way to solve the bug would be to change the get to
map.get(String.valueOf(A.charAt(i)))
Another way to do a check if a key does not exist is to use the contains method.
map.containsKey(String.valueOf(A.charAt(i)))

Related

Counting letter frequencies and print letter:count, but not duplicates in java strings

public static void main(String[] args) {
TextIO.putln("Text?");
String line = TextIO.getln();
line = line.toLowerCase();
char[] arr = line.toCharArray();
for(int i = 0; i < line.length(); i++){
if(Character.isLetter(arr[i])){
int count;
int j;
for(j = 0,count = 0; j < line.length(); j++){;
if( arr[i] == arr[j]){
count++;
}
}
System.out.printf("%c:%d\n", arr[i],count);
}
}
}
If I enter the string josh it prints out
j:1
o:1
s:1
h:1
If I enter joshh it prints
j:1
o:1
s:1
h:2
h:2
but I want
j:1
o:1
s:1
h:2
How do I, for any string with duplicates, only print out the unique letter and how many times it occurs total? I was thinking of maybe implementing a for loop that just checks for each letter and increment it such as
for ('a' : string)
total++
and then increment the 'a' by one, so the next loop would check how many occurrences of b, then c, and so on.
How much java do you know? Is this an assignment? Have you been through data structures? Two options:
Sort and then count
Use a map (dictionary if you come from Python as your username suggests), increment in the first pass and then iterate over the keys to print the values
From what I can tell, it looks like the issue lies in the for loop you are using while printing.
What happens is that you evaluate for every single character in the string and print. Once you evaluate for the first h in josh, your program then moves on to the second h, evaluates again, and as a result, prints h and its count again.
You could try a data structure such as a dictionary which accounts for unique elements. Or, as you count how many times letters appear, you can have another array that holds letters already seen. If you check against this array before counting how many times a letter appears you can see if the letter has already been counted, if so you can just skip this character and move on to the next. It isnt the most elegant solution, but it would work
public static void main(String[] args) {
TextIO.putln("Text?");
String line = TextIO.getln();
line = line.toLowerCase();
// char[] arr = line.toCharArray();
Map<Character, Integer> occurrences=new LinkedHashMap<Character, Integer>();
for(int i = 0; i < line.length(); i++){
int ch=line.charAt(i);
if(Character.isLetter(ch)){
if(occurrences.containsKey(ch)) {
occurrences.put(ch, occurrences.get(ch)+1); // increment
}
else {
occurrences.put(ch, 1);
}
}
}
for(char ch : occurrences.keySet()) {
System.out.print(ch+":"+occurrences.get(ch)+";");
}
System.out.println();
}
Try this.
Map<Character, Integer> map = new LinkedHashMap<>();
for (char c : line.toCharArray())
if (Character.isLetter(c))
map.compute(c, (k, v) -> v == null ? 1 : v + 1);
for (Entry<Character, Integer> e : map.entrySet())
System.out.printf("%c:%d\n", e.getKey(), e.getValue());

Count the no. of times a word can be created using the given input string

I want to print the no of times the word 'hello' can be printed from the given input of characters. Can you suggest what I am doing wrong, since This code is not passing all the test cases.
String strInput = br.readLine();//read the string
int count = 0;
int h = 0,e = 0,l= 0,o = 0;
for (int i=0;i< strInput.length();i++){
if(strInput.charAt(i)=='h'){
h++;}else if(strInput.charAt(i)=='l'){
l++;}else if(strInput.charAt(i)=='e'){
e++;}else if(strInput.charAt(i)=='o'){
o++;}
}
if(h>=1&&e>=1&&l>=2&&o>=1){
count++;
h--;
e--;
o--;
l=l-2;
}
System.out.println(count);
also how can I refactor this piece of code?
Your code looks almost fine; but its major problem is: it is very low-level, and therefore hard to read.
You see, all those counters and array accesses ... not so nice. And: you very much hardcoded "hello" into your code. What if you assignment will be to make this check for some arbitrary word?
So, lets give you some insights how you could improve your code.
You can use a Map<Character, Integer> to remember the characters you need to print one specific word:
String wordToCount = "hello"; // or maybe: coming form the user!
Map<Character, Integer> numberOfRequiredCharsPerChar = new HashMap<>();
for (char charToCount : wordToCount.toCharArray()) {
if (!numberOfRequiredCharsPerChar.containsKey(charToCount)) {
// unknown char, so we need a counter for it
numberOfRequiredCharsPerChar.put(charToCount, new Integer(0));
}
int currentCounter = numberOfRequiredCharsPerChar.get(charToCount);
numberOfRequiredCharsPerChar.put(charToCount, currentCounter+1);
}
So: the above iterates the "first" input, and afterwards, like for "hello", that Map tells you what you need to print it:
h x 1, e x 1, ll x 2, o x 1.
Then, in the second step, we use copies of that map in the reverse way:
int possibleCounts = 0;
String inputToCountOn = ....
Map<Character, Integer> numberOfUsedCharacters= new HashMap<>(numberOfRequiredCharsPerChar);
for (char availableChar : inputToCountOn()) {
if (numberOfUsedCharacters.containsKey(availableChar)) {
int currentCounter = numberOfUsedCharacters.get(availableChar);
currentCounter--;
if (currentCounter == 0) {
numberOfUsedCharacters.remove(availableChar);
} else {
numberOfUsedCharacters.put(availableChar, currentCounter);
}
if (umberOfUsedCharacters.isEmpty()) {
// that means: we fetched ALL chars we need to print the word ONCE
possibleCounts++;
// and reset our "counter" map
numberOfUsedCharacters= new HashMap<>(numberOfRequiredCharsPerChar);
}
}
... now you just print possibleCounts ...
Sure, this looks more complicated than your input; but it is much more flexible. And if one would spent some time to create little helper methods for each of the activities, you could write down the whole thing in a very readable way.
Here is another option. A few comments about it:
I used GhostCat's method to map the number of occurrences of each character in the input.
I check recursively if the characters needed are available in the input.
If so I remove those characters from input string, and check again.
The solution is case sensitive.
import java.util.HashMap;
import java.util.Map;
public class Test {
static String word = "hello";
static String strInput;
public static void main(String[] args) {
strInput = "hoe4olelltohlemllhlhoslelo";//read the string
Map<Character, Integer> charMap = mapNumOfChars();
int count = 0;
boolean done= false;
while(!done) {
for(Character c : charMap.keySet()) {
if(! hasTheNeededNumOfChars(c, charMap.get(c), 0)) {
done= true;
}
}
if(!done ) {
//remove from input string all chars that have been "used"
removeAllCharsUsed();
count++;
}
}
System.out.println(count);
}
/**
*Recursively search for num occurrences of c.
*#param c
* char to search
*#param num
* number of char occurrences
*#param startFrom
* start searching from index
*#return
*/
private static boolean hasTheNeededNumOfChars(char c, int num, int startFrom) {
int charIndex = strInput.indexOf(c, startFrom);
//no occurances of char found
if (charIndex < 0) {
return false;
}
//if char found is last, or only one char occurrence needed
//no need to continue checking
if((charIndex == (strInput.length() -1)) || (num == 1) ) {
return true;
}else {
//look for the remaining number of occurrences num-1
//starting from index charIndex
return hasTheNeededNumOfChars(c,num-1, charIndex+1);
}
}
private static void removeAllCharsUsed() {
for (char c : word.toCharArray()) {
strInput = strInput.replaceFirst(String.valueOf(c),"");
}
}
//taken from GhostCat solution
private static Map<Character, Integer> mapNumOfChars() {
Map<Character, Integer> charMap = new HashMap<>();
for (char charToCount : word.toCharArray()) {
if (!charMap.containsKey(charToCount)) {
// unknown char, so we need a counter for it
charMap.put(charToCount, new Integer(0));
}
int currentCounter = charMap.get(charToCount);
charMap.put(charToCount, ++currentCounter);
}
return charMap;
}
}
The if test should be within the for loop:
public static void main(String[] args) {
String strInput = br.readLine();//read the string
int count = 0;
int h = 0,e = 0,l= 0,o = 0;
for (int i=0; i< strInput.length();i++){
if(strInput.charAt(i)=='h'){ h++;}
else if(strInput.charAt(i)=='l'){l++;}
else if(strInput.charAt(i)=='e'){e++;}
else if(strInput.charAt(i)=='o'){o++;}
//this test should be made with every loop
if((h>=1) && (e>=1) && (l>=2) && (o>=1)){
count++;
h--;
e--;
o--;
l=l-2;
}
}
System.out.println(count);
}
here comes a generic refactored solution to your problem
the main idea is to count how many times we need each character to print our target word, and then see how many times we can find the needed amount inside the provided input.
for example:
if we want to print AAB and the input is AAABB, we need 2As and 1B to each time we will print, as we only have 3As we can print the As only once, and even if we can print the Bs twice the amount of As will limit us.
so with the following code you can call
timesCanBePrinted("hello","jhdfjhhelloejhlepoohhello");
and you will get the answer 2
private static int timesCanBePrinted(String targetWord, String letters) {
Map<Character, Integer> targetWordMap = new HashMap<>();
Map<Character, Integer> lettersWordMap = new HashMap<>();
//initializing targetWordMap
//so for hello for example our map will be like this
//{h:1,e:1,l:2,o:1}
initializeMapWithCharacterCount(targetWord, targetWordMap);
initializeMapWithCharacterCount(letters, lettersWordMap);
int timesCanBePrinted = Integer.MAX_VALUE;
Map<Character, Integer> result = createMapWithNumberOfTimesWeCanUseEachCharacter(targetWordMap, lettersWordMap);
//now we will look for the character that we can print less times
//this chacater will determine the number of times we can print the target
//word
for (Map.Entry<Character, Integer> resultCountKV : result.entrySet()) {
if(resultCountKV.getValue()<timesCanBePrinted){
timesCanBePrinted = resultCountKV.getValue();
}
}
return timesCanBePrinted;
}
/**
*
* create the map containing the number of times we can
* print a given character from the target word, with
* the current input
*
* #param targetWordMap
* #param lettersWordMap
* #return a map containing containing the number of times we can
* print a given character
*/
private static Map<Character, Integer> createMapWithNumberOfTimesWeCanUseEachCharacter(Map<Character, Integer> targetWordMap,
Map<Character, Integer> lettersWordMap) {
Map<Character, Integer> result= new HashMap<>();
for (Map.Entry<Character, Integer> neededLetterCount : targetWordMap.entrySet()) {
int totalTimesWeCanUseThisCharacter = 0;
if(lettersWordMap.containsKey(neededLetterCount.getKey())){
totalTimesWeCanUseThisCharacter = lettersWordMap.get(neededLetterCount.getKey())/neededLetterCount.getValue();
}
result.put(neededLetterCount.getKey(), totalTimesWeCanUseThisCharacter);
}
return result;
}
/**
* initializes targetWordMap
* so for hello for example our map will be like this
* {h:1,e:1,l:2,o:1}
*
* #param targetWord
* #param targetWordMap
*/
private static void initializeMapWithCharacterCount(String targetWord, Map<Character, Integer> targetWordMap) {
for(int i = 0;i<targetWord.length();i++){
if(targetWordMap.containsKey(targetWord.charAt(i))){
targetWordMap.put(targetWord.charAt(i),targetWordMap.get(targetWord.charAt(i))+1);
}
else{
targetWordMap.put(targetWord.charAt(i),1);
}
}
}

counting occurance of characters using hashtable in Java

I am trying to count occurrence of each character in a string.
So if I input aaabbbccc I am expecting o/p as {a=3, b=3, c=3} but instead I keep on getting it as {a=1, b=1, c=1} as my hashtable contains method fails and returns false. What is wrong in the code?
I also know that there is a HashMap collection quite similar to hashtable. but as I am learing java I want to try the same code with all datastructures just to get an idea of methods. The code with map is not much different than what I am doing here still this code fails. and I am not able to figure out where is the bug in the code.
I have following code:
Hashtable<Character, Integer> stringHash = new Hashtable<Character, Integer>();
This stringHash is a class level variable.
for(int i=0; i<s.length(); i++){
if(stringHash ==null || stringHash.size()==0){
stringHash.put(s.charAt(i), 1);
}
else{
if(! stringHash.contains(s.charAt(i)) ){
System.out.println(s.charAt(i));
stringHash.put(s.charAt(i), 1);
}
else{
int count = stringHash.get(s.charAt(i));
stringHash.put(s.charAt(i), count++);
}
}
System.out.println(stringHash + " " + s.charAt(i) + " "+ stringHash.contains(s.charAt(i)));
}
This code works for me:
String s = "aaabbbccc";
Map<Character, Integer> stringHash = new HashMap<Character, Integer>();
for (char ch : s.toCharArray())
stringHash.put(ch, stringHash.containsKey(ch) ? (stringHash.get(ch) + 1) : 1);
System.out.println(stringHash);
// output: "{a=3, b=3, c=3}"
I am using a Map<K, V> instead of HashTable<K, V>, but this is more common.
Try something like this....The reason your code is failing is that you are checking contains() on HashTable instead of its keySet. Hope that helps
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "aaaaabbcccc";
Hashtable<Character, Integer> counter = new Hashtable<Character, Integer>();
int count = 0;
for(int i=0;i<s.length();i++){
if(!counter.keySet().contains(s.charAt(i))){
counter.put(s.charAt(i), 1);
} else {
count = counter.get(s.charAt(i));
counter.put(s.charAt(i), ++count);
}
}
for(char c:counter.keySet()) {
System.out.println("Character : "+c+" - Occurences : "+counter.get(c));
}
}
o/p
Character : b - Occurences : 2
Character : c - Occurences : 4
Character : a - Occurences : 5
Your code
if(stringHash ==null || stringHash.size()==0){
stringHash.put(s.charAt(i), 1);
}
would throw NPE if somehow the hashmap is null. Luckily it seems that you have initialized it properly. The block rather should have been
if(stringHash ==null){
stringHash = new HashMap()
stringHash.put(s.charAt(i), 1);
}
Again, that would not have fixed your bug. You should use containsKey instead of contains that checks for value in HashTable. What you are looking to implement can be summarized in following pseudocode.
initialize hashmap
for each character c in inputString
count = 0
if hashmap has a key for c
count = get value for c from hashmap
end if
put in to hashmap c, count + 1
end for
In Java this would look like :
Map<Character, Integer> charCountMap = new HashMap<>();
for(char c : inputString.toCharArray()){
int count = 0;
if(charCountMap.containsKey(c)){
count = charCountMap.get(c);
}
charCountMap.put(c,count+1);
}
Or for the adventurous, here is Java8 version
Map<Character,Long> map = s.chars().mapToObj(i->(char)i)
.collect(Collectors
.groupingBy(e -> e,
Collectors.counting()));
System.out.println(map);
Finally, do not use HashTable its a legacy class, no one uses it now a days. Stick with HashMap or other flavors of Map implementations.
Debug my code questions are discouraged, but in the way of solving the general problem of counting characters in a string I can suggest a much simpler method:
public static int[] countCharacters( String s ){
int[] count = new int[ 256 ];
for( int xChar = 0; xChar < s.length(); xChar++ ) count[ s.charAt( xChar ) ]++;
return count;
}
This assumes you have single byte characters.
Why do you use hashMap for counting character occurance?
I would use integer array of size 255 like so:
int[] counter = new int[256];
String s = "aaabbbcccc";
for(int i = 0; i < s.length(); i++){
counter[s.charAt(i)]++;
}
for(int i = 0; i < counter.length; i++)
if(counter[i] > 0)
System.out.println(((char)i) + " occurs " + counter[i] + " times");
that coude would give an output:
a occurs 3 times
b occurs 3 times
c occurs 4 times
Don't use Hashtable, you can simplify that code a lot, something like this should work:
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class Main {
public static void main(String[] args) {
Map<Character, Long> countMap = count("aabbbcccc");
for (Map.Entry<Character, Long> entry : countMap.entrySet()) {
System.out
.println(MessageFormat.format("Char ''{0}'' with count ''{1}''", entry.getKey(), entry.getValue()));
}
}
private static Map<Character, Long> count(String value) {
Map<Character, Long> countMap = new HashMap<Character, Long>();
if (StringUtils.isNotBlank(value)) {
for (int i = 0; i < value.length(); i++) {
Long count = countMap.get(value.charAt(i));
count = count == null ? 1 : count + 1;
countMap.put(value.charAt(i), count);
}
}
return countMap;
}
}

How can I check character occurrence in a string?

My Question is-
Input is string. Return true if the String has exactly 1 character that appears twice in the string, 0 character that appear thrice in the string, and at least 1 character that appear four or more times in the string. There is a problem in my code and I am unable to find out the problem.
public class CheckCharacterOccurence {
static String testcase1 = "jjiiiiyy";
public static void main(String[] args) {
CheckCharacterOccurence testInstance = new CheckCharacterOccurence();
boolean result = testInstance.checkCharacterOccurence(testcase1);
System.out.println(result);
}
public boolean checkCharacterOccurence(String str) {
char ch=' ';
char ch1=' ';
int temp=0;
int temp1=0;
int temp2=0;
int count=0;
for(int i=0;i<str.length();i++){
ch=str.charAt(i);
for(int j=i;j<str.length();j++){
if(str.charAt(i)==str.charAt(j)){
ch1=str.charAt(i);
count++;
}
}
System.out.println(count);
if(count==2&&ch!=ch1){
temp++;
}
if(count==3&&ch!=ch1){
temp1++;
}
if(count>=4){
temp2++;
}
count=0;
}
if(temp==1&&temp1==0&&temp2>=1){
return true;
}
return false;
}
}
I would suggest using a map
For all characters in string, increment map[that_char]
At last iterate over map to find how many times each character appeared.
Alternatively you can use array also to keep count.
Something like
int [] ctr = new int[256]
ctr = all zeroes
for (ch : string)
ctr[ch]++
mxocc = 0
maxch = 'a'
for(ch = a, b, c, d, e...)
if(ctr[ch] > maxocc) maxocc = ctr[ch] and maxch = ch
Output require info
hey you can figure out the problem ... atleast i can give to some extend same code , you can check it and try to solve your problem... This program finds the pattern in the string, now you can go through this program, and try to solve ur problem in your program by your own self.and try to do it by your own then only ur coding skills will get improved.and vote this answer if u fing it really helpful
#include<stdio.h>
#include<string.h>
int occur(char[],char[]);
int occur(char sent[],char pattern[])
{
int count=0;
for(int i=0,j=i;sent[i]!='\0';)
{
if(sent[i+j]==pattern[j]&&pattern[j]!='\0')
{
j++;
}
else if(j==strlen(pattern))
{
count++;
i=i+j;
j=0;
}
else
{
i++;
j=0;
}
}
return count;
}
int main()
{
char sent[] = "aabaabaaabbbabababddfggaabbbasab";
char pattern[] = "aba";
int result = occur(sent,pattern);
printf("\nNo of Occurrences --- > %d",result);
return 0;
}
You should simplify your code. For example there is not need to use those complex for-loops, you can use a for-each.
This code finds out the frequency of characters in a string and stores it in a Map.
import java.util.*;
public class CheckCharacterOccurence {
public static void main(String[] args) {
Map<Character, Integer> counting = new HashMap<Character, Integer>();
String testcase1 = "Helloooo";
for(char ch: testcase1.toCharArray()){
Integer freq = counting.get(ch);
counting.put(ch, (freq == null) ? 1 : freq + 1);
}
System.out.println(counting.size() + " distinct characters:");
System.out.println(counting);
}
}

Sorting frequency of chars

I just made an algorithm that counts the frequency of chars in a String. What I am confused about is how to sort the frequency so the character with the greatest number of occurences is listed at the top, and the least at the bottom.
At first I tried having another variable 'fc' (for frequency counter) to coincide with my original counter variable 'k'. However I am stuck in the thought process of how to go about sorting this frequency, the fc var I made is just useless.
Thanks for any help provided!
Here is my code:
import java.io.*;
public class Freq
{
public static void main(String args[])throws IOException
{
//read input stream
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int ci,i,j,k,l,fc;l=0;
String str,str1;
char c,ch;
System.out.println("Enter your String");
str=in.readLine();
i=str.length();
//cycle through ASCII table chars and obtain chars typed
for(c='A';c<='z';c++)
{
k=0;
fc=0; //fc keeps count like k
for(j=0;j<i;j++)
{
ch=str.charAt(j);
if(ch==c)
k++;
fc=k-1; //was going to represent this counter for 'less than k'
}
if(k>0)
System.out.println("The character "+c+" has occured for "+k+" times");
}
}
}
You will need to store them all first. You can use a HashMap to store them all, it will also simplify your counting routine. Then Collections.sort on the entry set. You will need to make a Comparable> to compare the entry values for sorting.
Edited to add sample code....
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter your String");
String line = in.readLine();
HashMap<Character,Integer> counts = new HashMap<>();
for(char c : line.toCharArray()) {
Integer count = counts.get(c);
if (count == null) {
count = 0;
}
counts.put(c, ++count);
}
List<Entry<Character,Integer>> list = new ArrayList<>(counts.entrySet());
Collections.sort(list, new Comparator<Entry<Character,Integer>>() {
#Override
public int compare(Entry<Character, Integer> o1,
Entry<Character, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
for(Entry<Character,Integer> entry : list) {
System.out.println("The character "+entry.getKey() +" has occured for "+ entry.getValue()+" times");
}
You can follow these steps:
1) Create a class call CharCount having two fields : char and freq. Override equals to return true if characters are equal and override hashcode to return character's hashcode. Make it implement Comparable and override compare and return -1,0 or 1 based on values of freq of objects being compared
2) Have a Set of CharCount
3)Each time you find a character create an instance of this class with character and freq as 0.
4)Check if it exists in set and update feq accordingly
5) Sort set data yourself or call Collections.sort
I would do it like this:
int[] frequencyArray = new int['z' -'A'];
String inputString = "ttttttttttttttttest";
for(int i = 0; i<inputString.length();i++)
{
frequencyArray[inputString.charAt(i) -'A']++;
}
Then, you can sort this array by any of the popular sorting algorithms of your choosing.
EDIT Made the code more memory efficient.
Make a function count that gives you the count of particular character and sort on behalf of count, e.g
if( count(str,str.charAt[j]) > count(str,str.charAt[j+1]) )
SWAP
its better to convert str to char array before this, then it will be like
count(chararr,charrarr[j])
This one works faster than Hashmap solution:
public static void frequencySort(String s) {
int[] f = new int[256];
for (int c : s.toCharArray())
f[c]++;
List<CharStore> list = new ArrayList<>();
for (int i = 0; i < f.length; i++) {
if (f[i] != 0) list.add(new CharStore(i, f[i]));
}
Collections.sort(list);
for (CharStore c : list) {
System.out.println(((char)c.c) + " has occured " + c.count + " times";
}
}
static class CharStore implements Comparable<CharStore> {
int c;
int count;
public CharStore(int c, int count) {
this.c = c;
this.count = count;
}
#Override
public int compareTo(CharStore o) {
return o.count - count;
}
}

Categories

Resources