2

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

    }
Zerox
  • 61
  • 5
  • 5
    It will be more clear if you include an example, of list before this operation and list after this operation – sujith karivelil Jul 19 '16 at 04:38
  • 1
    You need circular queue data structure. Add items in circular queue and just keep moving the start position as required. – Sarvesh Mishra Jul 19 '16 at 04:44
  • 1
    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 – Zerox Jul 19 '16 at 04:44
  • 1
    why is linq not allowed? – pm100 Jul 19 '16 at 05:26
  • 1
    @Zerox the example you gave is a very special vase as it gives the same result for shifting 3 to the right and 3 to the left. I think it would have been better if you gave an example shifting 2 or 4 to the right. – Zein Makki Jul 19 '16 at 05:33

4 Answers4

5

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);
Zein Makki
  • 29,485
  • 6
  • 52
  • 63
4

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 ..

Noctis
  • 11,507
  • 3
  • 43
  • 82
  • as an afterthought, you can use an array, create a new one with same size, and simply copy with an offset ... – Noctis Jul 19 '16 at 04:48
2
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);
Cetin Basoz
  • 22,495
  • 3
  • 31
  • 39
0

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.

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368