[英]How to go out of bounds back to the start of an array?
I'm making a Caesar cipher, currently I have a shift of three that I want to encrypt the message with. 我正在制作凯撒密码,目前我要转移3个密码来加密邮件。 If any letter has "x, y or z" it will give me an out of bounds array error (because the shift is 3). 如果任何字母具有“ x,y或z”,它将给我一个超出范围的数组错误(因为移位为3)。
How can I pass the error by going back to the start of the array, but ending with the remainder of the shift? 我如何通过返回数组的开头但以平移的其余部分结尾来传递错误?
This is my code currently: 这是我目前的代码:
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;
}
}
}
You use the modulo operator: 您使用模运算符:
var i = 255
var z = i % 200 // z == 55
in your case here: 您的情况在这里:
for (int i = 0; i < alphabet.Length; i++)
{
if (letter == alphabet[i])
{
message.Append(alphabet[ (i + shift) % alphabet.Length]);
}
}
If after your addition of shift
the index is bigger then alphabet.Length
it will start at 0 again. 如果加上shift
后索引的大小大于alphabet.Length
,则长度将再次从0开始。
See C# Ref Modulo Operator 请参见C#Ref Modulo运算符
Unrelated, but your loop is not very efficient. 无关,但是您的循环效率不是很高。 A message of "ZZZZZ"
would go 5 times through your full alphabet to get translated. 一条"ZZZZZ"
消息将通过您的完整字母进行5次翻译。 You should use a Dictionary as lookup. 您应该使用字典作为查找。 You can create it at the start before you translate the message and then your lookup is very fast - thats what dictionarys excel at. 您可以在翻译消息之前一开始就创建它,然后查找就非常快-这就是字典擅长的领域。 O(1) lookups :o) O(1)查找:o)
If you know a little about linq, this should be understandable: 如果您对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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.