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

621
我有一个字符串
a.b.c.d
我希望以惯用方式计算“.”的出现次数,最好是一行代码解决。
(之前我曾表达过这个限制条件为“不使用循环”,以防你想知道为什么每个人都试图回答而不使用循环)。

1
作业?否则我看不出避免循环的要求。 - PhiLho
26
不是不喜欢使用循环,只是在寻找一个惯用语的一行代码。 - Bart
2
循环语句就是为了解决这样的问题而设计的,在通用工具类中编写循环,然后调用你刚创建的一行代码。 - che javara
字符串相关的类似问题:https://dev59.com/_HRA5IYBdhLWcg3w9ivq - koppor
显示剩余2条评论
48个回答

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

    }
}

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

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

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

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

1

一个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行解决方案的人那里得到更慢的解决方案。)


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

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

嗯,这是关于了解你的Java,特别是你已经可用的Java集合类的基本基础理解。如果你在整个帖子中查看,除了史蒂芬·霍金对宇宙起源的解释、达尔文进化论的平装书和基因·罗登伯里的《星际迷航》演员选择之外,几乎什么都有,就是如何快速轻松地完成这项工作...

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


1
你能否在发布代码之前添加一些解释说明吗? - MLavrentyev
这会创建一个parts数组,需要分配内存并稍后进行垃圾回收。完全没有必要的开销。尝试在紧密循环中执行此操作。 - Palec
1
除此之外,分割点应该使用split("\.")吧? - Tobias Reich
此外,如果字符串是“foo.”,结果将与字符串为“bar”时相同。 - dekaru

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

0
尝试这个方法:
StringTokenizer stOR = new StringTokenizer(someExpression, "||");
int orCount = stOR.countTokens()-1;

我给你点个踩。它并不总是返回有效的结果,例如如果我们在字符串“a,a,a,a,a”中计算'a',它返回3而不是5。 - Greg Witczak

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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接