频率分析算法

时间:2009-11-27 10:11:44

标签: java string analysis frequency

我想编写一个搜索密文的java程序,并返回密码中字符的频率计数,例如密码: “jshddllpkeldldwgbdpked”会有这样的结果:

出现2个字母:

pk = 2,ke = 2,ld = 2

出现3个字母:

pke = 2。

任何允许我尽可能高效地执行此操作的算法?

8 个答案:

答案 0 :(得分:4)

地图策略很好,但我会选择HashMap<String, Integer>,因为它会计算字符元组。

迭代密文中的字符,您可以保存最后的X个字符,这将为您提供所有出现的长度为X + 1的子字符串的映射。

答案 1 :(得分:2)

通常的做法是使用某种地图将你的角色映射到他们的计数。例如,您可以使用HashMap<Character, Integer>。然后,您可以按字符顺序遍历密文,并将字符放入映射中,计数为1(如果尚不存在)或增加其计数。

答案 2 :(得分:2)

您可以将n-grams存储在trie中,颠倒正常顺序,以便n-gram中的最后一个字符位于trie的顶部。 trie中的每个节点都存储一个字符计数。循环遍历字符串,跟踪最后N个字符(Buhb suggests)。每次通过外循环,你遍历trie,使用最后N个字符来选择路径,从​​最后一个字符开始,以N th 结尾。对于您访问的每个节点,递增其计数器。

要打印n-gram频率,请执行trie的广度优先遍历。

整体表现留作练习。

答案 3 :(得分:1)

要么有一个数组,每个可能的值都有一个单元格(如果密码文本都是小写字符则很容易 - 26 - 如果不是则更难)或者去传递字符的地图并在任一情况下递增值。阵列更快但灵活性更低。

答案 4 :(得分:1)

你可以使用哈希或图形(感谢outis,我现在知道它的特殊名称,这种图形叫做“trie”)。哈希会更慢,图表会更快。哈希将获得更少的内存,图表将在执行不良时花费更多。

你无法使用数组完成它,因为如果你的最大字符序列长度等于文本长度,并且文本足够长,它将获得大量内存。如果你将限制它,它将获得像([number of letters]^[max sequence length])*4个字节的smth,对于4个低/高字母序列将是(52^4)*4 ~= 24Mb的内存。如果有限的序列长度对你来说是正常的,并且这个记忆量是正常的,那么算法对于&lt; = 4个字母依次很容易。

答案 5 :(得分:1)

如果您需要的序列长度集合是固定的,那么明显的算法会采用线性数量的计数操作(例如,在哈希表中查找计数器并递增它)。

当你说“尽可能高效”时,你是否建议花费大量精力进行微小的恒定因子改进,无望地搜索次线性算法,或者你根本不理解算法复杂性类? / p>

答案 6 :(得分:0)

你可以先寻找最大可能的可重复序列然后从那里开始。例如,如果字符串是10个字符,则可能发生的最大可重复序列将是5个字母长,因此首先查找5个字母序列然后查找4个字母,依此类推,直到达到2.这应该减少程序中的迭代次数。 / p>

答案 7 :(得分:0)

我没有想到这个答案,

但我觉得,这个算法与压缩算法用于使用字典方法创建压缩文件的算法完全相同。

如果我没有错,在这种方法中,字典以下列方式使用:

数据:

abccccabaccabcaaaaabcaaabbbbbccccaaabcbbbbabbabab

解析1: 关键:* 值:abc

新数据:

*cccabacc*aaaa*aaabbbbbccccaa*bbbbabbabab

只是一个有根据的猜测,我认为(不确定这里)标准的“zip”文件使用这种方法, 所以我建议你看看这些算法