ページ 11

素数判定について

Posted: 2011年3月01日(火) 16:43
by ののき
今日、二回目の投稿となるののきです。今回はfor文を使ったプログラムに挑戦してみました。
実行はできるのですが、途中で問題が発生し、プログラムが停止してしまいます。
原因は無限にループしているのであるためだと思いますが、どうなのでしょう。

コード:

/*****************************************************************************
*素数を判定するためのプログラム    
*
*
*
******************************************************************************/
#include <iostream>
#include<math.h>
char line[10000];
int answer,waru,val;//answerは入力された数、wariは割る数、counterは最初の値 



int main()
{
	using namespace std;
	
	cout<<"2以上の値を入力し、エンターを押してください";
	cin>>answer;
	for(waru=0;waru<answer;waru++){//waruは最初はゼロ、割られる数より一つ低いとループ脱出、waruに数が+1され、ループする。条件に;を入れるのを忘れない 
		
		if(answer%waru++==0){
			val=0;//valはループ脱出の判定。条件が偽(0)になったため、ループを脱出する。
			cout<<"値は素数ではありません";
		}
	}
		if(answer%waru++==1)
	cout<<"値は素数です";
	
	

	
return(0);
}

Re: 素数判定について

Posted: 2011年3月01日(火) 16:54
by bitter_fox
ののき さんが書きました:

コード:

	for(waru=0;waru<answer;waru++){//waruは最初はゼロ、割られる数より一つ低いとループ脱出、waruに数が+1され、ループする。条件に;を入れるのを忘れない 
		
		if(answer%waru++==0){
			val=0;//valはループ脱出の判定。条件が偽(0)になったため、ループを脱出する。
			cout<<"値は素数ではありません";
		}
	}
これだとwaruが0から始まるので
answer%waruのところで0割りが発生してしまっていますよ。

あと、このアルゴリズムでは素数かどうかの判定を正常にできていないと思います。

Re: 素数判定について

Posted: 2011年3月01日(火) 17:06
by ののき
waruを2から始めるように直したのですが、cout文が出力されないようです。

Re: 素数判定について

Posted: 2011年3月01日(火) 17:09
by bitter_fox
ののき さんが書きました:

コード:

	for(waru=0;waru<answer;waru++){
		if(answer%waru++==0){
			val=0;
			cout<<"値は素数ではありません";
		}
	}
forのwaru++とifのwaru++で一度に二つ進めてるのが問題なのではないでしょうか?

Re: 素数判定について

Posted: 2011年3月01日(火) 17:51
by GRAM
およそ思ったところだけコメントします
ののき さんが書きました:

コード:

	for(waru=0;waru<answer;waru++){//ここのインクリメントを止めるか 
		
		if(answer%waru++==0){  //ここのインクリメントを止めるべきでしょうね。
			val=0;      //←valが使われませんね。ループから抜け出すにはbreakで十分です
                                                            //もしもvalを使いたければ最初の初期化時にval = 1;としてfor(waru=0;val&&waru<answer;waru++)としたらよいのでは?
			cout<<"値は素数ではありません";
		}
	}
		if(answer%waru++==1)  //coutが表示されない最大の問題だと思いますインクリメントはanswer%++waru == 1とすべきでしょう
	cout<<"値は素数です";
return(0);
}
waru++は値を返した後にインクリメントされます。つまり
answer%waru++ == 1は
if(answer%waru==1){waru=waru+1;cout<<"値は素数です";}
のようなコードになってしまいます
++waruとするといいと思います

Re: 素数判定について

Posted: 2011年3月01日(火) 18:06
by 結城
判定方法に「エラトスネスのふるい」というものを使ってみてはどうでしょうか?

Re: 素数判定について

Posted: 2011年3月01日(火) 18:16
by bitter_fox
GRAMさんの指摘でおおよそ正しい出力になるのですが、素数でないときも「値は素数です」と出力されてしまいます。
ですので、次のようにすると完全な出力になるでしょう。

コード:

int val = 1;

for (waru = 2; waru < answer; waru++)
{
	if (answer % waru == 0)
	{
		val = 0;
		cout << "値は素数ではありません" << endl;
		break;
	}
}

if (val)
{
	cout << "値は素数です" << endl;
}

コード:

for (waru = 2; waru < answer; waru++)
{
	if (answer % waru == 0)
	{
		cout << "値は素数ではありません" << endl;
		return 0;
	}
}
cout << "値は素数です" << endl;

return 0;

Re: 素数判定について

Posted: 2011年3月01日(火) 21:55
by box
実は、waruをanswerの1個手前まで増やしていく必要はなくって、
たかだかanswerの平方根まででよかったりします。

# 素数かどうかを調べる数値の変数名がanswerっていうのはちょっとどうなのかな、なんて思ったり。

Re: 素数判定について

Posted: 2011年3月02日(水) 00:20
by ののき
bitter fox様の解答に従い、記述を直しましたがひとつだけアレンジして、for文の条件を++waruに変えました。
この場合ですと++waru,waru++のどちらが適切なのでしょうか。
また、私のアレンジは正しかったのでしょうか。

Re: 素数判定について

Posted: 2011年3月02日(水) 21:59
by box
ののき さんが書きました:この場合ですと++waru,waru++のどちらが適切なのでしょうか。
実質的には、どちらでも同じでしょう。
厳密には、実行時間などが多少変わるのかもしれませんが、何億回もループするのでない限り
人間には体感できないほどの違いでありましょう。

前置派、後置派、それぞれの考えや言い分があるとは思いますが、
宗教論争になりそうなので私は退散。

Re: 素数判定について

Posted: 2011年3月03日(木) 16:06
by ののき
ご解答ありがとうございます。
それならば、前置の方が上のようなミスを犯さないようなのでこちらを使っていきたいと思います。

Re: 素数判定について

Posted: 2011年3月03日(木) 21:48
by box
ののき さんが書きました:前置の方が上のようなミスを犯さないようなので
おっしゃっている内容がさっぱりわかりませんね。
前置だとミスを犯さず、後置だとミスを犯す、とは一体全体何のことでしょうか?

Re: 素数判定について

Posted: 2011年3月04日(金) 13:19
by asd
box さんが書きました:
ののき さんが書きました:前置の方が上のようなミスを犯さないようなので
おっしゃっている内容がさっぱりわかりませんね。
前置だとミスを犯さず、後置だとミスを犯す、とは一体全体何のことでしょうか?
横槍失礼します。
上のようなミス(No.5でGRAMさんが指摘している内容)とのことなので、今回の場合は意図しない0による除算のことでしょうね。
前置だとありとあらゆるミスを犯さないと言っているわけではないので、そんな鬼の首を捕まえたように指摘することもないと思います。

for文ループの初期値が0である今回は前置が有効に効いているだけで、初期値を適切に設定する方法もありますね。

Re: 素数判定について

Posted: 2011年3月04日(金) 21:43
by box
はい、鬼の首を取ったようなコメントをした本人です。
今後気をつけます。