如何计算字符串中char的出现次数?

时间:2008-11-09 14:07:09

标签: java string

我有字符串

a.b.c.d

我想计算'。'的出现次数。以惯用的方式,最好是单行。

(之前我曾把这个约束表达为“没有循环”,如果你想知道为什么每个人都试图回答而不使用循环)。

47 个答案:

答案 0 :(得分:956)

这个怎么样?它不使用下面的regexp,所以应该比其他一些解决方案更快,并且不会使用循环。

int count = line.length() - line.replace(".", "").length();

答案 1 :(得分:677)

我的'惯用单行'是:

int count = StringUtils.countMatches("a.b.c.d", ".");

为什么当它已经在commons lang时自己写?

Spring Framework的oneliner就是:

int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");

答案 2 :(得分:244)

总结其他答案以及我所知道的使用单行的所有方法:

   String testString = "a.b.c.d";

1)使用 Apache Commons

int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);

2)使用 Spring Framework&#39>

int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);

3)使用替换

int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);

4)使用 replaceAll (案例1)

int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);

5)使用 replaceAll (案例2)

int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);

6)使用拆分

int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);

7)使用 Java8 (案例1)

long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);

8)使用 Java8 (案例2),对于unicode可能比案例1更好

long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);

9)使用 StringTokenizer

int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);

来自评论:小心使用StringTokenizer,对于abcd它可以工作但是对于... bc ... d或... abcd或者...... b ... ...... c ...... d ......等不起作用。它只是值得。字符之间只有一次

github

中的更多信息

Perfomance test(使用JMH,模式=平均时间,得分0.010优于0.351):

Benchmark              Mode  Cnt  Score    Error  Units
1. countMatches        avgt    5  0.010 ±  0.001  us/op
2. countOccurrencesOf  avgt    5  0.010 ±  0.001  us/op
3. stringTokenizer     avgt    5  0.028 ±  0.002  us/op
4. java8_1             avgt    5  0.077 ±  0.005  us/op
5. java8_2             avgt    5  0.078 ±  0.003  us/op
6. split               avgt    5  0.137 ±  0.009  us/op
7. replaceAll_2        avgt    5  0.302 ±  0.047  us/op
8. replace             avgt    5  0.303 ±  0.034  us/op
9. replaceAll_1        avgt    5  0.351 ±  0.045  us/op

答案 3 :(得分:170)

迟早,某事必须循环。编写(非常简单)循环比使用像split这样比你需要的强大得多的东西要简单得多。

一定要将循环封装在一个单独的方法中,例如

public static int countOccurrences(String haystack, char needle)
{
    int count = 0;
    for (int i=0; i < haystack.length(); i++)
    {
        if (haystack.charAt(i) == needle)
        {
             count++;
        }
    }
    return count;
}

然后你不需要在主代码中使用循环 - 但循环必须在某处。

答案 4 :(得分:61)

我有一个类似于Mladen的想法,但恰恰相反......

String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);

答案 5 :(得分:35)

String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();

ReplaceAll(“。”)将替换所有字符。

PhiLho's solution使用ReplaceAll(“[^。]”,“”),它不需要转义,因为[。]代表字符'dot',而不是'任何字符'。

答案 6 :(得分:27)

我的'惯用单线'解决方案:

int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();

不知道为什么接受使用StringUtils的解决方案。

答案 7 :(得分:26)

String s = "a.b.c.d";
long result = s.chars().filter(ch -> ch == '.').count();

答案 8 :(得分:22)

一个较短的例子是

String text = "a.b.c.d";
int count = text.split("\\.",-1).length-1;

答案 9 :(得分:17)

这是一个没有循环的解决方案:

public static int countOccurrences(String haystack, char needle, int i){
    return ((i=haystack.indexOf(needle, i)) == -1)?0:1+countOccurrences(haystack, needle, i+1);}


System.out.println("num of dots is "+countOccurrences("a.b.c.d",'.',0));

嗯,有一个循环,但它是不可见: - )

- Yonatan

答案 10 :(得分:14)

我不喜欢为此目的分配新字符串的想法。并且由于字符串后面已经有一个char数组,它存储了它的值,String.charAt()实际上是免费的。

for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))

只需要J2SE即可完成技巧,无需额外分配需要收集,只需1行或更少。

答案 11 :(得分:13)

好的,在Yonatan的解决方案的启发下,这是一个纯粹递归的方法 - 使用的唯一库方法是length()charAt(),它们都没有进行任何循环:< / p>

public static int countOccurrences(String haystack, char needle)
{
    return countOccurrences(haystack, needle, 0);
}

private static int countOccurrences(String haystack, char needle, int index)
{
    if (index >= haystack.length())
    {
        return 0;
    }

    int contribution = haystack.charAt(index) == needle ? 1 : 0;
    return contribution + countOccurrences(haystack, needle, index+1);
}

递归计数是否为循环取决于您使用的确切定义,但它可能会尽可能接近。

我不知道这些天大多数JVM是否会进行尾递归...如果不是,你当然会得到适当长串的同名堆栈溢出。

答案 12 :(得分:11)

灵感来自Jon Skeet,一个不会让你的筹码无法破坏的非循环版本。如果你想使用fork-join框架,也是有用的起点。

public static int countOccurrences(CharSequeunce haystack, char needle) {
    return countOccurrences(haystack, needle, 0, haystack.length);
}

// Alternatively String.substring/subsequence use to be relatively efficient
//   on most Java library implementations, but isn't any more [2013].
private static int countOccurrences(
    CharSequence haystack, char needle, int start, int end
) {
    if (start == end) {
        return 0;
    } else if (start+1 == end) {
        return haystack.charAt(start) == needle ? 1 : 0;
    } else {
        int mid = (end+start)>>>1; // Watch for integer overflow...
        return
            countOccurrences(haystack, needle, start, mid) +
            countOccurrences(haystack, needle, mid, end);
    }
}

(免责声明:未经测试,未编译,不合理。)

也许最好的(单线程,没有代理对支持)方式来编写它:

public static int countOccurrences(String haystack, char needle) {
    int count = 0;
    for (char c : haystack.toCharArray()) {
        if (c == needle) {
           ++count;
        }
    }
    return count;
}

答案 13 :(得分:9)

不确定这个效率,但它是我可以编写的最短代码而不引入第三方库:

public static int numberOf(String target, String content)
{
    return (content.split(target).length - 1);
}

答案 14 :(得分:9)

使用您也可以使用流来实现此目的。显然幕后有一个迭代,但你不必明确地写它!

public static long countOccurences(String s, char c){
    return s.chars().filter(ch -> ch == c).count();
}

countOccurences("a.b.c.d", '.'); //3
countOccurences("hello world", 'l'); //3

答案 15 :(得分:7)

完成示例:

public class CharacterCounter
{

  public static int countOccurrences(String find, String string)
  {
    int count = 0;
    int indexOf = 0;

    while (indexOf > -1)
    {
      indexOf = string.indexOf(find, indexOf + 1);
      if (indexOf > -1)
        count++;
    }

    return count;
  }
}

拨打:

int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3

答案 16 :(得分:6)

也可以在Java 8中使用reduce来解决这个问题:

int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);

输出:

3

答案 17 :(得分:5)

如果您使用的是Spring框架,您也可以使用“StringUtils”类。 该方法将是“countOccurrencesOf”。

答案 18 :(得分:5)

获得答案的最简单方法如下:

public static void main(String[] args) {
    String string = "a.b.c.d";
    String []splitArray = string.split("\\.");
    System.out.println("No of . chars is : " + splitArray.length-1);
}

答案 19 :(得分:4)

您只需使用一行代码中的split()功能

即可
int noOccurence=string.split("#").length-1;

答案 20 :(得分:4)

import java.util.Scanner;

class apples {

    public static void main(String args[]) {    
        Scanner bucky = new Scanner(System.in);
        String hello = bucky.nextLine();
        int charCount = hello.length() - hello.replaceAll("e", "").length();
        System.out.println(charCount);
    }
}//      COUNTS NUMBER OF "e" CHAR´s within any string input

答案 21 :(得分:3)

public static int countOccurrences(String container, String content){
    int lastIndex, currIndex = 0, occurrences = 0;
    while(true) {
        lastIndex = container.indexOf(content, currIndex);
        if(lastIndex == -1) {
            break;
        }
        currIndex = lastIndex + content.length();
        occurrences++;
    }
    return occurrences;
}

答案 22 :(得分:3)

虽然方法可以隐藏它,但没有循环(或递归)就无法计数。出于性能原因,您希望使用char []。

public static int count( final String s, final char c ) {
  final char[] chars = s.toCharArray();
  int count = 0;
  for(int i=0; i<chars.length; i++) {
    if (chars[i] == c) {
      count++;
    }
  }
  return count;
}

使用replaceAll(即RE)听起来不是最佳方式。

答案 23 :(得分:2)

这是一种略有不同的样式递归解决方案:

public static int countOccurrences(String haystack, char needle)
{
    return countOccurrences(haystack, needle, 0);
}

private static int countOccurrences(String haystack, char needle, int accumulator)
{
    if (haystack.length() == 0) return accumulator;
    return countOccurrences(haystack.substring(1), needle, haystack.charAt(0) == needle ? accumulator + 1 : accumulator);
}

答案 24 :(得分:2)

嗯,有一个非常相似的任务我偶然发现了这个线程。 我没有看到任何编程语言限制,因为groovy在java vm上运行: 以下是我使用Groovy解决问题的方法。

"a.b.c.".count(".")

完成。

答案 25 :(得分:2)

int count = (line.length() - line.replace("str", "").length())/"str".length();

答案 26 :(得分:2)

使用Eclipse Collections

int count = CharAdapter.adapt("a.b.c.d").count(c -> c == '.');

如果要计算多个字符,可以使用CharBag,如下所示:

CharBag bag = CharAdapter.adapt("a.b.c.d").toBag();
int count = bag.occurrencesOf('.');

注意:我是Eclipse Collections的提交者。

答案 27 :(得分:2)

以下源代码将为您提供用户输入的单词中给定字符串的出现次数: -

import java.util.Scanner;

public class CountingOccurences {

    public static void main(String[] args) {

        Scanner inp= new Scanner(System.in);
        String str;
        char ch;
        int count=0;

        System.out.println("Enter the string:");
        str=inp.nextLine();

        while(str.length()>0)
        {
            ch=str.charAt(0);
            int i=0;

            while(str.charAt(i)==ch)
            {
                count =count+i;
                i++;
            }

            str.substring(count);
            System.out.println(ch);
            System.out.println(count);
        }

    }
}

答案 28 :(得分:2)

代码中的某处,必须循环。解决这个问题的唯一方法是完全展开循环:

int numDots = 0;
if (s.charAt(0) == '.') {
    numDots++;
}

if (s.charAt(1) == '.') {
    numDots++;
}


if (s.charAt(2) == '.') {
    numDots++;
}

...等等,但是你是那个在源编辑器中手动执行循环的人 - 而不是运行它的计算机。请参阅伪代码:

create a project
position = 0
while (not end of string) {
    write check for character at position "position" (see above)
}
write code to output variable "numDots"
compile program
hand in homework
do not think of the loop that your "if"s may have been optimized and compiled to

答案 29 :(得分:2)

为什么不分割字符然后获得结果数组的长度。数组长度总是实例数+ 1.对吗?

答案 30 :(得分:1)

String[] parts = text.split(".");
int occurances = parts.length - 1;

" It's a great day at O.S.G. Dallas! "
     -- Famous Last Words

嗯,这是了解Java的一个案例,尤其是您对Java中已有的集合类的基本理解。如果你仔细观察整篇文章的内容,那么斯蒂芬霍金对宇宙起源的解释,达尔文关于进化的平装本以及基因罗登伯里的星际迷航演员选择都是如此。为什么他们和William Shatner一起去了解如何快速轻松地做到这一点......

......我还需要说吗?

答案 31 :(得分:1)

试试这个方法:

StringTokenizer stOR = new StringTokenizer(someExpression, "||");
int orCount = stOR.countTokens()-1;

答案 32 :(得分:1)

我看到很多技巧和使用。现在我并不反对美妙的技巧,但我个人只想简单地调用意味着的方法来完成工作,所以我已经创造了另一个答案。

请注意,如果性能有任何问题,请改用Jon Skeet's answer。这个有点概括,因此在我看来稍微更具可读性(当然,可以重复使用字符串和模式)。

public static int countOccurances(char c, String input) {
    return countOccurancesOfPattern(Pattern.quote(Character.toString(c)), input);
}

public static int countOccurances(String s, String input) {
    return countOccurancesOfPattern(Pattern.quote(s), input);
}

public static int countOccurancesOfPattern(String pattern, String input) {
    Matcher m = Pattern.compile(pattern).matcher(input);
    int count = 0;
    while (m.find()) {
        count++;
    }
    return count;
}

答案 33 :(得分:1)

你为什么试图避免循环?我的意思是你不能计算“numberOf”点而不检查字符串的每个字符,如果你调用任何函数,它会以某种方式循环。也就是说,String.replace应该循环验证字符串是否出现,以便它可以替换每一次出现。

如果您正在尝试减少资源使用量,则不会这样做,因为您正在创建一个新的字符串,仅用于计算点数。

现在,如果我们谈论递归的“在这里输入代码”方法,有人说它会因OutOfMemmoryException而失败,我想他忘记了StackOverflowException。

所以我的方法就像这样(我知道它和其他人一样但是,这个问题需要循环):

public static int numberOf(String str,int c) {
    int res=0;
    if(str==null)
        return res;
    for(int i=0;i<str.length();i++)
        if(c==str.charAt(i))
            res++;
    return res;
}

答案 34 :(得分:1)

 public static int countSubstring(String subStr, String str) {

    int count = 0;
    for (int i = 0; i < str.length(); i++) {
        if (str.substring(i).startsWith(subStr)) {
            count++;
        }
    }
    return count;
}

答案 35 :(得分:0)

试试这段代码:

package com.java.test;

import java.util.HashMap;
import java.util.Map;

public class TestCuntstring {

    public static void main(String[] args) {

        String name = "Bissssmmayaa";
        char[] ar = new char[name.length()];
        for (int i = 0; i < name.length(); i++) {
            ar[i] = name.charAt(i);
        }
        Map<Character, String> map=new HashMap<Character, String>();
        for (int i = 0; i < ar.length; i++) {
            int count=0;
            for (int j = 0; j < ar.length; j++) {
                if(ar[i]==ar[j]){
                    count++;
                }
            }
            map.put(ar[i], count+" no of times");
        }
        System.out.println(map);
    }

}

答案 36 :(得分:0)

如果你想算不上。字符串中的相同字符&#39; SELENIUM&#39;或者您想要打印字符串的唯一字符&#39; SELENIUM&#39;。

public class Count_Characters_In_String {

 public static void main(String []args){

    String s = "SELENIUM";
    System.out.println(s);
    int counter;

   String g = "";

    for( int i=0; i<s.length(); i++ ) { 

    if(g.indexOf(s.charAt(i)) == - 1){
       g=g+s.charAt(i); 
      }

   }
   System.out.println(g + " ");



    for( int i=0; i<g.length(); i++ ) {          
      System.out.print(",");

      System.out.print(s.charAt(i)+ " : ");
      counter=0; 
      for( int j=0; j<s.length(); j++ ) { 

    if( g.charAt(i) == s.charAt(j) ) {
       counter=counter+1;

       }      

      }
      System.out.print(counter); 
   }
 }

}

/ ********************输出********************** /

SELNIUM

S:1,E:2,L:1,E:1,N:1,I:1,U:1

答案 37 :(得分:0)

下面的递归算法怎么样。这也是线性时间。

import java.lang.*;
import java.util.*;

class longestSubstr{

public static void main(String[] args){
   String s="ABDEFGABEF";


   int ans=calc(s);

   System.out.println("Max nonrepeating seq= "+ans);

}

public static int calc(String s)
{//s.s
      int n=s.length();
      int max=1;
      if(n==1)
          return 1;
      if(n==2)
      {
          if(s.charAt(0)==s.charAt(1)) return 1;
          else return 2;


      }
      String s1=s;
    String a=s.charAt(n-1)+"";
          s1=s1.replace(a,"");
         // System.out.println(s+" "+(n-2)+" "+s.substring(0,n-1));
         max=Math.max(calc(s.substring(0,n-1)),(calc(s1)+1));


return max;
}


}


</i>

答案 38 :(得分:0)

使用Java 8和没有任何库的HashMap来计数所有不同的字符:

private static void countChars(String string) {
    HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
    string.chars().forEach(letter -> hm.put(letter, (hm.containsKey(letter) ? hm.get(letter) : 0) + 1));
    hm.forEach((c, i) -> System.out.println(((char)c.intValue()) + ":" + i));
}

答案 39 :(得分:0)

使用lambda函数,该函数会删除所有要计数的字符
计数是前后长度之差

@Html.DropDownList("cmbQuestion", binaryAnswer, "Select your answer", new { @class = "form-control" })

find deleteChars here


如果必须计算一个以上字符的出现次数,可以一键完成:
例如。用于String s = "a.b.c.d"; int count = s.length() - deleteChars.apply( s, "." ).length(); // 3 bc

.

答案 40 :(得分:0)

一种更简单的解决方案是仅根据与之匹配的字符来分割字符串。

例如,

int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }

在以下情况下将返回4: getOccurences("o", "something about a quick brown fox");

答案 41 :(得分:0)

这是我用来计算字符串出现次数的方法。

希望有人会觉得有用。

    private long countOccurrences(String occurrences, char findChar){
        return  occurrences.chars().filter( x -> {
            return x == findChar;
        }).count();
    }

答案 42 :(得分:0)

一个lambda单缸纸
不需要外部库。
创建一个包含每个字符计数的地图:

Map<Character,Long> counts = "a.b.c.d".codePoints().boxed().collect(
    groupingBy( t -> (char)(int)t, counting() ) );

得到:{a=1, b=1, c=1, d=1, .=3}
某个字符的计数,例如'.'被赋予:
counts.get( '.' )

(出于病态的好奇心,我还编写了一个lambda解决方案,以找出我的解决方案有多慢,最好是从有10行解决方案的人那里找到。)

答案 43 :(得分:0)

这里最简单易懂,不用数组,只用Hashmap。它还会计算空格、大写字符和小字符的数量、特殊字符等。

import java.util.HashMap;
  //The code by muralidharan  
    public class FindChars {
        
        public static void main(String[] args) {
            
            findchars("rererereerererererererere");
        }
        
        public static void findchars(String s){
            
            HashMap<Character,Integer> k=new HashMap<Character,Integer>();
            for(int i=0;i<s.length();i++){
                if(k.containsKey(s.charAt(i))){
                Integer v =k.get(s.charAt(i));
                k.put(s.charAt(i), v+1);
                }else{
                    k.put(s.charAt(i), 1);
                }
                
            }
            System.out.println(k);
            
        }
    
    }

O/P: {r=12, e=13}

第二个输入:

findchars("The world is beautiful and $#$%%%%%%@@@@ is worst");

O/P: { =7, @=4, a=2, b=1, #=1, d=2, $=2, e=2, %=6, f=1, h=1, i=3 , l=2, n=1, o=2, r=2, s=3, T=1, t=2, u=2, w=2}

答案 44 :(得分:-1)

公共静态无效getCharacter(String str){

    int count[]= new int[256];

    for(int i=0;i<str.length(); i++){


        count[str.charAt(i)]++;

    }
    System.out.println("The ascii values are:"+ Arrays.toString(count));

    //Now display wht character is repeated how many times

    for (int i = 0; i < count.length; i++) {
        if (count[i] > 0)
           System.out.println("Number of " + (char) i + ": " + count[i]);
    }


}

}

答案 45 :(得分:-3)

public class OccurencesInString { public static void main(String[] args) { String str = "NARENDRA AMILINENI"; HashMap occur = new HashMap(); int count =0; String key = null; for(int i=0;i<str.length()-1;i++){ key = String.valueOf(str.charAt(i)); if(occur.containsKey(key)){ count = (Integer)occur.get(key); occur.put(key,++count); }else{ occur.put(key,1); } } System.out.println(occur); } }

答案 46 :(得分:-4)

我尝试用switch语句解决你的问题,但我仍然需要一个for循环来解析字符串。如果我可以改进代码,请随时发表评论

public class CharacterCount {
public static void main(String args[])
{
    String message="hello how are you";
    char[] array=message.toCharArray();
    int a=0;
    int b=0;
    int c=0;
    int d=0;
    int e=0;
    int f=0;
    int g=0;
    int h=0;
    int i=0;
    int space=0;
    int j=0;
    int k=0;
    int l=0;
    int m=0;
    int n=0;
    int o=0;
    int p=0;
    int q=0;
    int r=0;
    int s=0;
    int t=0;
    int u=0;
    int v=0;
    int w=0;
    int x=0;
    int y=0;
    int z=0;


    for(char element:array)
    {
        switch(element)
        {
        case 'a':
        a++;
        break;
        case 'b':
        b++;
        break;
        case 'c':c++;
        break;

        case 'd':d++;
        break;
        case 'e':e++;
        break;
        case 'f':f++;
        break;

        case 'g':g++;
        break;
        case 'h':
        h++;
        break;
        case 'i':i++;
        break;
        case 'j':j++;
        break;
        case 'k':k++;
        break;
        case 'l':l++;
        break;
        case 'm':m++;
        break;
        case 'n':m++;
        break;
        case 'o':o++;
        break;
        case 'p':p++;
        break;
        case 'q':q++;
        break;
        case 'r':r++;
        break;
        case 's':s++;
        break;
        case 't':t++;
        break;
        case 'u':u++;
        break;
        case 'v':v++;
        break;
        case 'w':w++;
        break;
        case 'x':x++;
        break;
        case 'y':y++;
        break;
        case 'z':z++;
        break;
        case ' ':space++;
        break;
        default :break;
        }
    }
    System.out.println("A "+a+" B "+ b +" C "+c+" D "+d+" E "+e+" F "+f+" G "+g+" H "+h);
    System.out.println("I "+i+" J "+j+" K "+k+" L "+l+" M "+m+" N "+n+" O "+o+" P "+p);
    System.out.println("Q "+q+" R "+r+" S "+s+" T "+t+" U "+u+" V "+v+" W "+w+" X "+x+" Y "+y+" Z "+z);
    System.out.println("SPACE "+space);
}

}