質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

5896閲覧

java コラッツ予想のプログラム

RinT_hinabita39

総合スコア28

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/04/17 05:34

###前提・実現したいこと
コラッツ予想とは、任意の整数において、それが偶数ならば2で割り、奇数だったら3を掛けたものに1を足すという操作を繰り返して行くと、必ず最終的に1になるというものです。つまり、

f(n) = n/2 (nは偶数)
f(n) = 3n+1 (nは奇数)

今、2つの整数を入力として与えた時、その範囲内の全ての整数においてこの操作を繰り返し、その中で、1に辿り着くまでにかかった操作の回数が一番多かった時の回数を出力させる、ということをやりたいです。この時、一緒に入力した2整数も表示させたいです。

例えば入力を1と10とした場合は、1〜10の全ての数字に対して上記の操作を行い、1と、10と、その中で一番手順数が多かった回数、つまり3つの整数を出力させる、ということです。

###発生している問題・エラーメッセージ

実行しても一向に止まらないため、確認でnの値を出力させるようにしたら、
無限に1が出続けていましたが、理由が全く分かりません。
特に「1でないとき」という条件でwhileを回しているのに、1が出てて止まっていないというのが一番訳が分からないです。

###該当のソースコード

java

1import java.util.Scanner; 2import java.util.InputMismatchException; 3 4class Collatz { 5 public static void main (String[] args) { 6 Scanner scan = new Scanner(System.in); 7 System.out.println("Input 2 numeric values."); 8 9 try { 10 int countmax = 0; 11 int count = 1; 12 int a = scan.nextInt(); 13 int b = scan.nextInt(); 14 System.out.print(a+" "+b+" "); //入力した2整数を出力 15 16 //以下のループで第1引数の方が小さいことを前提としているため、第2引数の方が小さい場合は値を交換しておく 17 if(b<a) { 18 int tmp = b; 19 b = a; 20 a = tmp; 21 } 22 23 for(int n=a; n<=b; n++) { 24 while(n!=1) { 25 if(n%2==0) n/=2; 26 else n = 3*n+1; 27 System.out.println(n); //デバッグ用 これを足したら1が無限に出てくるようになりました 28 count++; 29 } 30 if(count>countmax) 31 countmax = count; //1に到達するのにかかった回数が一番多かったときの回数を覚えておく部分 32 count = 1; 33 } 34 35 System.out.println(countmax); 36 37 } catch(InputMismatchException e) { 38 System.out.println("Input must be type int."); 39 } 40 } 41}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

あなたがやっているのはこういうことですよ。

java

1for(int n=a; n<=b; n++) { 2 n = 1; 3}

投稿2017/04/17 05:47

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RinT_hinabita39

2017/04/17 07:24

一目見ただけでは意味わからなかったのですが、「こんな風になるわけなくね?なんで??」と思い、こうなりそうな要因となっている部分を推測して考えてみたらわかりました!ありがとうございました!!
guest

0

whileの外のforの後処理でnに1足す処理が書かれているから、たとえwhileを抜けても、次のforの処理でまたnが1足されてwhileに入って、また1になってwhileを抜けて…を繰り返しています。

Java

1 for(int n=a; n<=b; n++) { // ←ここでnに1が足される 2 while(n!=1) { 3 if(n%2==0) n/=2; 4 else n = 3*n+1; 5 System.out.println(n); //デバッグ用 これを足したら1が無限に出てくるようになりました 6 count++; 7 } 8 // ここではnは1になってループを抜けるが、次のループでnに1が足されてまたwhileの処理が始まる 9 if(count>countmax) 10 countmax = count; //1に到達するのにかかった回数が一番多かったときの回数を覚えておく部分 11 count = 1; 12 }

投稿2017/04/17 05:43

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RinT_hinabita39

2017/04/17 07:26

fuzzballさんの回答でひらめいて、masaya_ohashiさんの回答で確証を得られました。なんとか正しく動作するように書き換えられそうです。ありがとうございました!
guest

0

nの変数の値がどう変化するかfor文とwhile文の近辺を「自分がコンピューターになったつもりで」動きをシミュレートしてみてください。

いつもいつもデバッグでそんなことをやってはいられないですが、アルゴリズムを勉強中の場合、そんなやりかたも経験しておくとよいかと思います。

投稿2017/04/17 05:43

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RinT_hinabita39

2017/04/17 07:27

たまにその方法使いますし、今回も使ったのですが、何かしらの先入観が働いたのか今回の間違いに気付きませんでした…
KSwordOfHaste

2017/04/17 07:29

それが気づけるように練習するのがプログラミングの練習ともいえますね!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問