我试图通过指定的地点数量向右旋转项目列表,而不使用LINQ并以手动方式进行,我是如何做到的?
我认为我不理解如何处理/解决这个问题。这是我到目前为止所尝试的内容。
这个问题的一个明显例子可能是这样的: 初始数组(或列表):20,30,40,50,60,70 向右旋转3个位置:50,60,70,20,30,40
public void Test(List<int> items, int places)
{
items.RemoveAt(places);
items.Add(places);
}
答案 0 :(得分:5)
以下结果:
20,30,40,50,60,70
60,70,20,30,40,50 (Rotate 2)
50,60,70,20,30,40 (Rotate 3)
如果您打算将每个元素n个索引向左移动,只需将行list[i] = copy[index];
替换为list[index] = copy[i];
然后你得到这些结果:
20,30,40,50,60,70
40,50,60,70,20,30 (Rotate 2)
50,60,70,20,30,40 (Rotate 3)
这是一个简单的工作通用方法:
static void RotateList<T>(IList<T> list, int places)
{
// circular.. Do Nothing
if (places % list.Count == 0)
return;
T[] copy = new T[list.Count];
list.CopyTo(copy, 0);
for (int i = 0; i < list.Count; i++)
{
// % used to handle circular indexes and places > count case
int index = (i + places) % list.Count;
list[i] = copy[index];
}
}
用法:
List<int> list = new List<int>() { 20, 30, 40, 50, 60, 70 };
RotateList(list, 3);
或者因为我是扩展方法的忠实粉丝,你可以创建一个:
(通过使用IList,此方法也适用于数组)
public static class MyExtensions
{
public static void RotateList<T>(this IList<T> list, int places)
{
// circular.. Do Nothing
if (places % list.Count == 0)
return;
T[] copy = new T[list.Count];
list.CopyTo(copy, 0);
for (int i = 0; i < list.Count; i++)
{
int index = (i + places) % list.Count;
list[i] = copy[index];
}
}
用法:
List<int> list = new List<int>() { 20, 30, 40, 50, 60, 70 };
list.RotateList(12); // circular - no changes
int[] arr = new int[] { 20, 30, 40, 50, 60, 70 };
arr.RotateList(3);
答案 1 :(得分:4)
假设您有一个列表1-2-3-4-5
,并且您希望将其右移到:3-4-5-1-2
。
for n = 1 to 2
remove the head, put it at the tail
没有linq的简单循环。
即使这听起来更像是家庭作业,但说实话。
答案 2 :(得分:2)
{{1}}
答案 3 :(得分:0)
虽然这可能不能完全回答你的问题,但值得一提的是队列。对于循环操作,Queue<T>
可能是更好的数据结构选择。转移地点可能很简单:
public static void Rotate<T>(this Queue<T> items, int places)
{
for (int i = 0; i < places; i++)
items.Enqueue(items.Dequeue());
}
E.g。
var q = new Queue<int>(new[] { 20, 30, 40, 50, 60, 70 });
q.Rotate(3);
队列对于出列操作也比List<T>
更有效率,因为它不必从顶部移除并推送整个数组块(在此处阅读:Queue<T> vs List<T>)或数组这涉及复制整个阵列。