今アルゴリズムの勉強をしていてkupc(2012:practice)のサイトにあったアッカーマン関数の問題を見てプログラムを作りました。
下記が出来上がったものです。(m,n)=(2,3)であれば出力できましたが、入力例の2としてあった(3,45)はjava.lang.StackOverflowErrorとなりました。
bigintegerや例外処理できないか考えていますがここから進めないので何か方法があれば教えてほしいです。
import java.util.Scanner;
public class AckermannExec {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.print("[m]>");
long m=scan.nextInt();
System.out.print("[n]>");
long n=scan.nextInt();
long a=Ackermann(m,n);
System.out.println("A(m,n)="+a);
}
public static long Ackermann(long m,long n){
if(m>=1&&n>=1){
return Ackermann(m-1,Ackermann(m,n-1));
}else if(n==0){
return Ackermann(m-1,1);
}else{
return n+1;
}
}
}
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
java.lang.StackOverFlowErrorは名前の通りスタックがオーバーフローした状態を表します。
変数の桁数は関係ないですから、
このエラーに関しては変数の型を変えても意味はありません。
関数を呼ぶと、引数の情報・関数から戻った後に実行する命令のアドレスが
スタックと呼ばれる領域に格納されます。
これらのデータは関数から戻るまで削除されないため、
再帰の階層が深くなりすぎるとスタックを使い切ってしまい、上述のエラーが発生します。
Java VMの設定でスタック領域を増やすといった対策も考えられますが、
アルゴリズムの勉強とのことですので、
再帰の階層が深くなりすぎないように工夫するのもおもしろいと思います。
No.3
- 回答日時:
深い再帰呼び出しでStackOverflowErrorが出る場合は、javaの-Xssオプションでスタックを増やしてあげればStackOverflowErrorを出さずに実行を継続できるようになる場合があります。
しかしこの場合は無意味でしょう。
Ackermann(3,45)の再帰呼び出しの深さは約2の48乗になります。呼び出し1段で仮にスタックを64バイト消費するとすれば、2の54乗バイト(16ペタバイト)のメモリが必要になります。そんな大量のメモリを積めるコンピュータはありません。
再帰が深くならないように書き換えられればいいのですが、アッカーマン関数は再帰を使わない書き方が不可能であることが証明されています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java Java 配列<選挙> 4 2023/07/31 15:07
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数を動的に利用するには?
-
System.exit()の値を取得したい
-
中カッコ{}だけの記述について
-
NoSuchMethodErrorが解決できま...
-
java 素数判定について
-
Java プログラム public class ...
-
繰り返し
-
Javaでlog4jを使ってログ出力を...
-
randomで
-
Javaでデータベースの内容をGUI...
-
Java初心者です
-
プログラミングの問題です。大...
-
java iを1づつ増やすプログラ...
-
日本語が文字コードによっては...
-
C言語のポインターに関する警告
-
IF関数でEmpty値を設定する方法。
-
オブジェクトの中のプロパティ...
-
Java 入力した整数値の合計を、...
-
ORA-01858: 数値を指定する箇所...
-
実数からの小数部の取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数を動的に利用するには?
-
プログラミングの問題です。大...
-
中カッコ{}だけの記述について
-
System.exit()の値を取得したい
-
randomで
-
Javaでlog4jを使ってログ出力を...
-
ArrayList でスタックを
-
NoSuchMethodErrorが解決できま...
-
元旦からの経過日数を求めたい
-
javaのプログラミングで作るRPG...
-
JSP/Servletのパラメータの受け...
-
インタフェイス実装と抽象クラ...
-
コンストラクタの引数の中のnew?
-
日本語が文字コードによっては...
-
初心者なので教えてほしいです。
-
GetterとSetterをやったのに。
-
JAVAで「Yahoo Japan!」に接続
-
Listデータを重復せずにSetに格...
-
日付の比較をしたいのですが・...
-
Socketの接続のタイムアウトを...
おすすめ情報