Fastest way to remove rows in 2D Array
我有一个程序,我需要从
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public byte[][] checkRows(byte[][] grid) { LinkedList<Integer> temp = new LinkedList<Integer>(); boolean willRemove = false; for (int y = 0; y < grid.length; y++) { boolean tempCheck = true; for (int x = 0; x < grid[0].length; x++) { if (grid[y][x] == 0) { tempCheck = false; break; } } if (tempCheck) { temp.add(y); willRemove = true; } } if (willRemove) { int[] rowArray = convert(temp); return removeRows(grid, rowArray); } return grid; } public byte[][] removeRows(byte[][] grid, int[] rows) { int total = rows.length; int current = 0; byte[][] retGrid = new byte[grid.length][grid[0].length]; for (int i = total; i < grid.length; i++) { if (current < total && i-total+current == rows[current]) { current++; } //retGrid[i] = grid[i-total+current].clone(); System.arraycopy(grid[i-total+current], 0, retGrid[i], 0, xsize); } return retGrid; } public int[] convert(LinkedList<Integer> intList) { int[] retArray = new int[intList.size()]; for (int i = 0; i < retArray.length; i++) { retArray[i] = intList.get(i).intValue(); } return retArray; } |
这为我提供了一种从二维数组中删除行并将其替换为数组顶部零行的相当快速的方法。有没有更快的方法来达到同样的结果?
如果不清楚脚本的作用,那么它是用来删除俄罗斯方块游戏中的完整行。
更新:使用
使用一个链接列表可以进行o(1)删除,请看这个答案,因为无论如何都必须迭代该列表。
起初,我认为多维数组是紧凑的,因为它是一个连续的内存块,但看起来情况并非如此。因此,您不会失去任何可能已经生效的缓存优势。
遗憾的是Java没有值类型(当前),我将使用一个字节而不是字节来编码信息。这不是绝对必要的…
从代码审查的角度来看,在方法
哦,太复杂了。把
您正在复制整行,但不必复制。只需重新排列它们,保留的行就会下降,将完整的行移到顶部并进行清理。不需要内存分配。
由于所有复制操作都只使用一个维度,所以没有太多要优化的内容,因为最耗时的操作可能是确定一行中是否有任何零,以及(有时)清除一些行。
我想知道它是在哪台机器上运行的,因为我想即使是最慢的电话,它也一定运行得非常快。顺便说一下,CR更适合。想想更好的名字,如
这个小方法为一维情况执行问题的所需功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private static final void onClearFilledRows(final byte[] pTetris, final int pRowLength) { int i = 0, j = 0; /* Track the last valid position of row data. */ int lLastValidIndex = 0; /* Iterate through each row. */ for(i = 0; i < pTetris.length; i += pRowLength) { /* Iterate through each cell in the row. */ boolean lContainsZero = false; for(j = i; j < (i + pRowLength) & !lContainsZero; j++) { lContainsZero |= pTetris[j] == 0; } /* This row is valid. Copy it to the last valid index. */ if(lContainsZero) { System.arraycopy(pTetris, i, pTetris, (lLastValidIndex++ * pRowLength), pRowLength); } } /* Empty the remaining rows. */ for(i = lLastValidIndex * pRowLength; i < pTetris.length; i++) { /* Set the element to zero. */ pTetris[i] = 0; } } |
然后可以为二维情况重新编写此逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | private static final void onClearFilledRows(final byte[][] pTetris) { int i = 0, j = 0; /* Track the last valid position of row data. */ int lLastValidIndex = 0; /* Iterate through each row. */ for(i = 0; i < pTetris.length; i ++) { /* Iterate through each cell in the row. */ boolean lContainsZero = false; for(j = 0; j < pTetris[i].length & !lContainsZero; j++) { lContainsZero |= pTetris[i][j] == 0; } /* This row is valid. Copy it to the last valid index. */ if(lContainsZero) { System.arraycopy(pTetris[i], 0, pTetris[lLastValidIndex++], 0, pTetris[i].length); } } /* Empty the remaining rows. */ for(i = lLastValidIndex; i < pTetris.length; i++) { for(j = 0; j < pTetris[i].length; j++) { /* Set the element to zero. */ pTetris[i][j] = 0; } } } |