1

これは過去の試験 (プログラミングの基礎) からの質問で、解決方法がわかりません (2 時間以上試した後)。

void fillingSumOfNeighbours(int[][]m)m が行列で、最後の列と行が既に埋められている (非ゼロ) と仮定して、残りの値を sum で埋めるメソッドをプログラムしますm[i][j]=m[i][j+1]+m[i+1][j]+m[i+1][j+1]。このメソッドは再帰的でなければなりません!

これまでのところ、行列を正しい方法で埋めることはできますが、フィールド カウンターを使用せずに再帰を有限にすることはできません (フィールド カウンターを使用して再帰を停止するには定義済みのクラスが必要なため、私には正しくないようです)。直接再帰メソッドをそのメソッド内でのみ実行する回数を定義する方法はありますか?

基本的にこれを行う必要があります:

_ _ 1
_ _ 1
1 1 1 

_ _ 1
_ 3 1
1 1 1

_ 5 1
_ 3 1
1 1 1

_ 5 1
5 3 1 
1 1 1

13 5 1
5  3 1
1  1 1
4

3 に答える 3

2

例と問題文を見ると、3 つの再帰を実行する必要があることは明らかです。

  • 垂直上方移動用
  • 左横移動用
  • そして、斜め左用。

したがって、その動きを管理するには、インデックスもメソッドに渡す必要があります。メソッドの変更を許可していただければ幸いです。

したがって、基本的に再帰呼び出しは次のようになります。

fill(arr, row - 1, col);
fill(arr, row, col - 1);
fill(arr, row - 1, col - 1);

3つのパラメーターを取るメソッドであると仮定fillします:-

  • int[][] arr
  • int row
  • int col

ご覧のとおり、最初の呼び出しは行の値を減らしているため、インデックスが上に移動しています。2 番目のコールは左に向かって移動しています。top-leftそして、最後の呼び出しは、ほとんどのインデックスをカバーするために必要になります。

メソッド内では、数式を使用して、渡された現在のインデックスを埋めるロジックを記述するだけです。はい、基本条件を忘れないでください。つまり、いずれかのインデックスが 0 未満の場合は、すぐに戻ります。

したがって、これはあなたのメソッドがどのように見えるかです: -

public static void fill(int[][] arr, int row, int col) {
    arr[row][col] = arr[row][col + 1] + arr[row + 1][col] + arr[row + 1][col + 1];
    if (row <= 0 || col <= 0) {
        return;
    }
    fill(arr, row - 1, col);
    fill(arr, row, col - 1);
    fill(arr, row - 1, col - 1);
}

そして、最初の呼び出しは次のようになります: -

fill(arr, row - 2, col - 2);

rowは最大行サイズで、最大列サイズはどこですかcol

于 2013-01-05T21:10:00.347 に答える
1
preencheComSomaVizinhos (int[][]m){
    get(m,0,0)
}
get(int[][]m, int i, int j){
    if(!(i == m.length-1 || j==m.length-1)){
        m[i][j] = get(m, i, j+1) + get(m,i+1,j)+get(m,i+1,j+1);

    }
    return m[i][j]; 
}
于 2013-01-05T20:57:32.607 に答える
0

最後の行にいるときの基本ケースで、行と列の番号を再帰するように書きます。配列が正方形の場合、必要な再帰パラメーターは 1 つだけです (これが当てはまると仮定します)。

再帰の途中で、次のような状況になります。

0 0 0 0 0 *
0 x + + + *  <- currently working on row k
0 - & & & *
0 - & & & *
0 - & & & *
* * * * * *

は、*開始する前にすでに入力されています。次に、パラメーター を指定して再帰関数を呼び出しますk+1。これにより、 とマークされたすべてのセルが埋められ&ます。+次に、s でマークされた行、 s でマークされた列-、および でマークされたコーナーの 1 つのセルを手動で入力する必要がありますx。次に、呼び出し元の関数に制御を戻します。これにより、 とマークされた残りのセルが埋められ0ます。

私は Java を実際に 1 年間書いていません。ずさんな構文で失礼します。

void fillNeighbours(int[][] m) {

  int size = m.length;

  run(m, size, 0);  

}

void run(int[][] m, size, row) {

  if (row < size) {

    // fill the rest of the rows and cols
    run(m, size, row+1)

    // fill the column and row for this iteration
    for (int i = 1; size-i > row; i++) {
      m[row][size-i] = m[row+1][size-i] + m[row][size-i+1];
      m[size-i][row] = m[size-i+1][row] + m[size-i][row+1];
    }

    // fill the corner cell
    m[row][row] = m[row+1][row] + m[row][row+1];

  } else {
    // Base case, do nothing
  } 

}
于 2013-01-05T21:24:28.720 に答える