假设您想在某些文本中计算字符的出现次数。
我能想到的最快的方法是使用类似unsigned char charcounts[256]
的数组,将其初始化为零,然后查看文本输入中的每个字符并执行charcounts[c]++
。然后线性搜索charcounts[]
使用两个变量来跟踪最低(到目前为止)的char及其计数,当我们找到较低的值时将其替换为新的char / count,直到我们结束。
所以“text”将是t = 2,e = 1,x = 1.
有更快的方法吗?
答案 0 :(得分:4)
第一部分 - 计数字母频率 要指出的两个问题,假设这里的语言是C或C ++:
第二部分 - 查找频率最低的字母
答案 1 :(得分:4)
算法的第一部分是对字符进行计数 - 这只是生成按键排序的键。
如果你知道你只使用字母字符[A-Za-z] *那么你可以通过减少使用的桶数来优化你的算法,但这只是一个小小的调整。
第二部分只是一个稳定的排序 - 有很多方法可以做到这一点 - wikipedia page on sorting提供了一个很好的总结。如果您只对最少出现的字符感兴趣,那么您描述的(“阶段2”)方法可能效率最高。
我能想到的另一种改进方法是,如果你可以在字符范围内均匀地将字母分成固定数量的桶(比如16),然后在每个桶上递归。任何没有字符的桶都可以丢弃,在扫描/分拣阶段节省一些时间。同样,如果一个桶有一个字符,那么它就完成了。当你知道其中有多个不同的字符时,你还要确保只将一个桶分成16个。
使用单词test作为示例(假设有4个桶,只有小写字符:
这种方法的优点是我们不必扫描每个字母。如果字符范围大小相同,那么这两种方法最多都是O(n),其中n是字符串的长度(这是不可避免的,因为我们总是要查看每个字符),尽管构造字符列表我的例子可能会使算法与O(n ^ 2)一样糟糕。但是随着字符范围的增加,特别是对于短字符串,使用子存储桶将大大提高性能。对于unicode字符串,您可以使用混合方法 - 例如,在第一阶段中分离所有非ascii字符,并使用更简单的方法用于ascii部分。
答案 2 :(得分:1)
你在这里描述了两个任务。第一种是计算流中每个ASCII字符出现的次数,第二种是尝试查找最低频率的字符。
第一个算法看起来非常有效。我无法想到更快的方式。
但是,我不太确定你的第二个算法。您没有明确说明为什么要查找频率最低的字符或输入数据是什么,但我可以想象很容易有多个频率计数为零的字符,那么您希望如何区分它们?答案 3 :(得分:0)
这听起来像是你所描述的最有效的方法之一。我不确定你想要对第二部分做什么,听起来你想找到排序数据中出现次数最少的字符?