Dictionary< char, char>映射一个字母——用唯一的键&值

本文关键字:char 唯一 映射 Dictionary 一个 | 更新日期: 2023-09-27 18:08:40

我需要创建一个Dictionary,它表示字母表中的每个字符与字母表中的另一个字符之间的映射,其中键和值都是唯一的——就像一个非常简单的密码,表示如何编码/解码消息。不能有重复的键或值。

有人看到这段代码有什么问题吗?它仍然在映射中生成重复的,尽管在每次迭代中,对于每个已经使用的值,可用字符池会减少。

        string source_alphabet = _alphabet; //ie "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        string target_alphabet = _alphabet;
        Dictionary<char, char> _map = new Dictionary<char, char>();
        for (int i = 0; i < source_alphabet.Length; i++)
        {
            int random = _random.Next(target_alphabet.Length - 1); //select a random index
            char _output = target_alphabet[random]  //get the char at the random index
            _map.Add(source_alphabet[i], _output); //add to the dictionary
            target_alphabet = target_alphabet.Replace(_output.ToString(), string.Empty); 
            // remove the char we just added from the remaining alphabet
        } 

谢谢。

Dictionary< char, char>映射一个字母——用唯一的键&值

我会考虑对一个或两个字母表序列执行简单的Fisher Yates洗牌,然后您可以简单地遍历输出并将映射器放在一起。

伪代码
Shuffle(sequence1)
Shuffle(sequence2)
for index 0 to 25
    dictionary add sequence1[index], sequence2[index]

当你每次都选择一个随机值时,你很有可能会遇到碰撞,因此选择了一个非唯一的值。答案通常是洗牌,然后按顺序选择。

"一个快速修复"虽然不是最佳的(如果映射a到a是不允许的)

 int random = _random.Next(target_alphabet.Length - 1);
 while ( source_alphabet[i] == target_alphabet[random] ) {random = _random.Next(target_alphabet.Length - 1);};

如果允许A到A的映射,则忽略上述更改…但是至少把最后一行改成

target_alphabet = target_alphabet.Remove ( random, 1 );

我想你可以在target_alphabet上添加另一个"for"循环,在现有的"for"循环中,检查字符是否与小的"if"条件不相同,如果相同,则继续内循环,如果不相同,则中断。

可以了

 for (int i = 0; i < source_alphabet.Length; i++)
    {
        int random = _random.Next(target_alphabet.Length - 1); //select a random index
        char _output = target_alphabet[random];  //get the char at the random index

        _map.Add(source_alphabet[i], _output); //add to the dictionary
        // remove the char we just added from the remaining alphabet
        target_alphabet = target_alphabet.Remove(random, 1);

    }