Simple way to count character occurrences in a string
Solution 1
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
Functional style (Java 8, just for fun):
str.chars().filter(num -> num == '$').count()
Solution 3
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
You can use Apache Commons' StringUtils.countMatches(String string, String subStringToCount)
.
Solution 5
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
George Kastrinis
(contact: gkastrinis.info) Phd Candidate on program analysis Research on program analysis I love programming in general, and the mindset that it requires.
Updated on July 05, 2022Comments
-
George Kastrinis almost 2 years
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.
-
Mark Amery about 11 yearsThis works, but it's confusing and overcomplicated. Why use recursion - let alone this convoluted implementation - when iteration can be used simply and cleanly? Also,
indexOf
finds the leftmost index of the target string, socountChars(input.substring(0, input.indexOf(find)), find)
will always be equal to zero; you could scrap the first line of your return expression and get the same result. -
jahroy almost 11 yearsRegex = cleaner? Maybe shorter, but I would say regexes are generally pretty cryptic (and less clean) when compared to basic looping code.
-
user3090078 about 10 yearsYahoo! I got voted up! My first post ever :-D
-
user3090078 about 10 years@Marcelo solution looks nice but fails with:
"$$$$$$$$".split("\\$").length - 1
which = -1 or"$$$$$$$$".split("$").length - 1
which = 0. -
noddy almost 10 yearsAlmost a good idea. This fails on some simple cases though. e.g. s = "$"
-
Dmitry Ginzburg almost 10 yearsOoh, don't you mind using enhanced for loop instead of C-style going through indices?
-
Daniel almost 10 yearsI don't want to use implicit iterators.
-
Dmitry Ginzburg almost 10 yearsfirstly, surely, there's no shame to use iterators, what's the problem? Secondly, iterators are not used for looping arrays, see, for example, stackoverflow.com/a/7956673/1828937.
-
Daniel almost 10 years@DmitryGinzburg: The problem is we don't have a char array here, but a String. The alternate way would be to iterate over s.toCharArray(), but this would involve a copy of the Strings internal char array.
-
Boann over 9 yearsDoesn't work because $ is a regex metacharacter.
-
Chase over 9 yearsThis is needlessly complex, you can just use an array (256 long if only only basic characters are used, or 65535 long for the entire range java supports). do something like
array[str.charAt(i)]++
instead of that if/else branch, and then on the output, just dofor(int i = 0; i < length; ++i) if(array[i] != 0) System.out.println((char)i + " = " + array[i])
. -
Marcelo over 9 yearsI corrected the meta character issue in the answer.
-
Kaveesh Kanwal about 9 yearsBut, what if we have to find each character's occurrence in the string?
-
RajaReddy PolamReddy over 8 yearsthis is the best way :)
-
Hirofumi Okino over 8 yearsThat still doesn't work with trailing "$"s, e.g. "abdsd3$asda$asasdd$sadas$" , because empty trailing items are ignored by default. It should be
int counter = s.split("\$", -1).length - 1;
-
Yeti almost 8 years
"\$"
should be replaced with"\\$"
, because the backslash already has a special meaning that is unique to the string itself, such as newlines, tabs, etc. (escape character) Therefore a double backslash is needed. -
Sameer Kazi over 6 yearswaw super like !
-
oyenigun over 6 yearsit doesn't work in case of last char searching ex:"356595".split("5") -> size =3 "356559".split("5") -> size = 4
-
Kalpak Gadre over 6 yearsI always prefer apache commons
-
Integraty_beast over 4 yearscan't understand clearly