使用LINQ语法旋转数组

sat*_*jit 1 c# linq arrays rotation

我正在解决旋转数组的问题并使算法和代码工作

 int[] Rotate(int[] ar,int k)
        {
            if (k <= 0 || k > ar.Length - 1)
                return ar;
            Reverse(ar, 0, k - 1);
            Reverse(ar, k, ar.Length - 1);
            Reverse(ar, 0, ar.Length - 1);
            return ar;            
        }

 void Reverse(int[] ar,int start, int end)
        {
            while (start < end)
            {
                int temp = ar[start];
                ar[start] = ar[end];
                ar[end] = temp;
                start++;
                end--;
            }
        }
Run Code Online (Sandbox Code Playgroud)

现在我想在LINQ中执行此操作并获得以下代码,我认为这可以做得更好.

 int[] Rotate(int[] ar,int k)
    {
        if (k <= 0 || k > ar.Length - 1)
            return ar;
        int[] ar1=ar.Take(k-1).Reverse().ToArray();
        int[] ar2=ar.Skip(k - 1).Take(ar.Length - k+1).Reverse().ToArray();
        int[] ar3 = ar1.Concat(ar2).Reverse().ToArray();
        return ar3;
    }
Run Code Online (Sandbox Code Playgroud)

这是编程珍珠的一个众所周知的算法 - http://books.google.com/books?id=kse_7qbWbjsC&lpg=PA14&ots=DfzTzQCSar&dq=rotate%20an%20array%20programming%20pearls&pg=PA14#v=onepage&q&f=false

一般来说如何开发我的LINQ技能,如果我遇到编程问题,现在我只考虑for循环或foreach循环,如何考虑linq运算符.我正在阅读C#4.0简介,除了练习任何建议?

Jon*_*eet 14

老实说,我不确定为什么你会得到所有的逆转.这个怎么样:

int[] Rotate(int[] ar,int k)
{
    if (k <= 0 || k > ar.Length - 1)
        return ar;
    return ar.Skip(k)            // Start with the last elements
             .Concat(ar.Take(k)) // Then the first elements
             .ToArray();         // Then make it an array
}
Run Code Online (Sandbox Code Playgroud)

这是一个简短但完整的程序来演示它:

using System;
using System.Linq;

class Test
{
    static int[] Rotate(int[] ar,int k)
    {
        if (k <= 0 || k > ar.Length - 1)
            return ar;
        return ar.Skip(k)            // Start with the last elements
                 .Concat(ar.Take(k)) // Then the first elements
                 .ToArray();         // Then make it an array
    }

    static void Main()
    {
        int[] values = { 1, 2, 3, 4, 5 };
        int[] rotated = Rotate(values, 3);

        Console.WriteLine(string.Join(", ", rotated));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:4,5,1,2,3

编辑:我刚刚注意到我的代码和原始代码之间的一个主要区别:你的代码修改了原始数组 - 我的返回一个带有旋转值的数组.您的LINQ代码也是如此,但这意味着如果您使用仅查看原始数组的内容测试我的代码,您将看不到旋转.

LINQ被设计为通常以这种方式工作 - 它有利于返回新序列而不是修改现有序列.