尝试将字母表中的字母替换为字母表中具有相似频率的相应字母

时间:2015-12-14 15:34:21

标签: c# arrays string frequency-analysis alphabet

正如标题所述,我试图用字母表中相应字母替换频率最高的特定字符串中的字母。

例如,如果字符串中包含最多D s,那么我会用D替换所有E,因为这是字母表中最常见的字母,然后,我会继续按照字母频率进行此过程...

所以我有一个镜头,但我的输出是完全错误的。

我对progroqamming完全陌生,所以我很抱歉,如果这一切都令你感到厌恶,但我仍然希望以我已经关注的格式来做这件事。

我将我的代码链接如下,我已经用几个单独的方法完成了,我想知道是否有人能发现我遇到的问题。

我相信它正在替换错误的字母,但我真的不知道,我之前只做了一个简单的ceasar密码,所以这不是一大步,但我真的无法理解我的问题。

哦,请忽略变量名等,他们只是占位符:

public class Decode
{
    public static void doDecode()
    {
        string decoding = File.ReadAllText(@"thing.txt", Encoding.Default);
        string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int counter = 0;
        int amount = 0;
        int[] letterAmounts = new int[26];

        decoding = decoding.Replace(Environment.NewLine, "");
        decoding = decoding.Replace(" ", "");

        foreach (char k in alphabet)
        {
            amount = Advanced.Adv(decoding, k);
            letterAmounts[counter] = amount;
            counter++;
        }
        File.WriteAllText(@"stuff.txt", Change.doChange(decoding, letterAmounts));
        System.Diagnostics.Process.Start(@"stuff.txt");
    }
}

因此,这只是调用其他类并将找到的数字分配给数组

public class Advanced
{
    public static int Adv(string test, char c)
    {
        int count = 0;
        foreach (char x in test)
        {
            if (x == c)
            {
                count = count + 1;
            }
        }

        return count;
    }
}

以前称之为简单计算字母数量

public class Change
{
    public static string doChange(string test, int[] letterAmounts)
    {
        string frequency = "ETAOINSHRDLCUMWFGYPBVKJXQZ";
        char[] mostFrequent = frequency.ToCharArray();
        string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] abc = alphabet.ToCharArray();
        int most = 0;
        int position = 0;
        for (int tester = 0; tester < 26; tester++)
        {
            most = letterAmounts.Max();
            position = Array.IndexOf(letterAmounts, most);
            test = test.Replace(abc[position], mostFrequent[tester]);
            letterAmounts[position] = 0;
        }
        return test;
    }
}

这是我相信问题的所在,但我无法理解为什么,我知道它的混乱,但任何帮助都深受赞赏。

2 个答案:

答案 0 :(得分:0)

只需像这样更改你的代码,它可能会起作用

string decoding = File.ReadAllText(@"thing.txt", Encoding.Default);          
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
decoding = decoding.ToUpper();

答案 1 :(得分:0)

看来这部分做的很奇怪:

for (int tester = 0; tester < 26; tester++)
{
    most = letterAmounts.Max();
    position = Array.IndexOf(letterAmounts, most);
    test = test.Replace(abc[position], mostFrequent[tester]);
    letterAmounts[position] = 0;
}

所以,让我们来看一个&#34; I AM BOB&#34;的示例字符串。这将转换为&#34; IAMBOB&#34;而你的letterAmounts将导致1,1,1,2,1,2。您的上述for循环将执行以下操作:

most = 2;
position = 3; //IndexOf reports the zero-based index.
test = test.Replace(abc[3], mostFrequent[0]);
letterAmounts[3] = 0;

在第一个循环中,它将用“E”替换任何字母,其中没有。在第二个循环中你会得到:

most = 2; //second B.
position = 5; 
test = test.Replace(abc[5], mostFrequent[1]);
letterAmounts[5] = 0;

这一次,您将用“T”替换“E&#”。基本上,你不会取代你认为的那封信。此外,这很好地突出了你可能最终用新的替换以前替换的字母(在这种情况下,你已经在第一个循环中用E&替换了D&#39;但在第二个循环中,那些E&#39; s现在将替换为T&#39;

第一个错误似乎是使用letterAmounts中最大值的索引,然后找到&#39; abc&#39;中的字母。阵列。这些不一定相互对应。大概你想要的实际上是用最频繁的字母代替字母,所以B在第一个循环中带E?如果是这种情况,您需要创建一个List&gt;使您能够记录字母和出现次数。元组还允许您具有重复的条目(与字典不同),这可能在本示例中按照字母B的示例出现。

然后返回元组列表中的字母并使用它来进入替换的abc []部分。但是,您仍需要弄清楚如何继续替换已替换的字母。这应该发生吗?