Marshal
Marshal

Reputation: 1237

Shifting A single element in an array

I want to shift one element in an array to the right each time whilst leaving the original elements in their specific order in C#.

Ok so I've been asked to reword the code I can understand why so here we go:

I might have a number 48390

    //the ar elements have been commented out to show that we never know what ar contains but only the that I will always want to shift; ar[4]
    int[] ar = new int[5];
    //ar[0] = 4
    //ar[1] = 8
    //ar[2] = 3
    //ar[3] = 9
    //ar[4] = 0
    while(ar != 04839)
    {
       Shift code
    }

I might input 5 numbers 48390 if you notice its the same number but one digit is out. I want a while loop to rotate that 4 ar[1] to shift until the number forms 04839

I hope this makes sense. I am posting this question because most pages posting information about shifting based on shifting all elements to the right and I only really want to shift one specific element.

Thanks for looking.

edit: I should have been more specific. What if you don't know what each of the array elements could be? So I couldn't depend on "0" as an anchor. as another set of numbers might include another number for example "00238."

Upvotes: 0

Views: 1680

Answers (9)

Kim Ki Won
Kim Ki Won

Reputation: 1855

If you you linq, that's simple :-) But you need a size larger than the array.

ShiftLeft(ar, 1);

private static int[] ShiftLeft(int[] value, int countOfShift = 1)
{
    var length = value.Length;

    if (countOfShift > length)
    {
        throw new InvalidOperationException("countOfShift must less then value's length.");
    }

    var tempList = new List<int>(value);

    tempList.RemoveRange(length - countOfShift, countOfShift);
    tempList.InsertRange(0, value.Skip(length - countOfShift));

    return tempList.ToArray();
}

Upvotes: 0

S.A.Parkhid
S.A.Parkhid

Reputation: 2868

It is just a permutation of an item , below is the full source code of permutation algorithm.

    static List<string> Put(char s1, string list)
    {
        List<string> str =new List<string>();

        for (int i = 0; i < list.Length+1; i++)
        {
            string s = list.Substring(0, i) + s1.ToString() + list.Substring(i);
            str.Add(s);
        }
        return str;
    }
    static List<string> Permute(string list,int x)
    {
        List<string> Result = new List<string>();
        if (list.Length == 1)
        {
            Result.Add(list[0].ToString());
            return Result;
        }
        else
        {

            char first = list[0];
            list = list.Substring(x+1);
            List<string> part = Permute(list,0);
            foreach (string str in part)
            {
                  List<string> hasBeenPlaced = Put(first, str);
                  foreach (string str2 in hasBeenPlaced)
                  {
                        Result.Add(str2);
                  }
            }

        }

        return Result;
    }
    static void Main(string[] args)
    {

        List<string> per = Permute("abc",0);
        for (int i = 0; i < per.Count; i++)
        {
            Console.WriteLine(per[i]);
        }
        Console.ReadKey();
    }

Now if I add a break after the foreach , your problem has been solved . (it will writes all permuation for just an item which you want , not all of them....) So change that to :

       foreach (string str in part)
        {
            List<string> hasBeenPlaced = Put(first, str);
            foreach (string str2 in hasBeenPlaced)
            {
                Result.Add(str2);
            }
            break;
        }

Hope to helps you

Upvotes: 0

Kami
Kami

Reputation: 19407

From the example you need to shift elements around, and the example is a bit confusing over whether you need to loop them around to the start again. I have provided the below example that will loop around to the start - If you do not need to do that, the you can rework the if the statement.

private int[] Shift(int[] a)
{
    int zeroPos = Array.IndexOf(a, 0);

    int[] rtn = new int[a.Length];
    a.CopyTo(rtn, 0);

    if (zeroPos + 1 == a.Length)
    {
        rtn[0] = 0;
        for (int i = 0; i < a.Length - 1; i++)
        {
            rtn[i + 1] = a[i];
        }
    }
    else
    {
        rtn[zeroPos] = rtn[zeroPos + 1];
        rtn[zeroPos + 1] = 0;
    }

    return rtn;
}

Upvotes: 1

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56697

What's in your example is a swap, which can be implemented like:

private void Swap(ref int[] array, int index1, int index2)
{
    int temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
}

Calling Swap(ref source, 0, 1) would exchange the first and second element. What you want then is:

for (int i = 0; i < a.Length-1; i++)
{
    Swap(ref a, i, i+1);
}

This "bubbles" the first element up to the last position in each iteration.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460038

Perhaps

int oldLast = ar[ar.Length - 1];
for (int i = ar.Length - 1; i >= 0; i--)
    ar[i] = i == 0 ? oldLast : ar[i - 1];

Demo

Upvotes: 0

Rawling
Rawling

Reputation: 50104

This method will give you a sequence of arrays made by inserting a single element into (between) each position in a given array:

public static IEnumerable<T[]> InsertElementBetweenAllPositions<T>(
    T[] array, T element)
{
    int newLength = array.Length + 1;
    for (int i = 0; i < newLength; i++)
    {
        T[] rtn = new T[newLength];
        rtn[i] = element;
        Array.Copy(array, 0, rtn, 0, i);
        Array.Copy(array, i, rtn, i + 1, array.Length - i);
        yield return rtn;
    }
}

For your example, you might call it as

foreach (int[] arr in InsertElementBetweenAllPositions(new[] { 6, 7, 8, 9 }, 0))
{
    foreach (int i in arr)
        Console.Write(i + " ");
    Console.WriteLine();
}

Upvotes: 2

TLiebe
TLiebe

Reputation: 7966

Have you thought about using a LinkedList instead? A linked list data structure is probably more suited to what you are trying to do than an array. The AddFirst, AddLast, AddAfter and AddBefore methods allow you to insert elements into the list in a much more efficient way than re-organizing your array each time.

The disadvantage of linked lists is that you need to read the elements in order. So, it's very efficient for inserting/deleting elements but inefficient for accessing elements randomly.

There is a good overview of LinkedLists here.

Upvotes: 0

Justin Harvey
Justin Harvey

Reputation: 14672

How about this:

            List<int> l = new List<int>(){0,6,7,8,9};

            for (int i=1;i<5;i++)
            {
                l.Remove(0);
                l.Insert(i, 0);
            }

Upvotes: 1

Mert
Mert

Reputation: 6572

r=ar[0];

for (int i = 0; ar.lenght;i++)
{
ar[i]=ar[i + 1];
}

ar[ar.lenght] = r;

Upvotes: 0

Related Questions