如果我有下一个数组:
int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 };
如何将所有不等于0的值尽可能地移动,以便像这样构建数组:
int[] arr = { 123, 243, 123, 123, 0, 0, 0, 0, 0 };
谢谢!
答案 0 :(得分:12)
LINQ怎么样:
var result = arr.Where(x => x != 0).Concat(arr.Where(x => x == 0)).ToArray();
这非常易读且具有线性时间复杂度。另一方面,它在不合适的地方运行,需要两次通过输入。
答案 1 :(得分:4)
排序依据:
int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 }.OrderBy(x => x == 0).ToArray();
答案 2 :(得分:3)
到目前为止,所有答案都会创建一个新数组。实际上你可以在一个循环中移动项目,然后用0填充其余部分。
public static void ShiftZerosRight(this int[] arr)
{
int j = 0;
while (j < arr.Length && arr[j] != 0)
{
j++;
}
for (int i = j; i < arr.Length; i++)
{
if (arr[i] != 0)
{
arr[j++] = arr[i];
}
}
while (j < arr.Length)
{
arr[j++] = 0;
}
}
不像单行LINQ表达式那样优雅,但效率更高 - 这不会创建任何新对象(LINQ会创建几个和最终的新数组),这是单个数组传递。作为一种扩展方法,在主体中看不到复杂性,它可以用作:
int arr[] = { ... };
arr.ShiftZerosRight();
答案 3 :(得分:2)
也许使用Linq:
int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 };
arr = arr.OrderByDescending(a => a > 0).ToArray<int>();
答案 4 :(得分:1)
试试这个:
arr.OrderBy(x=>x == 0).ToArray();
答案 5 :(得分:0)
创建一个新数组并将值传输给它。
int[] newArr = new int[arr.Length];
int i = 0;
foreach ( var v in arr )
{
if (v != 0)
{
newArr[i++] = v;
}
}
arr = newArr;
由于int
是一个值类型,所以使用全零来初始化数组。然后,如果值不是0,我们一次只复制一个值,只增加目标索引i
。比显示的Linq示例更详细,并且显然是非冷却器。但如果你是学生,可能会更容易理解。
答案 6 :(得分:0)
此代码段不会创建另一个数组。这里'x []'是您的数组。您取第1个0值并将其替换为非零数字。
int i=0,j=0,index=0,temp=0;
for(i=0;i<x.length;i++)
{
if(x[i]==0)
{
index=i;
for(j=index;j<x.length;j++)
{
if(x[j]!=0)
{
temp=x[j];
x[j]=x[i];
x[i]=temp;
break;
}
}
}
}