C# 修剪数组内的空格(删除 0)



如果我有下一个数组:

int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 };

我如何将所有不等于0的值向左移动,以便数组将像这样构建:

int[] arr = { 123, 243, 123, 123, 0, 0, 0, 0, 0 };

谢谢!

使用LINQ:怎么样

var result = arr.Where(x => x != 0).Concat(arr.Where(x => x == 0)).ToArray();

这是非常可读的,并且具有线性时间复杂性。另一方面,它跑得不合适,需要两次通过输入。

OrderBy:

int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 }.OrderBy(x => x == 0).ToArray();

到目前为止,所有答案都创建了一个新数组。实际上,你可以在一个循环中向上移动项目,然后用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();

也许将Linq与一起使用

        int[] arr = { 123, 243, 0, 0, 123, 0, 0, 0, 123 };
        arr = arr.OrderByDescending(a => a > 0).ToArray<int>();

试试这个:

arr.OrderBy(x=>x == 0).ToArray();

创建一个新数组并将值传输给它。

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示例更冗长,而且绝对不酷。但如果你是一名学生,可能会更容易理解。

此代码片段不会创建另一个数组。这里"x[]"是您的数组。取第一个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;
          }
       }
    }
}

最新更新