到目前为止,这是我尝试过的:
public class CharacterCounter {
public static void main(String[] args){
String string = "sashimi";
int count = 0;
for(int i =0; i < string.length(); i++){
if(string.charAt(i) == 'i'){
count++;
}
}
System.out.println("The number of letter i is " + count);
}
}
输出:
The number of letter i is 2
但我想做的是,程序应该计算最常出现的字符。
例如这里的字符串是SASHIMI,输出应该是:
the number of letter S is 2
the number of letter I is 2
我被这个问题困扰了。我需要你的帮助。谢谢。
最佳答案
这将是最快的方法:
final int[] counts = new int[1<<16];
for (char c : <your_string>)
counts[c]++;
(我刚刚勾画出了迭代所有字符的部分,我相信这是简单的部分,与这个问题没有直接关系)。
基准测试结果
我用三个字符串长度将 HashMap
方法与我的方法进行了比较:
- 10
- 1,000
- 100,000
这些是结果:
Benchmark Mode Thr Cnt Sec Mean Mean error Units
testArray1 thrpt 1 5 5 6.870 0.083 ops/msec
testArray2 thrpt 1 5 5 6.720 0.374 ops/msec
testArray3 thrpt 1 5 5 3.770 0.019 ops/msec
testHashMap1 thrpt 1 5 5 1269.123 251.766 ops/msec
testHashMap2 thrpt 1 5 5 12.776 0.165 ops/msec
testHashMap3 thrpt 1 5 5 0.141 0.005 ops/msec
它们是什么意思?是的,将整个 512K 内存块初始化为零是昂贵的。但支付之后,我的数组算法几乎没有注意到数千个字符呼啸而过。另一方面,HashMap
方法对于非常短的字符串要快得多,但扩展性却要差得多。我猜交叉的字符串长度约为 2k。
我想,这样的字符计数统计数据通常是针对大量文本语料库运行的,而不是像你的名字和姓氏这样的东西,这是没有争议的。
当然,如果您可以假设不会使用完整的 UTF-16 代码点范围,则可以大幅提高数组方法的性能。例如,如果您使用仅容纳最低 1024 个代码点的数组,性能将升至 470 操作/毫秒。
关于java - Java中的字符计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17995021/