为什么字典替换字符串表现异常?

时间:2015-02-03 18:58:09

标签: c#

我的申请表中有一本字典如下:

Dictionary<char, char> securityDictionary 
    = new Dictionary<char, char>
      {
          {'A', 'Q'}, {'B', 'W'}, {'C', 'E'}, {'D', 'R'}, {'E', 'T'}, 
          {'F', 'Y'}, {'G', 'U'}, {'H', 'I'}, {'I', 'O'}, {'J', 'P'}, 
          {'K', '1'}, {'L', 'A'}, {'M', '2'}, {'N', '3'}, {'O', 'S'}, 
          {'P', '4'}, {'Q', 'D'}, {'R', 'F'}, {'S', '5'}, {'T', 'G'}, 
          {'U', 'Z'}, {'V', 'X'}, {'W', '6'}, {'X', 'C'}, {'Y', '7'}, 
          {'Z', '8'}, {'0', 'V'}, {'1', '9'}, {'2', 'B'}, {'3', '0'}, 
          {'4', 'N'}, {'5', 'M'}, {'6', 'H'}, {'7', 'J'}, {'8', 'K'}, 
          {'9', 'L'}
      };

现在,我将字符串传递给此字典,如下所示:

string KeyFromClient = "QWERTYUIOPASDFGHJKLZXCVB";

Console.WriteLine(KeyFromClient);

foreach (KeyValuePair<char, char> c in securityDictionary.ToList())
{
    KeyFromClient = KeyFromClient.Replace(c.Key, c.Value);
}

Console.WriteLine(KeyFromClient);

现在这是我的输出:

QWERTYUIOPASDFGHJKLZXCVB
DHGFGJKMMNDMFJKMNLAKCGCH

但是我认为输出应该如下所示,因为我只是告诉我的程序通过查看字典替换字符串中的每个字符:

QWERTYUIOPASDFGHJKLZXCVB
D6TFG7ZOS4Q5RYUIP1A8CE0W

2 个答案:

答案 0 :(得分:7)

您不止一次更换某些字符。

考虑最后一个角色。最初它是B。首先,您的循环使用B替换所有W个字符。稍后,它会使用W替换所有6个字符。稍后它会用6替换所有H个字符,这是我们在输出的最终位置看到的字符。

尝试按顺序替换每个字符,如下所示:

var transformedKey = new System.Text.StringBuilder();
foreach (char original in KeyFromClient)
    transformedKey.Append(securityDictionary[original]);
Console.WriteLine(transformedKey.ToString());
如果你更喜欢Linq,那么马特·伯兰德的答案有一个很好的例子。

答案 1 :(得分:2)

您的问题是您将替换应用于部分编码的字符串,导致已编码的字符被编码为第二(或第三或第四)时间。

简单的一行修复:

var output = new string(KeyFromClient.Select(c => securityDictionary[c]).ToArray());

[注意:如果您怀疑输入字符串可能包含在您的dictonary中未包含的值,则可能值得测试密钥存在于字典中

循环遍历原始字符串,并为每个字符查找字典中的相应条目并从中构建新字符串。

无论如何,循环字符串而不是字典会更有效。

对于您的示例,使用带有n条目和长度为m的字符串的词典,您将成为O(nm),因为对于字典中的所有n条目您需要搜索字符串的所有m个字符才能进行替换。通过循环字符串,您只循环m次,因为字典查找是O(1),所以整体O(m)