在2D数组中移动元素-Java

在2D数组中移动元素-Java,java,multidimensional-array,Java,Multidimensional Array,我正在寻找一种方法来上下移动2D数组中的所有元素,以便满足特定条件的元素保留在数组的末尾。我的意思的一个简化示例: 一个二维整数数组,其中包含1和4个零 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 我想做的是通过移动其他元素来填充孔(零),将零保留在末尾。预期的结果是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 在我的项目中,我处理的是一个2D对

我正在寻找一种方法来上下移动2D数组中的所有元素,以便满足特定条件的元素保留在数组的末尾。我的意思的一个简化示例:

一个二维整数数组,其中包含1和4个零

1 1 1 1 1  
1 1 1 1 0  
1 1 1 0 1  
1 1 1 1 1  
0 0 1 1 1 
我想做的是通过移动其他元素来填充孔(零),将零保留在末尾。预期的结果是:

1 1 1 1 1  
1 1 1 1 1  
1 1 1 1 1  
1 1 1 1 1  
1 0 0 0 0

在我的项目中,我处理的是一个2D对象数组,其状态是决定移位的因素。我只是在寻找一个基本的算法来实现这个结果。有没有一种简单的方法可以做到这一点?

对第一个数组中的每个数组进行bubblesort,并按顺序对它们进行排序

for (i=0; i<array1.length; i++){
   yourBubblesort(array1[i]);
}

for(i=0;i迭代数组并计算零。每次找到零时,将1添加到计数器中,并将零替换为1。然后从数组的末尾到其开头,将N个位置替换为0,其中N是零的总数。

尝试此方法

public void shiftZeros(int[] arr )
{
int count;
for(int j=0;j<arr.length-1;j++)
{
  if(arr[j]=0)
   {
    arr[j]=1;
    count++;
   }
}

for(int j=arr.length-1,i=1;i<count;i++,j--)
{
   arr[j]=0;
}

}
public void shiftZeros(int[]arr)
{
整数计数;

对于(int j=0;j,这里有一种方法使用复制到新数组

  • 创建新数组以保存移位的元素/最终结果
  • 迭代数组
  • 复制要移动的元素开关(满足条件)到最后一个 新阵列中的空闲位置
  • 复制一个不能移动的元件(不符合 条件)到阵列中的下一个可用位置
当元素即将到达处理端时,这样就不会有重叠

编辑

为了完整起见,这里是上述算法的一个实现

private E[][] shift(E[][] input) {
    int maxLen = get2DMaxLen(input);
    int i_next = 0, j_next = 0;
    int i_least = input.length-1, j_least = maxLen-1;
    E[][] actual = new E[input.length][maxLen];
    for(int i = 0; i < input.length; i++) {
        for(int j = 0; j < input[i].length; j++) {
            if(meetsCondition(input[i][j])) {
                actual[i_least][j_least--] = input[i][j];
                if(j_least == -1) {
                    j_least = maxLen-1;
                    i_least--;
                }
            } else {
                actual[i_next][j_next++] = input[i][j];
                if(j_next == input[i].length) {
                    j_next = 0;
                    i_next++;
                }
            }
        }
    }
    return actual;
}
输出

1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 0 0 0 0 
0 0 0 0 0

低效版本:

  • 在存储所有非0项时遍历数组(例如,使用a,可以使用a进行模拟)

  • 再次迭代并将存储的项逐个拉入数组

使用类似以下内容进行迭代:

for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[i].length; j++)
  ...

我不能给你代码,因为我不能为你做所有的工作。

为什么不先对列进行降序排序,然后对每行进行降序排序?有很多算法可以做到这一点。

对于上面的确切问题,解决方案可以是:

从两个指针开始,一个在数组的左上角,一个在右下角。让我们分别调用第一个和第二个指针。现在使用第一个指针逐行遍历数组。当您找到要放在末尾的元素时(本例中为“0”),检查第二个元素指向的元素。如果第二个元素是0,则减小第二个指针以指向二维数组中最后一个元素。现在检查此元素,如果这也是“0”,则再次减小第二个指针,依此类推,直到达到“1”(必须位于数组开头的元素)。然后交换两个元素。在任何时间点,如果指针相互交叉,则数组已按要求排序

以下java代码将执行此操作: 最初,变量endi和endj指向最后一个元素(第二个指针),变量i和j指向第一个元素(第一个指针)。数组大小为m X n

for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            if(a[i][j]==0)
            { 
                while(a[endi][endj]!=1 && i*m+j<endi*m+endj) //second part of the condition checks if i,j and endi,endj haven't crossed over
                {
                    endj--;
                    if(endj==-1)
                    {
                        endj=n-1;
                        endi--;
                        if(endi==-1)
                        {
                            disparr(a,m,n);
                            System.exit(0);
                        }
                    }
                }
                if(!(i*m+j<endi*m+endj))//if the pointer have crossed over
                {
                    disparr(a,m,n);
                    System.exit(0);
                }    
                int t=a[i][j];
                a[i][j]=a[endi][endj];
                a[endi][endj]=t;

            }
        }
    }

用于(i=0;iYes,我想有。闻起来像是一个没有吸引力的作业。这个作业不是没有吸引力的,但我正在简化我的问题,因为它是一个有多个类的大型项目。我只是在这里寻找一个基本算法,而不是一个完全编码的解决方案。@AmitG我通常会打标记,但这次我发表了评论。如果你以前不知道,你不知道哦,类似的结果。我很少使用smileys,而且我看不到这种情况会很快改变。显而易见的假设是,如果需要执行这种移位操作(在阵列上很慢)通常,二维数组可能不是最好的数据结构。值得一想。你忽略了它是二维数组的事实。我的实际数组不是所有的。假设我想用下一个非零元素替换每个零(移位而不是查找和替换).What?那么?@auregirl是否乐意创建新数组并复制?@A4L是的,我实际上尝试了一些复制数组的方法。您有没有想过解决方案?我尝试复制数组,跳过原始数组中不需要的元素,但我无法使其工作。不用担心,我dn不需要获得代码。我只是在寻找一种不同的思考方式。我尝试实现了链表,这似乎很有效!谢谢!
while ahead.hasNext
  // skip all 0s
  do
    i = ahead.next
  while i == 0
  behind.writeNext(i)

// the rest must all be 0
while behind.hasNext
  behind.writeNext(0)
for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            if(a[i][j]==0)
            { 
                while(a[endi][endj]!=1 && i*m+j<endi*m+endj) //second part of the condition checks if i,j and endi,endj haven't crossed over
                {
                    endj--;
                    if(endj==-1)
                    {
                        endj=n-1;
                        endi--;
                        if(endi==-1)
                        {
                            disparr(a,m,n);
                            System.exit(0);
                        }
                    }
                }
                if(!(i*m+j<endi*m+endj))//if the pointer have crossed over
                {
                    disparr(a,m,n);
                    System.exit(0);
                }    
                int t=a[i][j];
                a[i][j]=a[endi][endj];
                a[endi][endj]=t;

            }
        }
    }