使用更高效的算法消除多个循环; 特别是字母数组

Squ*_*3lz -1 c# performance loops

我知道它的劳动节.我感到无聊并开始了"Code Fight Challenge".虽然我是工作生活中的一个开发者(中),但我一直在做很多操作和维护.一边而不是de .. 因此,我有点生疏,并希望在一天之内至少得到一次"Code Fight"挑战,以便进行改造.问题不是我的逻辑,而是表现.

基本上它是一个反向挑战,不得不自己制定规则(我做过),问题是它在3ms以下运行:

问题就是这个:请做

"ThISisaVEryLonGStrIngggGGGgGisnTiT314159265"

这个...

"KyZJzjrMVipCfeXJkiZexxxXXXxXzjeKzK"

我的逻辑再次是合理的,但我似乎循环很多,这导致了perf问题.如果没有明确告诉我该怎么做,可能会为我提供一些文档来阅读以改进我的代码(非常):

    static string alphaChange(string s)
    {
        int number;
        bool result;
        string temp;
        int index = 0;
        string[] aDigits = new string[100/*s.Length*/];
        string ans = Regex.Replace(s, @"\d", string.Empty);
        string concat="";
        int adder = 0;
        char[] alphabet = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
        char[] alphabet2 = new char[] { 'A', 'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

        foreach (var c in s)
        {
            temp = c.ToString();
            result = Int32.TryParse(temp, out number);

            if(result)
            {
                aDigits[index] = Convert.ToString(temp);
                index++;
            }
        }
        for (int i = 0; i < aDigits.Length; i++ )
        {
            concat += Convert.ToString(aDigits[i]);

        }

        adder = Convert.ToInt32(concat);
        var charArr = ans.ToCharArray();
        string finalAnswer = "";


        //////////////////////////////////////////////////////////////
        for (int i = 0; i < charArr.Length; i++ )

            for(int j = 0; j<alphabet.Length; j++)
            {
                if (charArr[i].ToString() == alphabet[j].ToString() || charArr[i].ToString() == alphabet2[j].ToString())
                {
                    int tempAdder = j;
                    for(int k = 0; k < adder; k++)
                    {
                        tempAdder++;
                        if(tempAdder > alphabet.Length - 1)
                        {
                            tempAdder = 0;
                        }

                    }
                    //Console.WriteLine(tempAdder.ToString());
                    //Console.ReadLine();
                    if(charArr[i] == alphabet[j])
                    {
                        finalAnswer += alphabet[tempAdder];
                    }
                    else
                    {
                        finalAnswer += alphabet2[tempAdder];
                    }

                }


        }
              Console.WriteLine(finalAnswer);
              Console.ReadLine();

            return finalAnswer;
        }
Run Code Online (Sandbox Code Playgroud)

编辑(评论):

string input ="wHaT111"string ouput ="dOhA"获取字符串中的数字,并将这么多字符添加到输入字符串中的字母.即.输入"aaa1"将等于输出"bbb"

spe*_*der 5

通过利用一些正则表达式,linq和modulo(%)运算符(得到除法的余数),可以非常简洁地完成没有显式循环.

不要忘记a char可以被视为数字类型,允许(奇怪的)算术char值.例如

('A' + 1) == 66; //true
Run Code Online (Sandbox Code Playgroud)

然后再回来

(char)('A' + 1) == 'B' //true
Run Code Online (Sandbox Code Playgroud)

使用这个char算法,我们可以通过减去65('A')为大写,97('a')为小写,得到字母表中字符的零数.

这意味着我们可以将每个字符转换为其字母位置(因此A变为0,B变为1等).

现在我们添加密钥编号,每26个包装一次.在数学上,这可以表示为(字母位置添加到密钥编号)的余数,全部除以26. 这消除了必须单独计算添加的成本在循环中,每26次迭代重置为零.

现在,我们将65或97添加回此字母位置,具体取决于原始字符的大小写.这给出了解码后的字符编号(作为int),我们将其转换回char,并在Select下面的最后一个中使用强制转换.

string Decode(string input)
{
    var match = Regex.Match(input, @"(?<code>^[a-zA-Z]*?)(?<key>\d+)$");
    if(!match.Success)
    {
        throw new Exception();
    }
    var num = int.Parse(match.Groups["key"].Value);
    var code = match.Groups["code"].Value;

    var newChars = code
                    .Select(c => c < 'a' //true: uppercase
                                 ? 'A' + ((c - 'A') + num) % 26 
                                 : 'a' + ((c - 'a') + num) % 26)
                    .Select(c => (char)c);
    return string.Concat(newChars);
}
Run Code Online (Sandbox Code Playgroud)