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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

3回答

17428閲覧

2以上の数値で素因数分解を求めるプログラム

yoppi07

総合スコア30

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

2クリップ

投稿2017/08/04 08:51

編集2017/08/04 11:12

このソースコードは変数xが入力された値を格納しint型のyへ渡しているという認識です。
初歩的な質問かもしれませんが、なぜforの中でさらにwhileで繰り返す必要があるのかわかりません。
for、whileの中のコードの理解が出来ていないです。
そもそも、繰り返し処理を記述しなければいけないのでしょうか?
条件分岐でもこのプログラムは実現出来る気がするのですが、解説お願いします。

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

public static void main(String[] args) { System.out.println("数値を入力して下さい"); Scanner num = new Scanner(System.in); int x = num.nextInt(); int y = x; for (int i = 2; x > i; i++) { while ((y % i) == 0) { System.out.println(i); y = y / i; } } } }

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

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

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

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

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

guest

回答3

0

ループの中で何をしているのか

for、whileの中のコードの理解が出来ていないです。

((y % i) == 0)という条件式で、何をコントロールしているのかじっくり考えてください。

ループの中にループがある理由

なぜforの中でさらにwhileで繰り返す必要があるのかわかりません。

『ループが入れ子になっている』『ネストしている』という表現をします。

元のプログラムでループが入れ子になっているのは、二回以上用いられる約数のためです。
内部のループを外すと、24 = 12223が計算できません。

そもそも

二重ループにしているのは無駄だと思います。以下で充分。

Java

1int i = 2; 2while(y != 1) { 3 if(y % i == 0) { 4 System.out.println(i); 5 y /= i; 6 } 7 else { 8 i++; 9 } 10}

繰り返しは必要か

そもそも、繰り返し処理を記述しなければいけないのでしょうか?

再帰処理を用いれば実現可能です。(ただし、非推奨)

Java

1private void recursionPrime(int arg, int div) { 2 if(arg == 1) return; 3 4 if(arg % div == 0) { 5 System.out.println(div); 6 recursionPrime(arg/div, div); 7 } 8 else { 9 recurtionPrime(arg, div+1); 10 } 11} 12private void printPrimeFactor(int arg) { 13 recursionPrime(arg, 2); 14}

なんか、Javaっぽくないプログラムになってしまいました...
raccyさんの指摘のとおり、Javaでの安易な再帰処理の使用は推奨されません。
特に拘りや制約条件のない限り、ループで処理するのがよいでしょう。

重要

コードはバッククオート三つで括ってください。
よくわからない場合は、マークダウン記法について調べてみてください。
これをしているかどうかで、回答の量と質が変わってきます。
(マークダウン記法を用いていない質問者には回答しない、という方針の人もいます。)

追記

anahina1979さんが、以下のとおり驚くべき真実を教えてくださいました。

ちなみに、素数は2以外の偶数は存在しない

それを反映するとこうなります。

Java

1while(y % 2 == 0) { 2 System.out.println(2); 3 y /= 2; 4} 5 6i = 3; 7while(y != 1) { 8 if(y % i == 0) { 9 System.out.println(i); 10 y /= i; 11 } 12 else { 13 i+=2; 14 } 15}

処理速度が上がって、オーダーで言うとO(n)からO(n)になりましたね!

投稿2017/08/04 08:55

編集2017/08/04 14:28
LouiS0616

総合スコア35660

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

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

momon-ga

2017/08/04 09:13

ずいぶん原型なくなっちゃいましたが(w これなら、y使わないで直接xを除算でよいですね。
LouiS0616

2017/08/04 09:16

『とりあえずfor文使っとけ』という風潮が問題な気もします。 どちらかと言うとwhile文の方が汎用性が高いと思うのですが... おっしゃるとおり、yの存在意義はもはやないです。
退会済みユーザー

退会済みユーザー

2017/08/04 12:19

ちなみに、 素数は2以外の偶数は存在しない
LouiS0616

2017/08/04 12:24

実行速度とスマートさどっちを取るかだと思いますね。 最初だけ分岐すると、ちょっと汚くなるように感じるのです。
raccy

2017/08/04 13:29

Javaは末尾再帰最適化をサポートしていないため、素因数が大きめの数字ではスタックオーバーフローで止まってしまうのではないでしょうか?再帰回数がそれなりに少ないことがわかっていないなら、Javaで再帰関数は使うべき(勧めるべき)では無いと思われますが、いかがですか?(私としては、そもそもJavaを勧めないんですけど)
LouiS0616

2017/08/04 13:42

質問の『そもそも、繰り返し処理を記述しなければいけないのでしょうか?』という記述に対する返答であって、勧める意思はないです。 誤解のないよう、非推奨であることを追記させていただきますね。
LouiS0616

2017/08/04 13:43

raccyさんの質問/回答/コメントではいつも勉強させていただいています。 コメントありがとうございます。
guest

0

ベストアンサー

実際に紙面上で素因数分解しながら読んでください。例えば540の素因数分解を考えます。
0. まず一番小さな素数"2"で割れるか試します(for文でi=2)。
0. その素数で割れるだけ割ります(while(y%i==0))。
540/2=270,270/2=135,135は2で割れない
0. 次の素数"3"で割れるか試します(forの更新文i++)。
0. その素数で割れるだけ割ります(while(y%i==0))。
135/3=45,45/3=15,15/3=5,5は3で割れない
0. 次の素数"5"で割れるか試します。
正確にはいったんiは4になりますが、前のステップで2で割れるだけ割っているため、
4では絶対割り切れないのでwhile文に入れず次のforに入る。
0. その素数で割れるだけ割ります(while(y%i==0))。
5/5=1

という行程を踏むループになっています。

投稿2017/08/04 16:34

swordone

総合スコア20651

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

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

0

なぜforの中でさらにwhileで繰り返す必要があるのかわかりません。

whileは置いといて、for文からですが、素因数を求める為に、割り算に使う i を2から
自分の数字の1つ前までのループさせれば良しとしています。もれは無いでしょう。
なのでfor (int i = 2; x > i; i++){ .... }

さらにプログラムは素因数分解を求める為に、whileを使っているいます。
(整数が、どんな数であっても、素数の積によって表すことができる)

素因数分解を行うには、順に小さいものから割りまくるです。
割り算する数字が同じでも、割り切れている内は何回でも割ります。yは減っていきますけど。
例えば 20 の場合2,2,5になります。(構成しているのは素数です。)

これをwhileで実現しています、(割り切れている間は回る)
実際20の場合、割切れる2は2回ループして
y、が5になった時点で2では割り切れず、forループへ移ります。y/i は次の次の次の5で割り切れます。
forループは5から先の19までループして終了します。ちょっとだけ効率化するとして yが1になった時点で
forループをberakすれば良いかな。

入力が素数の場合でもforループの回数は入力数の半分で良いのですけれどね。

投稿2017/08/04 15:42

編集2017/08/04 19:29
A.Ichi

総合スコア4070

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問