tags:

views:

125

answers:

6

Let's say that I have an array of strings like this:

1, 2, 3, 4, 5, 6, 7, 8

and I want to shift the elements of the array such that

  1. The first element always remains fixed
  2. Only the remaining elements get shifted like so ...
  3. The last element in the array becomes the 2nd element and is shifted through the array with each pass.

Pass #1: 1, 2, 3, 4, 5, 6, 7, 8
Pass #2: 1, 8, 2, 3, 4, 5, 6, 7
Pass #3: 1, 7, 8, 2, 3, 4, 5, 6
Pass #4: 1, 6, 7, 8, 2, 3, 4, 5

Any assistance would be greatly appreciated.

+1  A: 

Because this looks like homework, I'm not going to solve it for you, but I have a couple of suggestions:

  1. Remember to not overwrite data if it isn't somewhere else already. You're going to need a temporary variable.
  2. Try traversing the array from the end to the beginning. The problem is probably simpler that way, though it can be done from front-to-back.
  3. Make sure your algorithm works for an arbitrary-length array, not just one that's of size 8, as your example gave.
Kevin
This is not homework.
Andy Evans
@Andy - Can you provide the code of what you have already tried. It is easier for people to correct your code then write it from scratch. Also, shows that you have tried something and aren't just looking for the answer given to you.
Craig T
+7  A: 

Because this looks like homework, I'm posting an unnecessary complex, but very hip LINQ solution:

int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };

int[] result = array.Take(1)
                    .Concat(array.Reverse().Take(1))
                    .Concat(array.Skip(1).Reverse().Skip(1).Reverse())
                    .ToArray();
dtb
+1 Haha - horribly inefficient but clever!
Andrew Hare
Very slick solution!
Andy Evans
+3  A: 

Probably the fastest way to do this in C# is to use Array.Copy. I don't know much about pointers in C# so there's probably a way of doing it that's even faster and avoids the array bounds checks and such but the following should work. It makes several assumptions and doesn't check for errors but you can fix it up.

void Shift<T>(T[] array) {
    T last = array[array.Length-1];
    Array.Copy(array, 1, array, 2, array.Length-2);
    array[1]=last;
}

EDIT
Optionally, there is Buffer.BlockCopy which according to this post performs fewer validations but internally copies the block the same way.

Josh Einstein
A: 

Although sounds like homework like others suggest, if changing to a List<>, you can get what you want with the following...

List<int> Nums2 = new List<int>();
for( int i = 1; i < 9; i++ )
   Nums2.Add(i);

for (int i = 1; i < 10; i++)
{
    Nums2.Insert( 1, Nums2[ Nums2.Count -1] );
    Nums2.RemoveAt(Nums2.Count -1);
}
DRapp
A LinkedList will give significantly better performance on larger collections.
Matthew Flaschen
I agree... much simpler for linked list -- even double-linked for reversal capabilities
DRapp
A: 

Define this:

public static class Extensions
{
    public static IEnumerable<T> Rotate<T>(this IEnumerable<T> enuml)
    {
        var count = enuml.Count();
        return enuml
            .Skip(count - 1)
            .Concat(enuml.Take(count - 1));
    }

    public static IEnumerable<T> SkipAndRotate<T>(this IEnumerable<T> enuml)
    {
        return enum
            .Take(1)
            .Concat(
                enuml.Skip(1).Rotate()
            );
    }
}

Then call it like so:

var array = new [] { 1, 2, 3, 4, 5, 6, 7, 8 };

var pass1 = array.SkipAndRotate().ToArray();
var pass2 = pass1.SkipAndRotate().ToArray();
var pass3 = pass2.SkipAndRotate().ToArray();
var pass4 = pass3.SkipAndRotate().ToArray();

There's some repeated code there that you might want to refactor. And of course, I haven't compiled this so caveat emptor!

Damian Powell
A: 

This is similar to Josh Einstein's but it will do it manually and will allow you to specify how many elements to preserve at the beginning.

static void ShiftArray<T>(T[] array, int elementsToPreserve)
{
    T temp = array[array.Length - 1];

    for (int i = array.Length - 1; i > elementsToPreserve; i--)
    {
        array[i] = array[i - 1];
    }

    array[elementsToPreserve] = temp;
}

Consumed:

int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };
ShiftArray(array, 2);

First pass: 1 2 8 3 4 5 6 7

Anthony Pegram