Simple way to count character occurrences in a string
JavaStringJava Problem Overview
Is there a simple way (instead of traversing manually all the string, or loop for indexOf) in order to find how many times, a character appears in a string?
Say we have "abdsd3$asda$asasdd$sadas" and we want that $ appears 3 times.
Java Solutions
Solution 1 - Java
public int countChar(String str, char c)
{
int count = 0;
for(int i=0; i < str.length(); i++)
{ if(str.charAt(i) == c)
count++;
}
return count;
}
This is definitely the fastest way. Regexes are much much slower here, and possible harder to understand.
Solution 2 - Java
Functional style (Java 8, just for fun):
str.chars().filter(num -> num == '$').count()
Solution 3 - Java
Not optimal, but simple way to count occurrences:
String s = "...";
int counter = s.split("\\$", -1).length - 1;
Note:
- Dollar sign is a special Regular Expression symbol, so it must be escaped with a backslash.
- A backslash is a special symbol for escape characters such as newlines, so it must be escaped with a backslash.
- The second argument of split prevents empty trailing strings from being removed.
Solution 4 - Java
You can use [Apache Commons][1]' StringUtils.countMatches(String string, String subStringToCount)
.
[1]: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#countMatches%28java.lang.String,%20java.lang.String%29 "Apache Commons"
Solution 5 - Java
Since you're scanning the whole string anyway you can build a full character count and do any number of lookups, all for the same big-Oh cost (n):
public static Map<Character,Integer> getCharFreq(String s) {
Map<Character,Integer> charFreq = new HashMap<Character,Integer>();
if (s != null) {
for (Character c : s.toCharArray()) {
Integer count = charFreq.get(c);
int newCount = (count==null ? 1 : count+1);
charFreq.put(c, newCount);
}
}
return charFreq;
}
// ...
String s = "abdsd3$asda$asasdd$sadas";
Map counts = getCharFreq(s);
counts.get('$'); // => 3
counts.get('a'); // => 7
counts.get('s'); // => 6
Solution 6 - Java
A character frequency count is a common task for some applications (such as education) but not general enough to warrant inclusion with the core Java APIs. As such, you'll probably need to write your own function.
Solution 7 - Java
I believe the "one liner" that you expected to get is this:
"abdsd3$asda$asasdd$sadas".replaceAll( "[^$]*($)?", "$1" ).length();
Remember that the requirements are:
> (instead of traversing manually all the string, or loop for indexOf)
and let me add: that at the heart of this question it sounds like "any loop" is not wanted and there is no requirement for speed. I believe the subtext of this question is coolness factor.
Solution 8 - Java
you can also use a for each loop. I think it is simpler to read.
int occurrences = 0;
for(char c : yourString.toCharArray()){
if(c == '$'){
occurrences++;
}
}
Solution 9 - Java
Something a bit more functional, without Regex:
public static int count(String s, char c) {
return s.length()==0 ? 0 : (s.charAt(0)==c ? 1 : 0) + count(s.substring(1),c);
}
It's no tail recursive, for the sake of clarity.
Solution 10 - Java
Traversing the string is probably the most efficient, though using Regex to do this might yield cleaner looking code (though you can always hide your traverse code in a function).
Solution 11 - Java
Well there are a bunch of different utilities for this, e.g. Apache Commons Lang String Utils
but in the end, it has to loop over the string to count the occurrences one way or another.
Note also that the countMatches
method above has the following signature so will work for substrings as well.
public static int countMatches(String str, String sub)
The source for this is (from here):
public static int countMatches(String str, String sub) {
if (isEmpty(str) || isEmpty(sub)) {
return 0;
}
int count = 0;
int idx = 0;
while ((idx = str.indexOf(sub, idx)) != -1) {
count++;
idx += sub.length();
}
return count;
}
I was curious if they were iterating over the string or using Regex.
Solution 12 - Java
This is simple code, but of course a little bit slower.
String s = ...;
int countDollar = s.length()-s.replaceAll("\\$","").length();
int counta = s.length()-s.replaceAll("a","").length();
An even better answer is here in a duplicate question
Solution 13 - Java
You can look at sorting the string -- treat it as a char array -- and then do a modified binary search which counts occurrences? But I agree with @tofutim that traversing it is the most efficient -- O(N) versus O(N * logN) + O(logN)
Solution 14 - Java
There is another way to count the number of characters in each string.
Assuming we have a String as
String str = "abfdvdvdfv"
We can then count the number of times each character appears by traversing only once as
for (int i = 0; i < str.length(); i++)
{
if(null==map.get(str.charAt(i)+""))
{
map.put(str.charAt(i)+"", new Integer(1));
}
else
{
Integer count = map.get(str.charAt(i)+"");
map.put(str.charAt(i)+"", count+1);
}
}
We can then check the output by traversing the Map as
for (Map.Entry<String, Integer> entry:map.entrySet())
{
System.out.println(entry.getKey()+" count is : "+entry.getValue())
}
Solution 15 - Java
public static int countChars(String input,char find){
if(input.indexOf(find) != -1){
return countChars(input.substring(0, input.indexOf(find)), find)+
countChars(input.substring(input.indexOf(find)+1),find) + 1;
}
else {
return 0;
}
}