Reputation: 61
I am trying to rotate a List of items to the right by the specified numbers of places without using LINQ and doing it the manual way, how am I able to do this?
I think I am not understanding how to approach/solve this problem in particular. Here's what I have tried so far.
A clear example of this problem could be something like this: Initial Array(or List): 20,30,40,50,60,70 Rotate to the right by 3 places: 50,60,70,20,30,40
public void Test(List<int> items, int places)
{
items.RemoveAt(places);
items.Add(places);
}
Upvotes: 2
Views: 859
Reputation: 30022
Results from the below:
20,30,40,50,60,70
60,70,20,30,40,50 (Rotate 2)
50,60,70,20,30,40 (Rotate 3)
If you meant to shift each element n indexes to the left, just replace the line list[i] = copy[index];
with list[index] = copy[i];
Then you get these results:
20,30,40,50,60,70
40,50,60,70,20,30 (Rotate 2)
50,60,70,20,30,40 (Rotate 3)
This is a simple working generic method:
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];
}
}
Usage:
List<int> list = new List<int>() { 20, 30, 40, 50, 60, 70 };
RotateList(list, 3);
Or since I'm a big fan of extension Methods, you can create one:
(By using IList, this method works for arrays also)
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];
}
}
Usage:
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);
Upvotes: 5
Reputation: 73163
While this may not exactly answer your question it's worth mentioning about queues. For circular operations Queue<T>
s could be a better data structure choice. To shift places it could be as simple as:
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);
Queues are also a lot more efficient than List<T>
s for dequeuing operation since it doesnt have to remove from top and push entire block of array one up (read about it here: Queue<T> vs List<T>) or arrays which involves copying of the entire array.
Upvotes: 0
Reputation: 23797
int[] numbers = {20, 30, 40, 50, 60, 70};
int rotateBy = 3;
int[] rotated = new int[numbers.Length];
Array.Copy(numbers, rotateBy, rotated, 0, numbers.Length-rotateBy);
Array.Copy(numbers, 0, rotated, numbers.Length - rotateBy, rotateBy);
Upvotes: 2
Reputation: 11763
assuming you have a list 1-2-3-4-5
, and you want to shift it 2 right to : 3-4-5-1-2
.
for n = 1 to 2
remove the head, put it at the tail
simple loop with no linq.
Even though this sounds more like homework to me to be honest ..
Upvotes: 4