我的问题是我希望在数组中有一个特定元素,将其复制到另一个变量,将整个数组仅向上移动到该元素,然后将元素放在前面。在一张漂亮的图纸中,它看起来像这样。
[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
答案 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();
}