私は現在、サイズがのnマップを読み込んでいます。 * nです。この「地図」は、.
および*
の文字で構成され、.
は水を表し、*
は土地を表します。プログラムのポイントは、マップ上に何個の「島」が存在するかを数えることです。ここで、「島」は水で完全に囲まれた土地(*
)です(.
)。伝統的な8方向のいずれかに2つの土地(*
)が接続されている場合、それらは1つの島とみなされます。参考までに、最後に入力と出力のサンプルを入れます。私も含まれます再帰時にStackOverflowエラーを処理するには?
私のコードは、それが*
に遭遇するたびint numOfIslands
をインクリメント、マップと一致した2D char
配列を解析します。次に、*
を.
に置き換え、再帰を使用して、その「島」の残りの部分を見つけて置き換え、トラバーサルで移動します。現在のところ、サンプルの入力など、より小さな入力サイズで動作します。しかし、問題は入力サイズがn = 1000
である必要があり、入力サイズが大きい場合にStackOverflowエラーが発生することです。 StackOverflowエラーを処理するにはどうすればよいですか?スタックを「アンロード」するために、再帰中に中断することとは何か関係があると思いますが、正直なところ、それをやりはじめようとは思っていません。インターネットの研究は実りありませんでした。
map[][]
は、入力ファイルと一致する2D char
アレイであるマイトラバーサルと再帰コード:
//traverses the map, looking for 1s, and then sets that location to 0 before running testLocation on it
public static void traverse() {
for (int col = 0; col < n; col++) {
for (int row = 0; row < n; row++) {
if (map[row][col] == '*') {
map[row][col] = '.';
testLocation(row, col);
numOfIslands++;
}
}
}
}
//takes in a land location, and makes that land, along with the rest of the "island" 0s
public static void testLocation(int row, int col) {
//test upper left
if (row > 0 && col > 0) {
if (map[row - 1][col - 1] == '*') {
map[row - 1][col - 1] = '.';
testLocation(row - 1, col - 1);
}
}
//test upper
if (row > 0) {
if (map[row - 1][col] == '*') {
map[row - 1][col] = '.';
testLocation(row - 1, col);
}
}
//test upper right
if (row > 0 && col < n - 1) {
if (map[row - 1][col + 1] == '*') {
map[row - 1][col + 1] = '.';
testLocation(row - 1, col + 1);
}
}
//test left
if (col > 0) {
if (map[row][col - 1] == '*') {
map[row][col - 1] = '.';
testLocation(row, col - 1);
}
}
//test right
if (col < n - 1) {
if (map[row][col + 1] == '*') {
map[row][col + 1] = '.';
testLocation(row, col + 1);
}
}
//test lower left
if (row < n - 1 && col > 0) {
if (map[row + 1][col - 1] == '*') {
map[row + 1][col - 1] = '.';
testLocation(row + 1, col - 1);
}
}
//test lower
if (row < n - 1) {
if (map[row + 1][col] == '*') {
map[row + 1][col] = '.';
testLocation(row + 1, col);
}
}
//test lower right
if (row < n - 1 && col < n - 1) {
if (map[row + 1][col + 1] == '*') {
map[row + 1][col + 1] = '.';
testLocation(row + 1, col + 1);
}
}
}
サンプル入力:
...*.
**..*
*....
*.*.*
**...
サンプル出力:
The total number of islands is 3
あなたが絶対に再帰を保ちたいなら、stacksizeを増やしてください。 それ以外の場合は、再帰的アルゴリズムの代わりに反復アルゴリズムを使用することを検討してください。 –
別のアルゴリズムを使用することもできます。 https://en.wikipedia.org/wiki/Connected-component_labelingがよく使われ、2回のパスしか使わない –
私はアルゴリズムを完全に理解していませんが、暗黙のベースケースがあり、明示的ではないと思います。明示的なベースケースを定義すると、ここでいくつかのコーナーをカットするのに役立つでしょうか? – hamena314