我正在解决这个旋转数组的问题并让算法和代码正常工作
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;
}
这是 Programming 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[] 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
}
这是一个简短但完整的程序来演示它:
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));
}
}
输出:4、5、1、2、3
编辑:我刚刚注意到我的代码与您的原始代码之间的一个主要区别:您的代码修改了原始数组 - 我的代码返回一个具有旋转值的新数组。您的 LINQ 代码也是如此,但这意味着如果您使用仅查看原始数组的东西测试我的代码,您将看不到旋转。
LINQ 通常设计为以这种方式工作 - 它倾向于返回新序列而不是修改现有序列。
关于c# - 使用 LINQ 语法旋转数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3640167/