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

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


现在,我想在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;
    }


这是来自Pearls编程的众所周知的算法-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概述,而不是练习任何建议?

最佳答案

从您的代码开始:

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


由于您只想获取所有剩余的元素,因此不需要第二行中的Take。

ar1和ar2只是枚举,因此它们不必是数组。不需要ToArray调用。进行了一些创造性的重命名,我们有:

IEnumerable<int> revFirst = ar.Take(k-1).Reverse();
IEnumerable<int> revLast = ar.Skip(k-1).Reverse();
int[] ar3 = revFirst.Concat(revLast).Reverse().ToArray();


现在我们有

rev(rev(第一)+ rev(最后))

分发外部转速给

rev(rev(last))+ rev(rev(first))

这与

last + first


将相同的操作应用于代码

IEnumerable<int> first = ar.Take(k-1);
IEnumerable<int> last = ar.Skip(k-1);
int[] ar3 = last.Concat(first).ToArray();


这进一步简化为

int[] ar3 = ar.Skip(k-1).Concat(ar.Take(k-1)).ToArray();


现在我们有了乔恩·斯基特的答案,所以我们必须完成。

关于c# - 使用LINQ语法旋转数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3640167/

10-13 08:11