java查找字符串中的字符_java – 查找字符串中最常见字符的更有效方法

2021-04-28 17:53:48 浏览数 (1)

参考链接: Java程序查找一个字符的ASCII值

执行此操作的最快方法是计算每个字符的出现次数,然后取计数数组中的最大值.如果您的字符串很长,那么在循环字符串中的字符时,不会跟踪当前最大值,您将获得不错的加速.

 如果你的字符串主要是ASCII,那么count循环中的一个分支可以在低128字符值的数组或其余的HashMap之间进行选择,这应该是值得的.如果您的字符串没有非ASCII字符,分支将很好地预测.如果在ascii和非ascii之间有很多交替,那么与使用HashMap处理所有内容相比,分支可能会受到一些伤害.

 public static char getMax(String s) {

 char maxappearchar = ' ';

 int counter = 0;

 int[] ascii_count = new int[128]; // fast path for ASCII

 HashMap nonascii_count = new HashMap();

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

 {

 char ch = s.charAt(i); // This does appear to be the recommended way to iterate over a String

 // alternatively, iterate over 32bit Unicode codepoints, not UTF-16 chars, if that matters.

 if (ch < 128) {

 ascii_count[ch] ;

 } else {

 // some code to set or increment the nonascii_count[ch];

 }

 }

 // loop over ascii_count and find the highest element

 // loop over the keys in nonascii_count, and see if any of them are even higher.

 return maxappearchar;

 }

 我没有充实代码,因为我没有做很多Java,所以IDK如果有一个容器,那么比HashMap get和put对更有效地执行insert-1-increment操作. https://stackoverflow.com/a/6712620/224132建议Guava MultiSet< Character>,看起来不错.

 这可能比你的2 ^ 16整数数组更好.但是,如果您只触摸此阵列的低128个元素,则可能永远不会触及大部分内存.分配但未触及的内存并没有真正伤害,或者耗尽RAM /交换.

 但是,在末尾循环遍历所有65536个条目意味着至少读取它,因此操作系统必须对其进行软页面故障并将其连接起来.它会污染缓存.实际上,更新每个角色的最大值可能是更好的选择. Microbenchmarks可能会显示迭代字符串,然后循环遍历charcnt [Character.MAX_VALUE]获胜,但这不会解释缓存/ TLB污染触及那么多非真正需要的内存.

0 人点赞