C#Shift数组的元素直到特定点,并将特定元素拉到前面

时间:2017-06-27 15:01:06

标签: c# arrays

我的问题是我希望在数组中有一个特定元素,将其复制到另一个变量,将整个数组仅向上移动到该元素,然后将元素放在前面。在一张漂亮的图纸中,它看起来像这样。

[0, 1, 2, 3, 4, 5]
          ^

[0, 1, 2, null, 4, 5]
          ^ (3)

[null, 0, 1, 2, 4, 5]
             ^ (3)

[null, 0, 1, 2, 4, 5]
 ^ (3)

[3, 0, 1, 2, 4, 5]
 ^

我已经尝试使用for循环将元素放到前面,然后插入3,但我担心我的做法并不是最有效或最快的方式。< / p>

这是我尝试过的。

        int elementAt = 3;
        int[] array = { 0, 1, 2, 3, 4, 5 };
        int mem = array[elementAt];
        for (int i = elementAt; i > 0; i--)
            array[i] = array[i - 1];
        array[0] = mem;

我怀疑像Array.Copy这样的东西可以更快地做到这一点......?

编辑: 下面的每个答案都有自己在特定场景中的用途。 这个问题没有明确的答案,让这些结果让您选择使用哪种方法。

iterations, index, arraysize
HIGH, HIGH, HIGH
Speed for ShiftRightAt: 6616, ticks: 28007912
Speed for shiftlist: 3556, ticks: 15054635
Speed for arrayCopy: 1742, ticks: 7376152
Speed for MoveValueToFront: 67, ticks: 285901
LOW, LOW, HIGH
Speed for ShiftRightAt: 0, ticks: 28
Speed for shiftlist: 42, ticks: 180476
Speed for arrayCopy: 33, ticks: 142717
Speed for MoveValueToFront: 0, ticks: 67
HIGH, LOW, HIGH
Speed for ShiftRightAt: 0, ticks: 1399
Speed for shiftlist: 3624, ticks: 15341777
Speed for arrayCopy: 3177, ticks: 13449012
Speed for MoveValueToFront: 0, ticks: 926
LOW, HIGH, HIGH
Speed for ShiftRightAt: 73, ticks: 311428
Speed for shiftlist: 41, ticks: 174652
Speed for arrayCopy: 18, ticks: 79768
Speed for MoveValueToFront: 65, ticks: 277266
HIGH, HIGH, LOW
Speed for ShiftRightAt: 0, ticks: 1379
Speed for shiftlist: 0, ticks: 3902
Speed for arrayCopy: 0, ticks: 728
Speed for MoveValueToFront: 0, ticks: 914
LOW, LOW, LOW
Speed for ShiftRightAt: 0, ticks: 3
Speed for shiftlist: 0, ticks: 32
Speed for arrayCopy: 0, ticks: 11
Speed for MoveValueToFront: 0, ticks: 12
HIGH, LOW, LOW
Speed for ShiftRightAt: 0, ticks: 135
Speed for shiftlist: 0, ticks: 3850
Speed for arrayCopy: 0, ticks: 998
Speed for MoveValueToFront: 0, ticks: 840
LOW, HIGH, LOW
Speed for ShiftRightAt: 0, ticks: 15
Speed for shiftlist: 0, ticks: 16
Speed for arrayCopy: 0, ticks: 9
Speed for MoveValueToFront: 0, ticks: 39

测试方法: https://pastebin.com/HKkixHGR

5 个答案:

答案 0 :(得分:3)

你漂亮的绘画给出了你需要写的东西。

public static void ShiftRightAt<T>(T[] array, int index)
{
    if (index < 0 || index >= array.Length) return; // throw exception

    var element = array[index]; // take out the element

    for (int i = index; i > 0; i--)
    {
        array[i] = array[i - 1];
    }

    array[0] = element;
}

答案 1 :(得分:1)

使用列表更容易。之后,将其转换回数组。

var array = new int[] { 0, 1, 2, 3, 4, 5 };                 
var list = array.ToList();
list.Remove(3);
list.Insert(0, 3);
array = list.ToArray();

答案 2 :(得分:1)

这是使用Array.Copy的示例,所以它应该足够快:

int elementAt = 3;
int[] array = { 0, 1, 2, 3, 4, 5 };

int[] arr1=new int[array.Length];
arr1[0] = array[elementAt];
Array.Copy(array, 0, arr1, 1, elementAt);
Array.Copy(array, elementAt+1, arr1, elementAt+1, array.Length-elementAt-1);
//arr1={3, 0, 1, 2, 4, 5}

修改

我对结果不满意,因为我认为Array.Copy应该更快。我认为这个版本可以提高速度:

int saved = array[elementAt];
Array.Copy(array, elementAt + 1, array, elementAt, array.Length - elementAt - 1);
Array.Copy(array, 0, array, 1, array.Length - 1);
array[0] = saved;

答案 3 :(得分:1)

这是您可以使用的扩展方法:

public static int[] MoveValueToFront(this int[] values, int searchValue)
{
    if (values == null || values.Length == 0)
    {
        return values;
    }

    var rest = values.TakeWhile(v => v != searchValue).ToArray();

    if (rest.Length == values.Length)
    {
        return values;
    }

    values[0] = searchValue;
    rest.CopyTo(values, 1);

    return values;
}

这将允许您这样做:

[TestMethod]
public void TestMoverExtension()
{

    var testValues = new int[] { 0, 1, 2, 3, 4, 5 };

    var result = testValues.MoveValueToFront(3);


    CollectionAssert.AreEqual(new int[] { 3, 0, 1, 2, 4, 5 }, result);
}

答案 4 :(得分:0)

如果您不能(或不想)使用List,您还可以使用以下内容:

public int[] moveElement(int[] array, int index)
{
    int[] save = new int[] { array[index] };
    var rest = array.Take(index).Concat(array.Skip(index + 1));
    return save.Concat(rest).ToArray();
}

修改

如果您需要针对不同的数据类型,这是一个通用版本:

public T[] moveElement<T>(T[] array, int index)
{
    T[] save = new T[] { array[index] };
    var rest = array.Take(index).Concat(array.Skip(index + 1));
    return save.Concat(rest).ToArray();
}