如何在C#中移动数组中的项?

时间:2010-04-20 00:07:53

标签: c# .net arrays

假设我有一个像这样的字符串数组:

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

我想要移动数组的元素

  1. 第一个元素始终保持固定
  2. 只有剩下的元素才会这样移动......
  3. 数组中的最后一个元素成为第二个元素,每次传递都会在数组中移动。
  4. 传递#1:1,2,3,4,5,6,7,8 通过#2:1,8,2,3,4,5,6,7 通过#3:1,7,8,2,3,4,5,6 通过#4:1,6,7,8,2,3,4,5

    非常感谢任何协助。

6 个答案:

答案 0 :(得分:7)

因为这看起来像是家庭作业,所以我发布了一个不必要的复杂但非常简洁的LINQ解决方案:

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

答案 1 :(得分:3)

在C#中执行此操作的最快方法可能是使用Array.Copy。我对C#中的指针知之甚少,所以可能有一种方法可以做得更快,并且避免了数组边界检查等,但以下情况应该有效。它做了几个假设,并没有检查错误,但你可以解决它。

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

修改
可选地,Buffer.BlockCopy根据this post执行较少的验证,但在内部以相同的方式复制块。

答案 2 :(得分:1)

因为这看起来像是家庭作业,我不打算为你解决,但我有几点建议:

  1. 如果数据不在其他地方,请记住不要覆盖数据。你需要一个临时变量。
  2. 尝试从最后到开头遍历数组。问题可能更简单,尽管可以从前到后完成。
  3. 确保您的算法适用于任意长度的数组,而不仅仅是大小为8的数组,如您的示例所示。

答案 3 :(得分:0)

虽然听起来像其他人的家庭作业所暗示的,如果更改为列表&lt;&gt;,您可以通过以下内容得到您想要的内容......

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

答案 4 :(得分:0)

定义:

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

然后这样称呼它:

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

那里有一些你可能想要重构的重复代码。当然,我还没有编译这个如此警惕的经纪人!

答案 5 :(得分:0)

这与Josh Einstein类似,但它会手动执行,并允许您指定在开头保留多少元素。

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

消费:

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

首传:1 2 8 3 4 5 6 7