While循环字母表

本文关键字:字母表 循环 While | 更新日期: 2023-09-27 17:50:18

我正在尝试对以下示例进行编码。

Input  ABCDEFGHIJKLMNOPQRSTUVWXYZ
Output  ZYXWVUTSRQPONMLKJIHGFEDCBA

如果用户键入A,它将输出Z。它必须超过25个字符才能到达Z。所以我猜需要一个while循环,如果B,它必须经过23次,所以-2,以此类推,直到它到达M,因为它将跳过1到达N,然后在25再次开始。

关于如何处理这个问题,有什么建议吗?

While循环字母表

根据ASCII表,大写ASCII字符的范围从65(0x41,'A'(到90(0x5A,'Z'(。

这就是算法:

// inputChar is a char holding your character
char inputChar = getCharFromUser();
int inputVal = inputChar - 65; // e.g. 0 for 'A', 1 for 'B'
char outputChar = 90 - inputVal; // e.g. 90 - 1 = 89 = 'Y' 
outputCharToUser(outputChar);

这就是你在C#中实现它的方法:

while (true)
{
    var key = Console.ReadKey(intercept: true);
    var inputChar = char.ToUpper(key.KeyChar);
    var outputChar = (char)('Z' - inputChar + 'A');
    Console.Write("{0}={1} ", inputChar, outputChar);
}

您可以使用两个字典来从索引中查找字符,反之亦然:

var indexLookup = "abcdefghijklmnopqrstuvwxyz"
    .Select((chr, index) => new { chr, index })
    .ToDictionary(x => x.chr, x => x.index);
var charLookup = "abcdefghijklmnopqrstuvwxyz"
    .Select((chr, index) => new { chr, index })
    .ToDictionary(x => x.index, x => x.chr);

现在很简单,关键部分是charLookup[25 - indexOfChar]:

string userInput = "B";
bool isUpper = char.IsUpper(userInput[0]);
char inputChar = Char.ToLowerInvariant(userInput[0]);
if(indexLookup.ContainsKey(inputChar))
{
    int indexOfChar = indexLookup[inputChar];
    char oppositeChar = charLookup[25 - indexOfChar];
    string result = isUpper ? Char.ToUpperInvariant(oppositeChar).ToString() : oppositeChar.ToString();
    Console.Write(result); // Y
}

实际上,您不需要两个字典,而只需要一个,因为string已经可以用于按索引查找字符。这是一个提供逻辑的类:

public class CharSwap
{
    private string alphabet;
    private Dictionary<char, int> indexLookup;
    public CharSwap() : this("abcdefghijklmnopqrstuvwxyz") { }
    public CharSwap(string alphabet)
    {
        if(alphabet == null) throw new ArgumentNullException("alphabet");
        this.alphabet = alphabet;
        indexLookup = alphabet.Select((chr, index) => new { chr, index }).ToDictionary(x => x.chr, x => x.index);
    }
    public char? OppositeChar(char input)
    {
        char lowerChar = Char.ToLowerInvariant(input);
        if (!indexLookup.ContainsKey(lowerChar))
            return null;
        int indexOfChar = indexLookup[lowerChar];
        int indexOpposite = alphabet.Length - 1 - indexOfChar;
        return Char.IsUpper(input) 
            ? Char.ToUpperInvariant(alphabet[indexOpposite])
            : alphabet[indexOpposite];
    }
}

测试:

CharSwap cw = new CharSwap();
char? oppositeChar = cw.OppositeChar('B');
Console.Write(oppositeChar);
char input = 'B';
string Range = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char result = Range[Range.Length - 1 - Range.IndexOf(input)]; //Y

或者另一种方法

char input = 'B';
string Range = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char result = Range.Reverse().ElementAt(Range.IndexOf(input)); //Y

这样的东西怎么样?

 char[] alphabet = {'A','B', 'C'} // and so on
 char[] mapsTo = {'Z', 'Y', 'X'} // and so on, excluded for brevity
 public function string changeLetter(char input)
 {
   int i = 0;
   foreach (char c in alphabet) {
      if (c == input) {
       return mapsTo[i];
      }
     i++;
   }
   return '';
 }

转换为c#:

char[] alphabet = {'A','B', 'C'}; // and so on
char[] mapsTo = {'Z', 'Y', 'X'}; // and so on, excluded for brevity
public string changeLetter(char input)
{
   int i = 0;
   foreach (char c in alphabet) {
      if (c == input) {
       return mapsTo[i].ToString();
      }
     i++;
   }
   return default(char).ToString();
}

你可以这样调用这个函数(例如(:

public static void RunProgram()
{
 Console.WriteLine("Please type in character");
 input = Console.ReadKey().KeyChar;
 Console.WriteLine("You typed in " + input + ". This results in: " + ChangeInput(input));
}

其中"ChangeInput"是前面定义的函数。

解决此问题的简单方法是使用Dictionary<char, char>:

public class Atbash {
    static string source = "abcdefghijklmnopqrstuvwxyz";
    static List<char> keys = source.ToList();
    static List<char> values = source.Reverse().ToList();
    static Dictionary<char, char> Converter = keys.ToDictionary(x => x, x => values[keys.IndexOf(x)]);

    public static char Convert(char input)
    {
        char output;
        bool isUpper = char.IsUpper(input);
        input = char.ToLowerInvariant(input);
        if(Converter.ContainsKey(input)) {
            output =  Converter[input];
            return (isUpper) ? char.ToUpperInvariant(output) : output;
        }
        throw new ArgumentOutOfRangeException("Input char is unknown");
        // of course, it can return default(char) instead of throwing an exception.
    }
}

为什么选择Atbash?请在这里阅读。