Find duplicate characters in string - java

I am trying to print duplicate characters in a string for example if string input is: "aabacdceefeg" output should be a-->3,b-->1,c--->2,e-->3 like this way have to print values but below code not working for this logic can some one suggest me please
public class Test {
public static void main(String[] args) {
String string1 = "Great responsibility";
char string[] = string1.toCharArray();
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for (int i = 0; i < string.length; i++) {
for (int j = i + 1; j < string.length; j++) {
if (string[i] == string[j]) {
Integer value = hashMap.get(string[i]);
hashMap.put(string[i], value+1);
} else {
hashMap.put(string[i], 1);
}
}
}
System.out.println(hashMap);
}
}

There are many answers how to optimise the solution but there are none to show how the original O(N^2) time complexity solution could be fixed.
Here are the things to fix in the original solution (besides the obvious inefficiency)
If a character doesn't exist in the map yet then value should be set to 1 as that's its first time occurrence.
If the current char doesn't equal to another char then keep its original count.
The fixed code is below:
public static void main(String[] args) {
String string1 = "Great responsibility";
char string[] = string1.toCharArray();
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for (int i = 0; i < string.length; i++) {
for (int j = i + 1; j < string.length; j++) {
Integer value = hashMap.get(string[i]);
if (value == null) {
value = 1;
}
if (string[i] == string[j]) {
hashMap.put(string[i], value + 1);
} else {
hashMap.put(string[i], value);
}
}
}
System.out.println(hashMap);
}

You can simplify it by just using the hashMap directly and only using one loop
String string1 = "Great responsibility";
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for (Character c : string1.toCharArray()) {
if (hashMap.containsKey(c)) {
int val = hashMap.get(c);
hashMap.put(c, val + 1);
}
else {
hashMap.put(c, 1);
}
}
System.out.println(hashMap);
output
{ =1, a=1, b=1, e=2, G=1, i=3, l=1, n=1, o=1, p=1, r=2, s=2, t=2, y=1}

You only need one level of loops:
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < string.length; i++) {
Integer count = map.get(string[i]);
if (count == null) {
map .put(string[i], 1);
} else {
map .put(string[i], count+1);
}
}

first create a list of characters and then loop over your desired string.
ArrayList<Character> charList=new ArrayList();
charList.clear();
for (int i = 0; i < string.length; i++) {
if(!charList.Contains(string[i])){
charList.add(string[i]))
}
}
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for (Char char:charList) {
count=0;
for (int j = i + 1; j < string.length; j++) {
if (char == string[j]) {
hashMap.put(char, count++);
}
}
}
System.out.println(hashMap);
}

String string1 = "Great responsibility";
char[] chars = string1.toCharArray();
Map<Character, Integer> map = new HashMap<>();
for(char c : chars)
{
if(map.containsKey(c)) {
int counter = map.get(c);
map.put(c, ++counter);
} else {
map.put(c, 1);
}
}
I hope it will help you..

You can also use Java8 lambda function to solve the problem. You can simply convert the String into the count Map.
String string1 = "aabacdceefeg";
Map<Character,Long> countMap = string1.chars().mapToObj(i -> (char)i).collect(
Collectors.groupingBy(Function.identity(), Collectors.counting())
);
System.out.println(countMap);

Related

Sorted String with input characters pattern

I have the methode sortString, that have to sort characters in the string with pattern that i add.
For example:
if the pattern : List patter= Arrays.asList('a', 'b', 'c', 'd', 'z') and the inputString is "bbacrrt"
sortString have to return "abbcrrt" symbols that doesn't included in pattern have to add in the end of return string, order of this symbols doesn't metter.
In ideal way difficulty should be O(n).
private static String sortString(String inputString, List<Character> pattern) {
List<Character> inputlist = convert(inputString); // method convert create List<Character> from String
List<Character> returnedList = new ArrayList<>(Collections.nCopies(inputlist.size(), ' '));
Map<Character, Integer> map = new HashMap<>();
boolean isAdded = false;
for (int i = 0; i < pattern.size(); i++) {
map.put(pattern.get(i), i);
}
for (int i = 0; i < inputlist.size(); i++) {
for (int j = 0; j < pattern.size(); j++) {
if (inputlist.get(i) == pattern.get(j)) {
if (returnedList.get(map.get(pattern.get(j))) == pattern.get(j)) {
returnedList.add(map.get(pattern.get(j)), inputlist.get(i));
} else {
if (map.get(pattern.get(j)) - 1 < 0) {
returnedList.add(map.get(pattern.get(j)), inputlist.get(i));
} else {
returnedList.add(map.get(pattern.get(j)) + 1, inputlist.get(i));
}
}
isAdded = true;
}
}
if (!isAdded) {
returnedList.add(inputlist.get(i));
}
isAdded = false;
}
return returnedList.toString();
}
Could you help me?
My initial thought was to use a HashMap<String, ArrayList> to store the returnList. Use the String part of the HashMap to store each character of the pattern and ArrayList to store each character of the inputList as you walked through that string.
When you want the final output, loop through the HashMap using the pattern as the index.
When sorting characters, it's usually a counting sort. Then use a boolean array to mark the characters in the pattern. When you build the string, use the boolean array to check if the character should be append in the sort section or the unsorted section. Use the count array to append the number of characters to the string.
This is an O(n) solution.
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Character> pat = Arrays.asList('a', 'c', 'z');
String s = "atttbbacrrt";
System.out.println(sort(pattern, input));
}
static String sort(List<Character> pat, String s) {
boolean[] mustHave = new boolean[26];
int[] count = new int[26];
for(char c: pat) mustHave[c-'a'] = true;
for(char c: s.toCharArray()) count[c-'a']++;
StringBuilder sorted = new StringBuilder();
StringBuilder unsorted = new StringBuilder();
for(int i = 0; i < 26; i++) {
StringBuilder sb = mustHave[i] ? sorted : unsorted;
for(int j = 0; j < count[i]; j++) sb.append((char)('a'+i));
}
return sorted.toString() + unsorted.toString();
}
}
Output:
aacbbrrtttt
I hope that will help to someone
This is my Solition:
private static String sortString(String input, List<Character> alphabet) {
List<Character> inputlist = convert(input); // method convert return List<Character> from String
Map<String, ArrayList<String>> returnedMap = new HashMap<>();
Map<Integer, String> orderedMap = new HashMap<>();
List<List<String>> listWithSortedValues = new ArrayList<>();
boolean isAdded = false;
for (int i = 0; i < alphabet.size(); i++) {
returnedMap.put(alphabet.get(i).toString(), new ArrayList<>());
orderedMap.put(i ,alphabet.get(i).toString());
}
returnedMap.put("undefined", new ArrayList<>()); //better create CONSTANT private final static String UNDEFINED_PART = "undefined";
orderedMap.put(alphabet.size(), "undefined");
for (int i = 0; i < inputlist.size(); i++) {
for (int j = 0; j < alphabet.size(); j++) {
if (inputlist.get(i) == alphabet.get(j)) {
ArrayList<String> strings = returnedMap.get(inputlist.get(i).toString());
strings.add(alphabet.get(j).toString());
returnedMap.put(alphabet.get(j).toString(), strings);
isAdded = true;
}
}
if (!isAdded) {
ArrayList<String> unsortedValues = returnedMap.get("undefined");
unsortedValues.add(inputlist.get(i).toString());
returnedMap.put("undefined", unsortedValues);
}
isAdded = false;
}
for (int i = 0; i < orderedMap.size(); i++) {
String keyWithValueFromOrderedMap = orderedMap.get(i);
listWithSortedValues.add(returnedMap.get(keyWithValueFromOrderedMap));
}
List<String> returnedList = listWithSortedValues.stream().flatMap(List::stream).collect(Collectors.toList());
return converterListToString(returnedList); //method converterListToString returned String from List<String>

Leetcode Problem 451. Sort Characters By Frequency PriorityQueue sorting problem

public static String frequencySort(String s) {
String answer = "";
HashMap<Character, Integer> map = new HashMap<>();
for(int i = 0; i < s.length(); i++) {
map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
}
//System.out.println(map.get('l'));
//System.out.println(map.get('e'));
PriorityQueue<Character> q = new PriorityQueue<>(new Comparator<Character>() {
#Override
public int compare(Character o1, Character o2) {
if(map.get(o1) == map.get(o2)) {
//System.out.println("o1 - o2: " + o1 + o2 + " " + (o1 - o2));
return o2 - o1;
}
else {
return map.get(o2) - map.get(o1);
}
}
});
for(int i = 0; i < s.length(); i++) {
q.add(s.charAt(i));
}
while(!q.isEmpty()) {
answer += String.valueOf(q.poll());
}
return answer;
}
My code looks like this, but I don't know why sometimes when the frequency got same but the queue didn't poll out the char as I write in the comparator, for example it output as ccwccwwwcwwwwwwccwwcccwcwwcw
Looks pretty good! Not sure about your bug though, this'll just pass in Java without using PriorityQueue:
public final class Solution {
public static final String frequencySort(
String s
) {
Map<Character, Integer> countmap = new HashMap<>();
for (char character : s.toCharArray()) {
countmap.put(character, 1 + countmap.getOrDefault(character, 0));
}
List<Character>[] bucket = new List[s.length() + 1];
for (char key : countmap.keySet()) {
int frequency = countmap.get(key);
if (bucket[frequency] == null) {
bucket[frequency] = new ArrayList<>();
}
bucket[frequency].add(key);
}
StringBuilder sb = new StringBuilder();
for (int pos = bucket.length - 1; pos >= 0; pos--)
if (bucket[pos] != null)
for (char character : bucket[pos])
for (int i = 0; i < pos; i++) {
sb.append(character);
}
return sb.toString();
}
}
Here are some of LeetCode's official solutions with comments:
public String frequencySort(String s) {
if (s == null || s.isEmpty()) return s;
// Create a sorted Array of chars.
char[] chars = s.toCharArray();
Arrays.sort(chars);
// Convert identical chars into single Strings.
List<String> charStrings = new ArrayList<String>();
StringBuilder currentString = new StringBuilder();
currentString.append(chars[0]);
for (int i = 1; i < chars.length; i++) {
if (chars[i] != chars[i - 1]) {
charStrings.add(currentString.toString());
currentString = new StringBuilder();
}
currentString.append(chars[i]);
}
charStrings.add(currentString.toString());
// Our comparator is (a, b) -> b.length() - a.length().
// If a is longer than b, then a negative number will be returned
// telling the sort algorithm to place a first. Otherwise, a positive
// number will be returned, telling it to place a second.
// This results in a longest to shortest sorted list of the strings.
Collections.sort(charStrings, (a, b) -> b.length() - a.length());
// Use StringBuilder to build the String to return.
StringBuilder sb = new StringBuilder();
for (String str : charStrings) sb.append(str);
return sb.toString();
}
public String frequencySort(String s) {
// Count up the occurances.
Map<Character, Integer> counts = new HashMap<>();
for (char c : s.toCharArray()) {
counts.put(c, counts.getOrDefault(c, 0) + 1);
}
// Make a list of the keys, sorted by frequency.
List<Character> characters = new ArrayList<>(counts.keySet());
Collections.sort(characters, (a, b) -> counts.get(b) - counts.get(a));
// Convert the counts into a string with a sb.
StringBuilder sb = new StringBuilder();
for (char c : characters) {
int copies = counts.get(c);
for (int i = 0; i < copies; i++) {
sb.append(c);
}
}
return sb.toString();
}
public String frequencySort(String s) {
if (s == null || s.isEmpty()) return s;
// Count up the occurances.
Map<Character, Integer> counts = new HashMap<>();
for (char c : s.toCharArray()) {
counts.put(c, counts.getOrDefault(c, 0) + 1);
}
int maximumFrequency = Collections.max(counts.values());
// Make the list of buckets and apply bucket sort.
List<List<Character>> buckets = new ArrayList<>();
for (int i = 0; i <= maximumFrequency; i++) {
buckets.add(new ArrayList<Character>());
}
for (Character key : counts.keySet()) {
int freq = counts.get(key);
buckets.get(freq).add(key);
}
// Build up the string.
StringBuilder sb = new StringBuilder();
for (int i = buckets.size() - 1; i >= 1; i--) {
for (Character c : buckets.get(i)) {
for (int j = 0; j < i; j++) {
sb.append(c);
}
}
}
return sb.toString();
}
This solution uses Priority Queue similar to yours (was in a comment on this link):
class Solution {
public String frequencySort(String s) {
PriorityQueue<Map.Entry<Character, Integer>> maxHeap =
new PriorityQueue<>((a, b) -> b.getValue() - a.getValue());
Map<Character, Integer> frequency = new HashMap<>();
for (Character c : s.toCharArray()) {
frequency.put(c, frequency.getOrDefault(c, 0) + 1);
}
maxHeap.addAll(frequency.entrySet());
StringBuilder sb = new StringBuilder();
while (maxHeap.size() > 0) {
Map.Entry<Character, Integer> entry = maxHeap.remove();
for (int i = 0; i < entry.getValue(); i++) {
sb.append(entry.getKey());
}
}
return sb.toString();
}
}
References
For additional details, please see the Discussion Board where you can find plenty of well-explained accepted solutions with a variety of languages including low-complexity algorithms and asymptotic runtime/memory analysis1, 2.

String sort descending order using java based on number of times character repeated

Here i have two strings that prints each character occurred how many times but i want that result in descending order.
public static void main(String[] args) {
TreeMap tm = new TreeMap();
String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
int[] counts = new int[128];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch < 128) {
counts[ch]++;
} else {
System.out.println("out of range");
}
}
for (char c = 0; c < 128; c++) {
if (counts[c] != 0) {
tm.put(counts[c], c);
// System.out.println(c + " occured " + counts[c] + "times");
}
}
for(int i=0;i<tm.size();i++){
System.out.println(tm.get(i));
}
}
This code giving output as:null,null,null,s,d but i need ouput as: j l a f k d s .please guide me.
My answer is probably rather too like the others but I tried to keep to the spirit of the original code, they were just quicker at writing it.
package uk.co.puce4.charactercount;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;
public class CharacterCount {
public static void main(String[] args)
{
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
int count = 1;
if(tm.containsKey(ch)){
count=tm.get(ch) + 1;
}
tm.put(ch, count);
}
TreeSet<CharItem> ts = new TreeSet<CharItem>();
Iterator<Character> it = tm.descendingKeySet().iterator();
while (it.hasNext()){
char ch = (char) it.next();
int count = tm.get(ch);
CharItem ci= new CharItem(ch, count);
ts.add(ci);
}
Iterator<CharItem> it2 = ts.iterator();
while(it2.hasNext()){
CharItem ci=it2.next();
System.out.println(ci.getCh() + " occured " + ci.getCount() + " times");
}
}
}
class CharItem implements Comparable<CharItem>{
private int count;
private char ch;
public CharItem(char c, int i){
count = i;
ch = c;
}
public char getCh() {
return this.ch;
}
public int getCount() {
return this.count;
}
#Override
public int compareTo(CharItem b) {
return b.count - this.count ;
}
}
There are a few problems with your approach:
You have a TreeMap that maps from char count to char. If multiple chars occur with the same count, you'll loose all but 1 of the chars.
You use the get method of TreeMap which means you're getting a char that have occurs i times instead of the value of the i-th entry in the map.
Here's an alternative for you:
Create a Container class that has fields for the char and the count.
Use TreeSet instead of TreeMap.
Code:
public class StringMap {
public static void main(String[] args) {
TreeSet<Container> ts = new TreeSet<>();
String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
int[] counts = new int[128];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch < 128) {
counts[ch]++;
} else {
System.out.println("out of range");
}
}
for (char c = 0; c < 128; c++) {
if (counts[c] != 0) {
ts.add(new Container(c, counts[c]));
}
}
for (Container c : ts.descendingSet()) {
System.out.println(c.character);
}
}
}
class Container implements Comparable<Container> {
Container(char c, int count) {
this.character = c;
this.count = count;
}
char character;
int count;
#Override
public int compareTo(Container o) {
int result = Integer.compare(count, o.count);
return result == 0 ? Character.compare(character, o.character) : result;
}
#Override
public boolean equals(Object o) {
return o instanceof Container && ((Container)o).character == character;
}
}
Your approach is correct, but there are a few minor changes to make.
First you should explicitly state the types in generic collections:
TreeMap<Integer, Set<Characters>>
You want to map a count to a set of characters, since there may be two or more characters that appear the same number of times. Otherwise inserting into the map will overwrite the previous count -> char mapping.
Second you want to append your character to the end of a count -> char set if it already exists in the map. The reason is explained above.
Third, a TreeMap of Integers sorts ascending, so refer to the javadoc to see how to get a descending view of your TreeMap.
Java TreeMap
Finally, to iterate over a map, you can loop over the entrySet() or values(). Again, checking the javadocs is your best friend.
public static void main(String[] args) {
TreeMap<Integer, Set<Character>> tm = new TreeMap<Integer, Set<Character>>();
String s = "ajklfajdlkfajsdklfjalljaklsdfjaklsdjf";
int[] counts = new int[128];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch < 128) {
counts[ch]++;
} else {
System.out.println("out of range");
}
}
for (char c = 0; c < 128; c++) {
if (counts[c] != 0) {
if (tm.contains(counts[c])) {
// Collision, there's already a character that appeared
// this number of times
tm.get(counts[c]).add(c);
} else {
Set<Character> charSet = new HashSet<Character>();
charSet.add(c);
tm.put(counts[c], charSet);
}
}
}
NavigableMap<Integer, Set<Character>> descendingMap = tm.descendingMap();
for (Map.Entry<Integer, Set<Character>> entry : descendingMap.entrySet()) {
//int count = entry.getKey();
Set<Character> chars = entry.getValue();
for (char c : chars) {
System.out.println(c);
}
}
}
}
Updated to use Set instead of list for efficiency.

How to find the most frequently occurring character in a string with Java?

Given a paragraph as input, find the most frequently occurring character. Note that the case of the character does not matter. If more than one character has the same maximum occurring frequency, return all of them
I was trying this question but I ended up with nothing. Following is the code that I tried but it has many errors I am unable to correct:
public class MaximumOccuringChar {
static String testcase1 = "Hello! Are you all fine? What are u doing today? Hey Guyz,Listen! I have a plan for today.";
public static void main(String[] args)
{
MaximumOccuringChar test = new MaximumOccuringChar();
char[] result = test.maximumOccuringChar(testcase1);
System.out.println(result);
}
public char[] maximumOccuringChar(String str)
{
int temp = 0;
int count = 0;
int current = 0;
char[] maxchar = new char[str.length()];
for (int i = 0; i < str.length(); i++)
{
char ch = str.charAt(i);
for (int j = i + 1; j < str.length(); j++)
{
char ch1 = str.charAt(j);
if (ch != ch1)
{
count++;
}
}
if (count > temp)
{
temp = count;
maxchar[current] = ch;
current++;
}
}
return maxchar;
}
}
You already got your answer here: https://stackoverflow.com/a/21749133/1661864
It's a most easy way I can imagine.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MaximumOccurringChar {
static final String TEST_CASE_1 = "Hello! Are you all fine? What are u doing today? Hey Guyz,Listen! I have a plan for today. Help!";
public static void main(String[] args) {
MaximumOccurringChar test = new MaximumOccurringChar();
List<Character> result = test.maximumOccurringChars(TEST_CASE_1, true);
System.out.println(result);
}
public List<Character> maximumOccurringChars(String str) {
return maximumOccurringChars(str, false);
}
// set skipSpaces true if you want to skip spaces
public List<Character> maximumOccurringChars(String str, Boolean skipSpaces) {
Map<Character, Integer> map = new HashMap<>();
List<Character> occurrences = new ArrayList<>();
int maxOccurring = 0;
// creates map of all characters
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (skipSpaces && ch == ' ') // skips spaces if needed
continue;
if (map.containsKey(ch)) {
map.put(ch, map.get(ch) + 1);
} else {
map.put(ch, 1);
}
if (map.get(ch) > maxOccurring) {
maxOccurring = map.get(ch); // saves max occurring
}
}
// finds all characters with maxOccurring and adds it to occurrences List
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
if (entry.getValue() == maxOccurring) {
occurrences.add(entry.getKey());
}
}
return occurrences;
}
}
Why don't you simply use N letter buckets (N=number of letters in alphabet) ? Just go along the string and increment the corresponding letter bucket. Time complexity O(n), space complexity O(N)
This method allows you to find the most frequently occurring character in a string:
public char maximumOccuringChar(String str) {
return str.chars()
.mapToObj(x -> (char) x) // box to Character
.collect(groupingBy(x -> x, counting())) // collect to Map<Character, Long>
.entrySet().stream()
.max(comparingByValue()) // find entry with largest count
.get() // or throw if source string is empty
.getKey();
}
import java.util.Scanner;
public class MaximumOccurringChar{
static String testcase1 = "Hello! Are you all fine? What are u doing today? Hey Guyz,Listen! I have a plan for today.";
public static void main(String[] args) {
MaximumOccurringChar test = new MaximumOccurringChar();
String result = test.maximumOccuringChar(testcase1);
System.out.println(result);
}
public String maximumOccuringChar(String str) {
int temp = 0;
int count = 0;
int current = 0;
int ind = 0;
char[] arrayChar = {'a','b' , 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
int[] numChar = new int[26];
char ch;
String s="";
str = str.toLowerCase();
for (int i = 0; i < 26; i++) {
count = 0;
for (int j = 0; j < str.length(); j++) {
ch = str.charAt(j);
if (arrayChar[i] == ch) {
count++;
}
}
numChar[i] = count++;
}
temp = numChar[0];
for (int i = 1; i < numChar.length; i++) {
if (temp < numChar[i]) {
temp = numChar[i];
ind = i;
break;
}
}
System.out.println(numChar.toString());
for(int c=0;c<26;c++)
{
if(numChar[c]==temp)
s+=arrayChar[c]+" ";
}
return s;
}
}
Algorithm:-
Copying the String character by character to LinkedHashMap.
If its a new character then insert new character , 1.
If character is already present in the LinkedHashMap then update the value by incrementing by 1.
Iterating over the entry one by one and storing it in a Entry object.
If value of key stored in entry object is greater than or equal to current entry then do nothing
Else, store new entry in the Entry object
After looping through, simply print the key and value from Entry object.
public class Characterop {
public void maxOccur(String ip)
{
LinkedHashMap<Character, Integer> hash = new LinkedHashMap();
for(int i = 0; i<ip.length();i++)
{
char ch = ip.charAt(i);
if(hash.containsKey(ch))
{
hash.put(ch, (hash.get(ch)+1));
}
else
{
hash.put(ch, 1);
}
}
//Set set = hash.entrySet();
Entry<Character, Integer> maxEntry = null;
for(Entry<Character,Integer> entry : hash.entrySet())
{
if(maxEntry == null)
{
maxEntry = entry;
}
else if(maxEntry.getValue() < entry.getValue())
{
maxEntry = entry;
}
}
System.out.println(maxEntry.getKey());
}
public static void main(String[] args) {
Characterop op = new Characterop();
op.maxOccur("AABBBCCCCDDDDDDDDDD");
}
}
The Big O below solution is just o(n). Please share your opinion on it.
public class MaxOccuringCahrsInStr {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "This is Sarthak Gupta";
printMaxOccuringChars(str);
}
static void printMaxOccuringChars(String str) {
char[] arr = str.toCharArray();
/* Assuming all characters are ascii */
int[] arr1 = new int[256];
int maxoccuring = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != ' ') { // ignoring space
int val = (int) arr[i];
arr1[val]++;
if (arr1[val] > maxoccuring) {
maxoccuring = arr1[val];
}
}
}
for (int k = 0; k < arr1.length; k++) {
if (maxoccuring == arr1[k]) {
char c = (char) k;
System.out.print(c + " ");
}
}
}
}
function countString(ss)
{
var maxChar='';
var maxCount=0;
for(var i=0;i<ss.length;i++)
{
var charCount=0;
var localChar=''
for(var j=i+1;j<ss.length;j++)
{
if(ss[i]!=' ' && ss[i] !=maxChar)
if(ss[i]==ss[j])
{
localChar=ss[i];
++charCount;
}
}
if(charCount>maxCount)
{
maxCount=charCount;
maxChar=localChar;
}
}
alert(maxCount+""+maxChar)
}
Another way to solve it. A simpler one.
public static void main(String[] args) {
String str= "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcddddeeeeee";
String str1 = "dbc";
if(highestOccuredChar(str) != ' ')
System.out.println("Most Frequently occured Character ==> " +Character.toString(highestOccuredChar(str)));
else
System.out.println("The String doesn't have any character whose occurance is more than 1");
}
private static char highestOccuredChar(String str) {
int [] count = new int [256];
for ( int i=0 ;i<str.length() ; i++){
count[str.charAt(i)]++;
}
int max = -1 ;
char result = ' ' ;
for(int j =0 ;j<str.length() ; j++){
if(max < count[str.charAt(j)] && count[str.charAt(j)] > 1) {
max = count[str.charAt(j)];
result = str.charAt(j);
}
}
return result;
}
public void countOccurrence(String str){
int length = str.length();
char[] arr = str.toCharArray();
HashMap<Character, Integer> map = new HashMap<>();
int max = 0;
for (char ch : arr) {
if(ch == ' '){
continue;
}
if (map.containsKey(ch)) {
map.put(ch, map.get(ch) + 1);
} else {
map.put(ch, 1);
}
}
Set<Character> set = map.keySet();
for (char c : set) {
if (max == 0 || map.get(c) > max) {
max = map.get(c);
}
}
for (Character o : map.keySet()) {
if (map.get(o).equals(max)) {
System.out.println(o);
}
}
System.out.println("");
}
public static void main(String[] args) {
HighestOccurence ho = new HighestOccurence();
ho.countOccurrence("aabbbcde");
}
public void stringMostFrequentCharacter() {
String str = "My string lekdcd dljklskjffslk akdjfjdkjs skdjlaldkjfl;ak adkj;kfjflakj alkj;ljsfo^wiorufoi$*#&$ *******";
char[] chars = str.toCharArray(); //optionally - str.toLowerCase().toCharArray();
int unicodeMaxValue = 65535; // 4 bytes
int[] charCodes = new int[unicodeMaxValue];
for (char c: chars) {
charCodes[(int)c]++;
}
int maxValue = 0;
int maxIndex = 0;
for (int i = 0; i < unicodeMaxValue; i++) {
if (charCodes[i] > maxValue) {
maxValue = charCodes[i];
maxIndex = i;
}
}
char maxChar = (char)maxIndex;
System.out.println("The most frequent character is >" + maxChar + "< - # of times: " + maxValue);
}
For Simple String Manipulation, this program can be done as:
package abc;
import java.io.*;
public class highocc
{
public static void main(String args[])throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter any word : ");
String str=in.readLine();
str=str.toLowerCase();
int g=0,count,max=0;;
int ar[]=new int[26];
char ch[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for(int i=0;i<ch.length;i++)
{
count=0;
for(int j=0;j<str.length();j++)
{
char ch1=str.charAt(j);
if(ch[i]==ch1)
count++;
}
ar[i]=(int) count;
}
max=ar[0];
for(int j=1;j<26;j++)
{
if(max<ar[j])
{
max=ar[j];
g=j;
}
}
System.out.println("Maximum Occurence is "+max+" of character "+ch[g]);
}
}
Sample Input1: Pratik is a good Programmer
Sample Output1: Maximum Occurence is 3 of character a
Sample Input2: hello WORLD
Sample Output2: Maximum Occurence is 3 of character l
maxOccu m = new maxOccu();
String str = "moinnnnaaooooo";
char[] chars = str.toCharArray();
Arrays.sort(chars);
str = new String(chars);
System.out.println(str);
m.maxOccurence(str);
void maxOccurence(String str) {
char max_char = str.charAt(0),
cur_char,
prev = str.charAt(0);
int cur_count = 0,
max_count = 0,
n;
n = str.length();
for (int i = 0; i < n; i++) {
cur_char = str.charAt(i);
if (cur_char != prev) cur_count = 0;
if (str.charAt(i) == cur_char) {
cur_count++;
}
if (cur_count > max_count) {
max_count = cur_count;
max_char = cur_char;
}
prev = cur_char;
}
System.out.println(max_count + "" + max_char);
}
public class HigestOccurredCharTest {
public static void main(String[] args) {
System.out.println("Enter the char string to check higest occurrence");
Scanner scan = new Scanner(System.in);
String str = scan.next();
if(str != null && !str.isEmpty()){
Map<Character, Integer> map = countOccurrence(str);
getHigestOccurrenceChar(map);
}else{
System.out.println("enter valid string");
}
}
public static Map<Character, Integer> countOccurrence(String str){
char strArr[] = str.toCharArray();
Map<Character, Integer> map = new HashMap<Character , Integer>();
for (Character ch : strArr) {
if(map.containsKey(ch)){
map.put(ch, map.get(ch)+1);
}else{
map.put(ch, 1);
}
}
return map;
}
public static void getHigestOccurrenceChar(Map<Character, Integer> map){
Character ch = null;
Integer no = 0;
Set<Entry<Character, Integer>> entrySet = map.entrySet();
for (Entry<Character, Integer> entry : entrySet) {
if(no != 0 && ch != null){
if(entry.getValue() > no){
no = entry.getValue();
ch = entry.getKey();
}
}else{
no = entry.getValue();
ch = entry.getKey();
}
}
System.out.println(ch+ " Higest occurrence char is "+ no);
}
}
Try Like that:-
string inputString = "COMMECEMENT";
List<Tuple<char, int>> allCharListWithLength = new List<Tuple<char, int>>();
List<char> distinchtCharList = inputString.Select(r => r).Distinct().ToList();
for (int i = 0; i < distinchtCharList.Count; i++)
{
allCharListWithLength.Add(new Tuple<char, int>(distinchtCharList[i], inputString.Where(r => r ==
distinchtCharList[i]).Count()));
}
Tuple<char, int> charWithMaxLength = allCharListWithLength.Where(r => r.Item2 == allCharListWithLength.Max(x => x.Item2)).FirstOrDefault();
Question: Frequently occurring Character in a String
Method 1: Using HashMap
public class t1{
public static void main(String a[]){
Map<Character, Integer> map = new HashMap<>();
String a1 = "GiinnniiiiGiiinnnnnaaaProtijayi";
for(char ch : a1.toCharArray()) {map.put(ch, map.getOrDefault(ch,0)+1);}//for
System.out.println(map);
char maxchar = 0 ;
int maxvalue = Collections.max(map.values());
System.out.println("maxvalue => " + maxvalue);
for( Entry<Character,Integer> entry : map.entrySet()) {
if(entry.getValue() == maxvalue) {
System.out.println("most frequent Character => " + entry.getKey());
}
}//for
}
}
Method 2 : Using count of alphabets in Python
str = "GiinnniiiiGiiinnnnnaaaProtijayi";
count = [0]*256
maxcount= -1
longestcharacter =""
# Traversing through the string and maintaining the count of
# each character
for ch in str:count[ord(ch)] += 1;
for ch in str:
if( maxcount < count[ord(ch)] ):
maxcount = count[ord(ch)]
longestcharacter = ch
print(longestcharacter)
print(maxcount)
IN Java :
public class t1{
public static void main(String[] args) {
String a = "GiinnniiiiGiiinnnnnaaaProtijayi";
int[] count = new int[256];
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
count[ch] +=1;
}//for
int maxcount = -1 ;
char longest = 0 ;
for( char ch : a.toCharArray()) {
if(count[ch] > maxcount) {
maxcount = count[ch];
longest = ch ;
}//if
}//for
System.out.println(longest);
System.out.println(maxcount);
}//main
}
Method 3: Using collections.Counter().most_common()
import collections
a = "GiinnniiiiGiiinnnnnaaaProtijayi";
fullDictionary = collections.Counter(a).most_common()
FirstElementWithCount = fullDictionary[0]
print(FirstElementWithCount)
FirstElementWithoutCount = FirstElementWithCount[0]
print(FirstElementWithoutCount)
Method 4: Using sorted and key = lambda ch : ch[1]
a = "GiinnniiiiGiiinnnnnaaaProtijayi";
d = {}
for ch in a: d[ch] = d.get(ch, 0) + 1
fullDictionary = sorted(d.items(), key=lambda ch :ch[1], reverse=True)
print(fullDictionary)
FirstElement = fullDictionary[0][0]
print(FirstElement)
package com.practice.ArunS;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
public class HighestFrequencyElement {
/*
* CONTENTSERV=N(2),T(2),E(2) SearchSort=S(2),r(2)
* HighestFrequencyElement=E(5)
*/
public static void main(String[] args) {
String str = "CONTENTSERV";
findHighestFrequencyElement(str);
}
private static void findHighestFrequencyElement(String str) {
System.out.println("Original String:" + str);
Map<String, Integer> myMap = new TreeMap<String, Integer>();
char[] ch = str.toCharArray();
for (int i = 0; i < str.length(); i++) {
if (myMap.containsKey(Character.toString(ch[i]))) {
Integer value = myMap.get(Character.toString(ch[i]));
myMap.replace(Character.toString(ch[i]), ++value);
} else {
myMap.put(Character.toString(ch[i]), 1);
}
} // end of foor loop
Comparator<Entry<String, Integer>> valueComparator = new Comparator<Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
Integer v1 = e1.getValue();
Integer v2 = e2.getValue();
return v2-v1;
}
};
// Sort method needs a List, so let's first convert Set to List in Java
List<Entry<String, Integer>> listOfEntries = new ArrayList<Entry<String, Integer>>(myMap.entrySet());
// sorting HashMap by values using comparator
Collections.sort(listOfEntries, valueComparator);
for(int i=0;i<listOfEntries.size();i++){
if(listOfEntries.get(0).getValue()==listOfEntries.get(i).getValue()){
System.out.println(listOfEntries.get(i));
}
}
}//end of method
}
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Answers {
public static void main(String[] args) {
String input1 = "Hello! Are you all fine? What are u doing today? Hey Guyz,Listen! I have a plan for today.";
String[] arin = input1.split("");
Predicate<String> checkIfValidChar = str -> ((str.charAt(0) >= '0' && str.charAt(0) <= '9')
|| (str.charAt(0) >= 'a' && str.charAt(0) <= 'z')
|| (str.charAt(0) >= 'A' && str.charAt(0) <= 'Z'));
String maxChar = Arrays.stream(arin).max(Comparator.comparing(i -> Arrays.stream(arin).filter(j -> {
return i.equalsIgnoreCase(j) && checkIfValidChar.test(j);
}).count())).get();
int count = Collections.frequency(Arrays.asList(arin), maxChar);
System.out.println(Arrays.stream(arin).filter(i -> {
return Collections.frequency(Arrays.asList(arin), i) == count && checkIfValidChar.test(i);
}).collect(Collectors.toSet()));
}
}
I see many answers that are unnecessarily convoluted, import tons of stuff or use a cannon to shoot a mosquito ( the accepted answer uses an HashTable ).
Here a simple solution:
public List<Character> mostFrequentLetter(String message) {
var m = message
.replaceAll("[^a-z]", "")
.toLowerCase();
int[] count = new int[26];
for(var c : m.toCharArray()){
int i = ((int)c)-97;
count[i]++;
}
var max_i = 0; // index of the most frequent letter
var max_c = count[max_i]; // count of the most frequent letter
var max = new ArrayList<Character>(3); // list containing letters with the same frequency
for(int i = 1; i < 26; ++i){
if (count[i] >= max_c){
max_i = i;
char c = (char)(max_i + 97);
if(count[i]!=max_c){
max.clear();
max_c = count[i];
}
max.add(c);
}
}
return max;
}
Here str will be the given string. This is Javascript code
function maxCharacter(str){
let str1 = str; let reptCharsCount=0; let ele='';let maxCount=0;
let charArr = str1.split('');
for(let i=0; i< str1.length; i++){
reptCharsCount=0;
for(let j=0; j< str1.length; j++){
if(str1[i] === str1[j]) {
reptCharsCount++;
}
}
if(reptCharsCount > maxCount) {
ele = str1[i];
maxCount = reptCharsCount;
}
}
return ele;
}
Although all the answers are correct posting my way of doing it
/Question: For the given string such as "aabbbbbcc" print the longest occurring character,
index and number of times it occurs.
Ex:
"longest occurring character is b and length is 5 at index 2"./
class Codechef {
public static void main (String[] args) {
String problem = "aabbbbbcc";
Map<Character,Temp> map = new HashMap<>();
for(int i = 0; i < problem.length(); i++){
if (map.containsKey(problem.charAt(i))) {
map.get(problem.charAt(i)).incrementCount();
} else {
map.put(problem.charAt(i), new Temp(i, 1, problem.charAt(i)));
}
}
List<Map.Entry<Character, Temp>> listOfValue = new LinkedList<Map.Entry<Character, Temp>>(map.entrySet());
Comparator<Map.Entry<Character, Temp>> comp = (val1, val2) -> (val1.getValue().getCount() < val2.getValue().getCount() ? 1: -1);
Collections.sort(listOfValue, comp);
Temp tmp = listOfValue.get(0).getValue();
System.out.println("longest occurring character is "+ tmp.getStr()+ " and length is " + tmp.getCount()+ " at index "+ tmp.getIndex());
}}
And then created one Model class to keep these values
class Temp {
Integer index;
Integer count;
Character str;
public Temp(Integer index, Integer count, Character str ){
this.index = index;
this.count = count;
this.str = str;
}
public void incrementCount(){
this.count++;
}
public Integer getCount(){
return count;
}
public Character getStr(){
return str;
}
public Integer getIndex(){
return index;
}}
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class Maxchar {
public static void main(String[] args) {
String str = "vaquar khan.";
// System.out.println();
System.out.println(maxChar(str));
String testcase1 = "Hello! Are you all fine? What are u doing today? Hey Guyz,Listen! I have a plan for today.";
System.out.println(maxChar(testcase1));
}
private static char maxChar(String str) {
if (null == str)
return ' ';
char[] charArray = str.replaceAll("\s+", "").toCharArray();
//
Map<Character, Integer> maxcharmap = new HashMap<Character, Integer>();
//
for (char c : charArray) {
if (maxcharmap.containsKey(c)) {
maxcharmap.put(c, maxcharmap.get(c) + 1);
} else {
maxcharmap.put(c, 1);
}
// Inside map we have word count
// System.out.println(maxcharmap.toString());
}
//
//
Set<Entry<Character, Integer>> entrySet = maxcharmap.entrySet();
int count = 0;
char maxChar = 0;
//
for (Entry<Character, Integer> entry : entrySet) {
if (entry.getValue() > count) {
count = entry.getValue();
maxChar = entry.getKey();
}
}
System.out.println("Maximum Occurring char and its count :");
System.out.println(maxChar + " : " + count);
return maxChar;
}
}
If you're open to 3rd party libraries you could use the Bag type from Eclipse Collections and select the top occurrences.
public char[] maxOccurringChar(String s) {
MutableCharBag bag = CharBags.mutable.of(s.toCharArray());
MutableList<CharIntPair> maxOccurringCharsWithCounts = bag.topOccurrences(1);
MutableCharList maxOccurringChars = maxOccurringCharsWithCounts.collectChar(CharIntPair::getOne);
return maxOccurringChars.toArray();
}
Note in this example we used the primitive collections to avoid boxing of the char and int types.
import java.util.*;
import java.util.stream.*;
class MaxOccur{
public static void main(String[] args){
String str = "sfowfjalkfaeffawkefjweajjwjegjoweeowe";
maxOcc(str);
}
public static void maxOcc(String s){
ArrayList<Character> arr = (ArrayList<Character>) s.chars().mapToObj(e ->(char)e).collect(Collectors.toList());
HashSet<Character> hs = new HashSet<>(arr);
int max = 0;
int f = 0;
String answer = "";
for(Character ch : hs){
f = Collections.frequency(arr,ch);
if(f>max){
max = f;
answer = ch;
}
System.out.println(ch + " occurs " + max + " times, the maximum");
}
}
In above, I'm using streams. Following are the steps:
Converting string's characters to arraylist using streams.
Making a hashset (discards all duplicate occurences of characters) using the arrayList created in step 1.
Use Collections.frequency to count occurence of each character in arrayList.
It's not the easiest solution, neither is it really adorable! But, it makes use of streams, something which i recently started learning and wanted to apply. I'm no adept in using streams, but they are beautiful. I've learnt most of them here on stackoverflow, and i'm so grateful. :)
Map the chars to their occurrence then query entries for the max value and get its key, note this will return the first char that has the highest occurrence
"abc".chars().mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparingLong(Map.Entry::getValue))
.get()
.getKey();
Here I am posting the answer by using HashMap
public class maximumOccurrence {
public static Map<Character,Integer> maximumOccurence(String s) {
char maxchar='';
int maxint=0;
Map<Character,Integer> map = new HashMap<Character, Integer>();
char strAtt[]= s.toCharArray();
for(Character ch : strAtt) {
if(map.containsKey(ch)) {
map.put(ch, map.get(ch)+1);
}else {
map.put(ch,1);
}
}
for(Map.Entry<Character,Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
if(maxint<entry.getValue()) {
maxint=entry.getValue();
maxchar=entry.getKey();
}
}
System.out.println("Character repeated ="+maxchar+" it's value is:"+maxint);
return map;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String s= "uuuiiiiiiiiiiioooooopp";
System.out.println(maximumOccurence(s));
}
}

Java count occurrence of each item in an sorted array

I have an Array of Strings and want to count the occurrences of any single String.
I have already sorted it. (It's a long Array and I wanted to get rid of the O(n²)-loop)
Here my code.. obviously it runs out in an ind.outOfB. exc.. the reason is clear but I donno how to solve..
for (int i = 0; i < patternsTest.length-1; i++) {
int occ=1;
String temp=patternsTest[i];
while(temp.equals(patternsTest[i+1])){
i++;
occ++;
}
}
This would be a good place for a HashMap, the key would be the Word, and the value the Number of times it occurs. The Map.containsKey and Map.get methods are constant time lookups which are very fast.
Map<String,Integer> map = new HashMap<String,Integer>();
for (int i = 0; i < patternsTest.length; i++) {
String word=patternsTest[i];
if (!map.containsKey(word)){
map.put(word,1);
} else {
map.put(word, map.get(word) +1);
}
}
As a side benefit you don't even need to sort beforehand!
You can use Java HashMap:
Map<String, Integer> occurrenceOfStrings = new HashMap<String, Integer>();
for(String str: patternsTest)
{
Integer currentValue = occurrenceOfStrings.get(str);
if(currentValue == null)
occurrenceOfStrings.put(str, 1);
else
occurrenceOfStrings.put(str, currentValue + 1);
}
This does not have index out of bounds:
String[] patternsTest = {"a", "b"};
for (int i = 0; i < patternsTest.length-1; i++) {
int occ=1;
String temp=patternsTest[i];
while(temp.equals(patternsTest[i+1])){
i++;
occ++;
}
}
You can cause an Index Out of Bounds by changing the data to:
String[] patternsTest = {"a", "a"};
you could try a map and only one loop
Map<String, Integer> occurences = new HashMap<String, Integer>();
String currentString = patternsTest[0];
Integer count = 1;
for (int i = 1; i < patternsTest.length; i++) {
if(currentString.equals(patternsTest[i]) {
count++;
} else {
occurrences.put(currentString, count);
currentString = patternsTest[i];
count = 1;
}
}
occurrences.put(currentString, count);
Guava Multiset solution (two lines of code):
Multiset<String> multiset = HashMultiset.create();
multiset.addAll(Arrays.asList(patternsTest));
//Then you could do...
multiset.count("hello");//Return count the number of occurrences of "hello".
We could use it both sorted and un-sorted arrays. Easy to maintain code.
My solution is:
public int cantOccurences(String pattern, String[] values){
int count = 0;
for (String s : values) {
count += (s.replaceAll("[^".concat(pattern).concat("]"), "").length());
}
return count;
}

Categories

Resources