【问题标题】:Trying to replace letters in a string with the corresponding letter in the alphabet with a similar frequency尝试用相似频率的字母表中的相应字母替换字符串中的字母
【发布时间】:2015-12-14 15:34:20
【问题描述】:

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

例如,如果字符串中的Ds 最多,那么我会将所有Ds 替换为E,因为这是字母表中最常见的字母,然后我将继续此过程降低字母频率...

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

我对 progroqamming 完全陌生,如果这一切让你感到厌恶,我很抱歉,但我仍然喜欢以我已经遵循的格式来做。

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

我相信它正在替换错误的字母,但我真的不知道,我之前只做过一个简单的凯撒密码,所以这不是一个很大的步骤,但我真的无法弄清楚出了什么问题。

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

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;
    }
}

这是我认为问题所在,但我无法理解为什么,我再次知道它的混乱,但任何帮助都深表感谢。

【问题讨论】:

  • 有什么问题?你能给出错误的输入、预期输出和实际输出吗?
  • 我不确定您是否尝试将位置设置为发现 Max 的点 in most 或 letterAmounts 的位置。如果您尝试将位置设置为字母数量,那么您需要使用position = letterAmounts.ToList().IndexOf(most);
  • @YacoubMassad 是的,我可以输入但输出错误,我想我现在有了,但谢谢=D
  • @bilpor 是的,我明白你在说什么,但认为 sr28 已经为我解决了,再次感谢你 =D

标签: c# arrays string frequency-analysis alphabet


【解决方案1】:

这部分看起来有些奇怪:

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;
}

那么,让我们来看一个示例字符串“I AM BOB”。这将转换为“IAMBOB”,您的 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;

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

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

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

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

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

【讨论】:

  • 非常感谢您的完整解释,正是我想要的 =D
  • 关于元组/列表这件事的旁注,我从来没有使用过,你会建议制作一个元组列表吗?
  • @Miztingz - 元组列表允许与字典不同的重复条目,这在您的情况下可能是必要的。所以,是的,我认为元组列表是一个好的开始。
  • @Miztingz - 刚刚看到您添加评论的原因。我的清单位在答案中被切断了。它应该读到“您将需要创建一个元组列表,类型为 string 和 int...”。
【解决方案2】:

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

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

【讨论】:

  • 我明白你在说什么,我输入的输入实际上已经大写了,谢谢你非常考虑,我现在就输入这个=D
最近更新 更多