问题
I'm trying to create a method for traversing a square 2-dimensional array which takes in a parameter that specifies the direction, either up, down, left or right. I've been able to split the task into two separate methods; one for traversing vertically and one for traversing horizontally:
private void concatHorizontal(boolean left) {
int rowIndex, columnIndex, index;
for (int i=0; i<board.size(); i++) {
index = (left) ? 0 : board.get(0).size()-1;
for (int j=0; j<board.get(0).size(); j++) {
if (left) {
rowIndex = i;
columnIndex = j;
} else {
rowIndex = board.size() - 1 - i;
columnIndex = board.get(0).size() - 1 - j;
}
int val = board.get(rowIndex).get(columnIndex).getValue();
if (val != 0) {
board.get(rowIndex).get(index).setValue(val);
if (columnIndex != index) {
board.get(rowIndex).get(columnIndex).setValue(0);
}
index = (left) ? index+1 : index-1;
}
}
}
}
private void concatVertical(boolean up) {
int rowIndex, columnIndex, index;
for (int i=0; i<board.get(0).size(); i++) {
index = (up) ? 0 : board.size()-1;
for (int j=0; j<board.size(); j++) {
if (up) {
columnIndex = i;
rowIndex = j;
} else {
columnIndex = board.get(0).size() - 1 - i;
rowIndex = board.size() - 1 - j;
}
int val = board.get(rowIndex).get(columnIndex).getValue();
if (val != 0) {
board.get(index).get(columnIndex).setValue(val);
if (rowIndex != index) {
board.get(rowIndex).get(columnIndex).setValue(0);
}
index = (up) ? index+1 : index-1;
}
}
}
}
The methods shifts all values in an array not equal to zero as far as possible in a given direction, like in the game 2048 but without merging neighbors with the same value.
As you can see my code is neither intuitive nor compact, and I would like to merge the two methods above into one if possible. It should, in other words, traverse the arraylist like one of the for-loops below depending on the given direction.
for (int i=0; i<board.size(); i++) {
for (int j=0; j<board.get(0).size(); j++) {
// Traverse to the right
}
}
for (int i=0; i<board.size(); i++) {
for (int j=board.get(0).size()-1; j>=0; j--) {
// Traverse to the left
}
}
for (int i=0; i<board.get(0).size(); i++) {
for (int j=0; j<board.size(); j++) {
// Traverse downwards
}
}
for (int i=0; i<board.get(0).size(); i++) {
for (int j=board.size()-1; j>=0; j--) {
// Traverse upwards
}
}
回答1:
This is one step of the solution (with simplified access to the element value):
private void concatHori(boolean left) {
if( left ){
concatHori( 0, 0, 1 );
} else {
concatHori( board.size()-1, board.get(0).size()-1, -1 );
}
}
private void concatHori(int rowstart, int colstart, int inc ) {
for (int i=0; i<board.size(); i++) {
int index = colstart;
for (int j=0; j<board.get(0).size(); j++) {
int rowIndex = rowstart + inc*i;
int colIndex = colstart + inc*j;
int val = board.get(rowIndex).get(colIndex);
if (val != 0) {
board.get(rowIndex).set(index, val);
if (colIndex != index) {
board.get(rowIndex).set(colIndex, 0);
}
index += inc;
}
}
}
}
The "vertical" method can be transformed in the same way.
The second step would be the union of Horizontal and Vertical, which could be done by providing access functions to the - then - single method. But I think that the resulting code would be more lines and less intuitive that what there is now, and therefore I refrain from adding step 2.
来源:https://stackoverflow.com/questions/33064326/traversing-a-2d-array-in-four-directions-up-down-left-right