gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:12:53 26 4
gpt4 key购买 nike

我创建了一个方法来查找字符串中最常见的字符:

public static char getMax(String s) {

char maxappearchar = ' ';
int counter = 0;
int[] charcnt = new int[Character.MAX_VALUE + 1];


for (int i = 0 ; i < s.length() ; i++)
{
char ch = s.charAt(i);
// increment this character's cnt and compare it to our max.
charcnt[ch]++ ;
if (charcnt[ch] >= counter)
{
counter = charcnt[ch];
maxappearchar = ch;
}
}
System.out.println("the max char is " +maxappearchar + " and displayed " +counter+ " times");
return maxappearchar;
}

我在询问不同的解决方案:

  • 解决方案 1 - 最快的代码(这是我附加的代码吗?)
  • 解决方案 2 - 在内存方面最有效,减少数组和变量的使用

我使用 HashMap 创建了我的方法 - 它更适合解决方案 2 吗?如果是,为什么?优点/缺点是什么?

附件代码是否适用于 o 技术(o^,o logn ...)?如果是,为什么?

最佳答案

最快的方法是计算每个字符的出现次数,然后取计数数组中的最大值。如果您的字符串很长,在遍历字符串中的字符时不跟踪当前最大值,您将获得不错的加速。

参见 How to count frequency of characters in a string?有关如何计算频率的许多其他想法。

如果您的字符串主要是 ASCII,那么计数循环中的一个分支可以在低 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<Character,Integer> nonascii_count = new HashMap<Character,Integer>();

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 如果有容器可以插入- 1 -or-increment 操作比 HashMap 更有效 getput一对。 https://stackoverflow.com/a/6712620/224132建议 Guava MultiSet<Character> ,看起来不错。


这可能比您的 2^16 int 数组做得更好秒。但是,如果您只接触过该数组的低位 128 个元素,那么可能永远不会接触到大部分内存。已分配但未触及的内存并没有真正的伤害,也不会耗尽 RAM/swap。

但是,在末尾遍历所有 65536 个条目意味着至少要读取它,因此操作系统必须软页面错误并将其连接起来。它会污染缓存。所以实际上,更新每个角色的最大值可能是更好的选择。微基准测试可能表明迭代字符串,然后遍历 charcnt[Character.MAX_VALUE]赢了,但这并不能解释接触那么多并不真正需要的内存所造成的缓存/TLB 污染。

关于java - 查找字符串中最常见字符的更有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31990103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com