0
public static boolean diagonals(char[][] b, int row, int col, int l) {

            int counter = 1; // because we start from the current position
            char charAtPosition = b[row][col];
            int numRows = b.length;
            int numCols = b[0].length;
            int topleft = 0;
            int topright = 0;
            int bottomleft = 0;
            int bottomright = 0;
            for (int i=row-1,j=col-1;i>=0 && j>=0;i--,j--) {
                if (b[i][j]==charAtPosition) {
                    topleft++;
                } else {
                    break;
                }
            }
            for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
                if (b[i][j]==charAtPosition) {
                    topright++;
                } else {
                    break;
                }
            }
            for (int i=row+1,j=col-1;i<=numRows && j>=0;i++,j--) {
                if (b[i][j]==charAtPosition) {
                    bottomleft++;
                } else {
                    break;
                }
            }
            for (int i=row+1,j=col+1;i<=numRows && j<=numCols;i++,j++) {
                if (b[i][j]==charAtPosition) {
                    bottomright++;
                } else {
                    break;
                }
            }
            return topleft + bottomright + 1 >= l || topright + bottomleft + 1 >= l; //in this case l is 5
    }

上記のコードをここに投稿し終えた後、私は仕方がなく、4つのほぼ同じループを1つのメソッドにマージすることによってコードを単純化したいと思いました。

これが私が望んでいる種類の方法です:

public int countSteps(char horizontal, char vertical) {
   
}

2つのパラメータhorizontalであり、またはのverticalいずれ+-で、4つの方向を示すことができます。可能であれば、の値をとるときにi++;一般化されます。i horizontal horizontal;horizontal+

私が見たくないのはif、またはswitchステートメントです。たとえば、次のようになります。

public int countSteps(char horizontal, char vertical) {
     if (horizontal == '+' && vertical == '-') {
         for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
                if (b[i][j]==charAtPosition) {
                    topright++;
                } else {
                    break;
                }
            }
     } else if (horizontal == '+' && vertical == '+') {
          for (int i=row+1,j=col+1;i>=0 && j<=numCols;i++,j++) {
                if (b[i][j]==charAtPosition) {
                    topright++;
                } else {
                    break;
                }
            }
     } else if () {

     } else {

     }
}

オリジナルと同じくらい面倒なので。i>=0 && j<=numCols;たとえば、ループ条件の符号の比較は、と>= && <=の値の組み合わせに対応していることにも注意してください。horizontalvertical

言葉遣いがおかしいのでごめんなさい。不明な点があれば教えてください。

4

2 に答える 2

2

ループは次のようなものに簡単に変換できます。

int doit(int i_incr, int j_incr) {
    int cornerIncrement = 0;
    for (int i=row+i_incr, j=col+j_incr; i>=0 && j>=0; i+=i_incr, j+=j_incr) {
        if (b[i][j]==charAtPosition) {
            cornerIncrement++;
        } else {
            break;
        }
    }
    return cornerIncrement;
}

そして、4回繰り返します...

int increment = doit(+1, -1);  // Or (-1, +1) etc
topLeft += increment;  // Or bottomLeft/topRight/bottomRight
于 2012-12-04T17:02:25.987 に答える
1

したがって、次の2つのループがあります。

for (int i=row-1,j=col-1;i>=0 && j>=0;i--,j--) {
  if (b[i][j]==charAtPosition) {
    topleft++;
  } else {
    break;
  }
}
for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
  if (b[i][j]==charAtPosition) {
    topright++;
  } else {
    break;
  }
}

まず、カウンターを配列に変換します。つまり、topleft->counter[0]topright->counter[1]

次に、コード間の違いを変数に変換すると、次のようになります。

for(direction = 0; direction < 2; direction++) {
  int offset = direction * 2 - 1; // This is what I mean by doing some math
  for(int i=row-1,j=col+offset;i>=0 && -j*offset>=-numCols*direction;i--,j+=offset) {
  if (b[i][j]==charAtPosition) {
    counter[direction]++;
    // etc.

数学は時々醜くなることがあります、またはあなたは別の行でそれを行うことができます。構文を使用してこの特定の問題の数学を行うためのエレガントな方法については、この質問に関する他の投稿を参照してください。? :

于 2012-12-04T17:01:16.970 に答える