我如何计算一个字符在字符串中出现的次数?

我有字符串

a.b.c.d

我想数一下'的出现次数。,最好是一句单句俏皮话。

(之前我把这个约束表述为“不使用循环”,以防你想知道为什么每个人都试图在不使用循环的情况下回答)。

979804 次浏览

迟早,某物必须循环。编写(非常简单的)循环要比使用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;
}

那么你不需要在你的主代码中有循环-但循环必须在那里的某个地方。

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

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

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

ReplaceAll(".")将替换所有字符。

PhiLho的解决方案使用ReplaceAll("[^.]",""),不需要转义,因为[. .]]表示字符“点”,而不是“任何字符”。

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

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

好的,受Yonatan解决方案的启发,这里有一个是纯粹的递归-唯一使用的库方法是length()charAt(),它们都不做任何循环:

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是否都做尾递归…当然,如果不是这样,对于适当长的字符串就会出现同名堆栈溢出。

虽然方法可以隐藏它,但没有循环(或递归)就无法计数。但出于性能考虑,您希望使用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)听起来不是最好的方法。

灵感来自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;
}

在代码的某个地方,某些东西必须循环。解决这个问题的唯一方法是完全展开循环:

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

这是一个稍微不同风格的递归解决方案:

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

一个简短的例子是

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

我对此的“惯用语”是:

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

既然已经在commons lang中,为什么还要自己编写呢?

Spring Framework的线性程序是:

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

试试这个方法:

StringTokenizer stOR = new StringTokenizer(someExpression, "||");
int orCount = stOR.countTokens()-1;
如果你正在使用Spring框架,你也可以使用“StringUtils”类。 方法是"countOccurrencesOf"

为什么不只是分割字符,然后得到结果数组的长度。数组长度总是实例数+ 1。对吧?

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

这个怎么样。它没有在底层使用regexp,因此应该比其他一些解决方案更快,并且不会使用循环。

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

完整的示例:

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
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

不确定这样做的效率,但这是我在不引入第三方库的情况下所能写的最短代码:

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

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

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

只使用J2SE,在1行或更少的时间内,无需需要收集的额外分配。

下面的源代码会给你答案。在用户输入的单词中出现给定字符串的次数:-

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


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

你为什么要避开这个循环?我的意思是,如果不检查字符串的每一个字符,你就不能计算“numberOf”点,如果你调用任何函数,它都会以某种方式循环。这是字符串。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;
}
String s = "a.b.c.d";
long result = s.chars().filter(ch -> ch == '.').count();

我的“惯用的一句话”解决方案:

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

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

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

使用,你也可以使用流来实现这一点。显然,在幕后有一个迭代,但您不必显式地编写它!

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

那么下面的递归算法呢?这也是线性时间。

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>

我看到过很多这样的花招。现在我不反对漂亮的技巧,但就我个人而言,我喜欢简单地调用的意思的方法来做这项工作,所以我创建了另一个答案。

注意,如果性能有问题,请改用乔恩·斯基特的回答。在我看来,这个更一般化,因此可读性稍强(当然,对于字符串和模式也可重用)。

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

我试图用一个开关语句来解决你的问题,但我仍然需要一个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);
}

试试下面的代码:

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


}
好吧,在一个非常相似的任务中,我偶然发现了这个线程。 我没有看到任何编程语言的限制,因为groovy运行在java虚拟机上: 下面是我如何能够解决我的问题使用Groovy
"a.b.c.".count(".")

完成了。

总结一下其他的答案,以及我所知道的所有用一句话来做到这一点的方法:

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

1)使用Apache Commons

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

2)使用Spring框架的

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),可能比情况1对unicode更好

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,对于a.b.c.d它将工作,但对于a…b.c....D或a.b.c。D或a....b......c..... D…等等,它不会工作。这只是有意义的。字符之间只有一次

更多信息在github

性能测试(使用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

您可以在一行代码中使用split()函数

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

如果你想数不。字符串'SELENIUM'中的相同字符,或者你想打印字符串'SELENIUM'中的唯一字符。

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

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

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

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

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

输出:

3

使用# EYZ0

int count = Strings.asChars("a.b.c.d").count(c -> c == '.');

如果你有多个字符需要计数,你可以使用CharBag,如下所示:

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

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

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


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

好吧,这是一个了解Java的情况,特别是对Java中已经可用的集合类的基本理解。如果你看了整篇文章,除了斯蒂芬·霍金对宇宙起源的解释,达尔文关于进化论的平装书,以及吉恩·罗登贝瑞的《星际迷航》演员选择,他们为什么选择威廉·夏特纳,除了如何快速简单地做到这一点……

... 我还需要多说吗?

public static void 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]);
}




}
}

使用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));
}
< p > # EYZ0
计数是before-length和after-length的差值

String s = "a.b.c.d";
int count = s.length() - deleteChars.apply( s, "." ).length();  // 3

find deleteChars here


如果你需要计算多个字符的出现次数,你可以一次性完成:
如。对于b c.:

int count = s.length() - deleteChars.apply( s, "bc." ).length();  // 5

一个更简单的解决方案是根据匹配的字符拆分字符串。

例如,

int getOccurences(字符串字符,字符串){ 字符串[]words = String .split(字符); 回来的话。长度- 1; 代码}< / > < / p > 在以下情况下返回4: # EYZ0 < / p >

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

希望有人觉得有用。

    private long countOccurrences(String occurrences, char findChar){
return  occurrences.chars().filter( x -> {
return x == findChar;
}).count();
}
< p > # EYZ0
不需要外部库。
创建一个包含每个字符计数的映射:

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}
某一人物的数目。'.':
# EYZ0 < / p >

(出于病态的好奇心,我也写了一个lambda解,想知道我的解有多慢,最好是来自有10行解的人。)

这里是最简单和容易理解的,不使用数组,只需使用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);
            

}
    

}
< p > <强> O / p: {e = r = 12日13}< /强> < / >强

第二个输入:

findchars("The world is beautiful and $#$%%%%%%@@@@ is worst");
< p > <强> O / p: {@ = 4 = 7, = 2, b = 1, # = 1, d = 2, = 2美元,e = 2, % = 6 f = 1, h = 1, i = 3 l = 2, n = 1, o = 2, r = 2, = 3, T = 1, T = 2, u = 2, w = 2} < /强> < / >强

 public static String encodeMap(String plainText){
        

Map<Character,Integer> mapResult=new LinkedHashMap<Character,Integer>();
String result = "";
for(int i=0;i<plainText.length();i++){
if(mapResult.containsKey(plainText.charAt(i))){
Integer v =mapResult.get(plainText.charAt(i));
mapResult.put(plainText.charAt(i), v+1);
}else{
mapResult.put(plainText.charAt(i), 1);
}
}
        

for(Map.Entry<Character, Integer> t : mapResult.entrySet()) {
result += String.valueOf(t.getKey())+t.getValue();
}
        

return result;
        

}


public static void main(String args[]) {
String  plainText = "aaavvfff";
System.out.println(encodeMap(plainText)); //a3v2f3
}