在Java中使用频率分析**的凯撒密码:这是我的解码部分代码:
public static String decode (String code){
int key=0;
final int ALPHABET_SIZE = 26;
int[] freqs = new int[ALPHABET_SIZE];
for (int l=0;l<freqs.length;l++){
freqs[l]=0;
}
for (int k=0;k<code.length();k++){
if (code.charAt(k)>='a' && code.charAt(k)<='z'){
freqs[code.charAt(k)-'a']++;
}
}
int biggest = 0;
for (int t=0;t<freqs.length;t++){
if (freqs[t]>biggest){
biggest= t;
}
}
if (biggest<4){
key = (biggest + 26 - ('e'+'a'));
}
else{
key = biggest + 'a' - 'e';
}
return (decode(code,key));
}
我不能使用映射,导入,列表或添加键,我知道最常见的字母是E,但是我不知道如何在其他函数中实现它。谢谢您提供更优雅的解决方案。 **频率分析
答案 0 :(得分:0)
我不太确定您对“优雅”的定义是什么,但是总体来说您的解决方案看起来不错。
一些评论:
实际上,由于Java会帮您实现这一目的,因此您实际上不必在一开始就手动将数组初始化为0。
在计算字符时可以查找频率最高的字母
例如,for
循环可以变成:
int highestFreq = 0;
int highestFreqIdx = -1;
for (int k=0; k < code.length(); k++) {
if (code.charAt(k) >= 'a' && code.charAt(k) <= 'z') {
int count = freqs[code.charAt(k)-'a']++;
if (count > highestFreq) {
highestFreq = count;
highestFreqIdx = k;
}
}
}
如果我没记错的话,您的关键是频率最高的字母离'e'的位置数。在这种情况下,您只需执行以下操作:
key = biggest - ('e' - 'a');
因此您的代码变为:
public static String decode (String code){
int key = 0;
final int ALPHABET_SIZE = 26;
int[] freqs = new int[ALPHABET_SIZE];
int highestFreq = 0;
int highestFreqIdx = -1;
for (int k=0; k < code.length(); k++) {
if (code.charAt(k) >= 'a' && code.charAt(k) <= 'z') {
int count = freqs[code.charAt(k)-'a']++;
if (count > highestFreq) {
highestFreq = count;
highestFreqIdx = k;
}
}
}
key = highestFreqIdx - ('e' - 'a'); // Can also directly use 4 instead of 'e' - 'a'
return (decode(code, key));
}
也就是说,您的代码仅适用于真正以字母“ e”为最常见字母的邮件...
中,此类代码检查问题可能会更好