Easy way to count characters in a string

Is there an easy way (instead of manually moving the entire line or loop for indexOf) to find out how many times a character appears in a line?

Say we have "abdsd3 $ asda $ asasdd $ sadas" and we want $ to appear 3 times.

+57
java string
May 23 '11 at 17:30
source share
15 answers
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 by far the fastest way. Regular expressions here are much slower and harder to understand.

+102
May 23 '11 at 17:33
source share

Functional style (Java 8, just for fun):

 str.chars().filter(num -> num == '$').count() 
+45
May 28 '14 at 8:40
source share

Not an optimal but easy way to count occurrences:

 String s = "..."; int counter = s.split("\\$", -1).length - 1; 

Note:

  • The dollar sign is a special regular expression character, so it must be escaped with a backslash.
  • A backslash is a special character for escape characters, such as newlines, so it must be escaped with a backslash.
  • The second argument to split prevents the removal of empty lines.
+31
May 23 '11 at 17:37
source share

You can use Apache Commons ' StringUtils.countMatches(String string, String subStringToCount) .

+22
Jul 23 '14 at 8:35
source share

Since you are scanning the entire string anyway, you can build a full character counter and make any number of queries, all for the same big-th 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 
+7
May 30 '13 at 6:43
source share

Character frequency is a common task for some applications (such as education), but not common enough to guarantee inclusion in the core Java APIs. So you probably need to write your own function.

+5
May 23 '11 at 17:34
source share

I believe that the β€œone liner” you expected to receive is this:

 "abdsd3$asda$asasdd$sadas".replaceAll( "[^$]*($)?", "$1" ).length(); 

Remember that the requirements are:

( instead of manually moving the entire row or for indexOf )

and let me add: what is at the heart of this question is that "any loop" is not needed, and there is no need for speed. I believe that the subtext of this issue is the cool factor.

+4
Dec 11 '13 at 7:55
source share

you can also use a for each loop. I think this is easier to read.

 int occurrences = 0; for(char c : yourString.toCharArray()){ if(c == '$'){ occurrences++; } } 
+4
Jan 29 '14 at 15:42
source share

Moving a line is probably the most efficient, although using Regex for this can lead to cleaner code (although you can always hide your reverse code in a function).

+3
May 23 '11 at 17:33
source share

Well, there are many different utilities for this, for example. Apache Commons Lang String Utils

but in the end, he has to iterate over the string in order to read the events anyway.

Please also note that the countMatches method mentioned above has the following signature, therefore it will work under substrings as well.

public static int countMatches(String str, String sub)

Source for this (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 repeat the line or use Regex.

+3
May 23 '11 at 17:34
source share

Something 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); } 

This is not a tail recursive, for clarity.

+3
May 28 '14 at 8:22
source share

This is simple code, but of course a 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 recurring question

+2
Nov 23 '13 at 11:11
source share

You can look at the sorting of the string - treat it like a char array - and then do a modified binary search that takes into account the occurrences? But I agree with @tofutim that intersecting it is the most efficient - O (N) compared to O (N * logN) + O (logN)

0
May 23 '11 at 17:36
source share

There is another way to count the number of characters in each line. Suppose we have String as String str = "abfdvdvdfv"

Then we can count the number of times that each character appears, passing only once, when

 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); } } 

Then we can check the output by going through the map as

 for (Map.Entry<String, Integer> entry:map.entrySet()) { System.out.println(entry.getKey()+" count is : "+entry.getValue()) } 
0
Oct 21 '14 at 15:16
source share
  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; } } 
-one
Jan 26 '13 at 15:29
source share



All Articles