c# - 如何越界回到数组的开头?

标签 c#

我正在制作一个凯撒密码,目前我有一个 3 的类次,我想用它来加密消息。如果任何字母有“x、y 或 z”,它会给我一个越界数组错误(因为移位是 3)。

如何通过返回到数组的开头但以移位的剩余部分结束来传递错误?

这是我目前的代码:

using System;
using System.Text;


//caesar cipher
namespace Easy47
{
    class Program
    {
        static void Main(string[] args)
        {
            const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            var input = Input(alphabet);
            Encrypt(3, input, alphabet);
            Console.WriteLine();
        }

        private static void Encrypt(int shift, string input, string alphabet)
        {
            var message = new StringBuilder();

            foreach (char letter in input)
            {
                for (int i = 0; i < alphabet.Length; i++)
                {
                    if (letter == alphabet[i])
                    {
                        message.Append(alphabet[i + shift]);
                    }
                }
            }

            Console.WriteLine("\n" + message);
        }

        private static string Input(string alphabet)
        {
            Console.Write("Input your string\n\n> ");

            string input = Console.ReadLine().ToUpper();

            return input;
        }
    }
}

最佳答案

您使用模运算符:

var i = 255
var z = i % 200  // z == 55 

在这里你的情况:

for (int i = 0; i < alphabet.Length; i++)
{
    if (letter == alphabet[i])
    {
        message.Append(alphabet[ (i + shift) % alphabet.Length]);
    }
}

如果在添加 shift 之后索引大于 alphabet.Length,它将再次从 0 开始。

参见 C# Ref Modulo Operator


无关,但你的循环不是很有效。 "ZZZZZ" 的消息将通过您的完整字母表进行 5 次翻译。您应该使用字典作为查找。您可以在开始翻译消息之前创建它,然后您的查找速度非常快 - 这就是字典的优势所在。 O(1) 查找 :o)

如果你稍微了解一下linq,这应该是可以理解的:

// needs:  using System.Linq;

private static void Encrypt(int shift, string input, string alphabet)
{
    var message = new StringBuilder();
    // create a string that is shifted by shift characters  
    // skip: skips n characters, take: takes n characters
    // string.Join reassables the string from the enumerable of chars
    var moved = string.Join("",alphabet.Skip(shift))+string.Join("",alphabet.Take(shift));

    // the select iterates through your alphabet, c is the character you currently handle,
    // i is the index it is at inside of alphabet
    // the rest is a fancy way of creating a dictionary for 
    // a->d
    // b->e
    // etc   using alphabet and the shifted lookup-string we created above.
    var lookup = alphabet
        .Select( (c,i)=> new {Orig=c,Chiff=moved[i]})
        .ToDictionary(k => k.Orig, v => v.Chiff);


    foreach (char letter in input)
    {
        // if the letter is not inside your alphabet, you might want to add
        // it "as-is" in a else-branch. (Numbers or dates or .-,?! f.e.)
        if (lookup.ContainsKey(letter)) 
        {
            message.Append(lookup[letter]);
        }
    }

    Console.WriteLine("\n" + message);
}

关于c# - 如何越界回到数组的开头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49835075/

相关文章:

c# - 如何使用Microsoft AntiXss 4.x?

c# - 增加 c# 中属性的 setter 方法的计数

c# - 使用 C# 和 MySql 存储密码的最佳方式

c# - Dictionary<> 总是按值排序,从键查找索引

c# - 如何从 PlayCommand 中删除目标?

c# - 尽管通过代码运行测试,ReSharper dotcover 仍显示 0% 的覆盖率

c# - 如何从 windows-mobile 2005 打印到条码打印机?

c# - .NET WCF Json 反序列化 Dictionary<int, int>

c# - 浏览器中的 Asp.net Core 空 .scss 文件

c# - Azure 函数遇到 System.Net.Sockets.SocketException