而字母表循环

时间:2015-05-21 11:10:24

标签: c# .net

我正在尝试编写以下示例。

Input  ABCDEFGHIJKLMNOPQRSTUVWXYZ

Output  ZYXWVUTSRQPONMLKJIHGFEDCBA

如果用户在A中输入,则会输出Z。它必须超过25个字符才能达到Z。所以我猜测需要一个while循环,然后如果B它必须经过23次,那么 - 2依此类推,直到达到M,因为它会跳过1到达{{ 1}},然后从25开始。

有关如何处理此问题的任何建议吗?

5 个答案:

答案 0 :(得分:3)

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

这是算法:

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

答案 1 :(得分:3)

您可以使用两个词典,这些词典可以从索引中查找char,反之亦然:

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已经可以用于按索引查找char。这是一个提供逻辑的类:

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

答案 2 :(得分:1)

这样的事情怎么样?

 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”是之前定义的函数。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

解决此问题的简便方法是使用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? read about it here.