- 締切済み
おしえてください。
cobol言語のスクールにかよっていますがわからないのでおしえてください。 素数判定プログラムなのですが(ある数が割り切れたとき、素数ではない 割り切れなければ素数) 途中から PERFOM KEISAN UNTIL OWARI = "N". DISPLAY SPACE. STOP RUN. KEISAN. MOVE SPACE TO H-ATAI. ACCEPT H-ATAI AT 0436. MOVE H-ATAI TO ATAI. PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. <==ここに1回でも割り切れたとき DISPLAY KOTAE AT 0535. 判定する言語をおしえて ACCEPT OWARI AT 1045. この文だと全部「素数」と、 KEISAN2. 出てしまうのですが。 DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE "素数ではありません" TO KOTAE ELSE MOVE "素数です"TO KOTAT. お願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- paz777
- ベストアンサー率47% (77/163)
こんにちは。 勝手に解釈しました。 変数[N]により[PERFORM]を抜ける仕様となると[KEISAN2] で[ATAI]が素数であるかどうかは[KOTAE]を判定するしか ないですね。 従って[PERFORM KEISAN2・・・]と[PERFORM KEISAN3・・・]の間 に[IF]文が必要となることは分かりますね? [KEISAN3]では[ATAI]に一番近い素数を求めるようにすれ ば良いのですが、[PERFORM]の入れ子を使う必要があると 思います。([PERFORM]の中に[PERFORM]を入れる) 例えば[ATAI]が10の時を考えましょう。 [KEISAN2]では[N]が[2]の時[AMARI]が[0]になるので、こ の時点で[KEISAN2]は終了します。 同時に[KOTAE]には[素数ではありません]が入ります。 ここまでは良いでしょうか? [KOTAE]が[素数ではありません]の時に[ATAI -1]から [-1]づつ小さくする[PERFORM]文を作ります。 (要は9からスタートして3より小さくなるまで) --------------------------------------------------- PERFORM KEISAN3 VARYING N FROM ATAI - 1 BY - 1 UNTIL N < 3 --------------------------------------------------- 後は[N]が素数か判定する[PERFOM]を作り[N]が素数である 時に[PERFORM KEISAN3]を抜けるようにすれば良いと思い ます。 多分、今回の設問のポイントはここだと思います。 [PERFORM KEISAN3・・・]を前回の設問のように[2]から[+1] づつ大きくすると[ATAI -1]まで必ず素数かどうなのか 判定しないといけないけど[ATAI -1]から[-1]づつ小さく していくと始めに現れた素数が[ATAI]に一番近い素数に なるはずですよ。 ヒントはここまで、出力の仕様が分からないので・・・ 後はご自身でコーディングをしてみて下さい。 (お勉強!お勉強!) 分からなければ補足して下さい。 ここからは蛇足・・・ σ(^^)もprof_usagiさん同様に[N]に値を代入して[PERFORM] を抜けるやり方はあまりお勧めしません。 実務経験上、他人の作ったプログラムで同様のことをしている 時、プログラムが追いにくいからです。 まぁ、今回はスクールなので他人のプログラムを修正するわけ でもないので良いのでしょうが、もし実務で同様の事例が発生 した時は使用しない方が良いですよ。 それと[END-IF][END-PERFORM][SECTION]は使用してはいけない のでしょうか?使えるととっても助かるのですが・・・
文章と、コーディングの内容が違うので、どちらに解釈すれば良いのか、教えて下さい。 今のコーディングでは、KEISAN2は意味の無いものになります。必ず、KEISAN3を通りますからね。 本当は、どっち? それとも、また勝手に解釈して作っても良いのかな? あと、話は違いますが、あなたの先生の回答に有る、PERFORMの変数に、判定式に引っかかる数を転送して強制的に抜ける方法ですが、処理系によっては、やってはいけない場合がありますので、良い方法ではありません。
- paz777
- ベストアンサー率47% (77/163)
再登場のpaz777です。 ごめんなさい、とっても不親切でしたね。 お詫びのしるしに1つだけ回答します。 (雛形は#3 prof_usagiさんの回答を参考にしました。) ・新しい変数を使用する方法。 ------------------------------------------------------------ PERFOM KEISAN UNTIL OWARI = "N". DISPLAY SPACE. STOP RUN. KEISAN. MOVE SPACE TO H-ATAI. ACCEPT H-ATAI AT 0436. MOVE H-ATAI TO ATAI. MOVE ZERO TO SL. * * [N]が[ATAI]になるか[SL]が[0]になるまで[KEISAN2]を繰り返す。 * PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1 OR SL = 1. * * 1.[SL]が[1]の時は素数ではない * 2.[SL]が[0]の時は素数 * IF SL = 1 OR ATAI < 2 MOVE "素数ではありません" TO KOTAE ELSE MOVE "素数です" TO KOTAE. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. * * [AMARI]が[0]の時は素数ではないのでPERFORMを抜ける * ように[SL]に[1]を入れる * DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE 1 TO SL ELSE MOVE ZERO TO SL. ------------------------------------------------------------ 机上デバックすると理解できると思います。 例えば[ATAI]が[2]の時[N]は[2]から開始されるので、KEISAN2は実行 されませんよね。そうすると[SL]はZEROのままなので[素数です]と なります。 次に[ATAI]が[3]の時はどうでしょうか。 同じように[N]は[2]から開始されるので、1回目のKEISAN2が実行され ます。[ATAI]が[3]で[N]が[2]である時[AMARI]は[1]なので[SL]には [0]が入ります。PERFORMに戻った時[N]は[3]になるので終わりです。 [SL]は[0]ですので[素数です]となります。 同様に[ATAI]が[4],[5],[6]の場合を確認してみて下さい。 ではでは・・・
では、ご要望にお答えしますね。 PERFOM KEISAN UNTIL OWARI = "N". DISPLAY SPACE. STOP RUN. KEISAN. MOVE SPACE TO H-ATAI. ACCEPT H-ATAI AT 0436. MOVE H-ATAI TO ATAI. MOVE 1 TO AMARI. PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1 OR AMARI = 0. IF AMARI = 0 OR ATAI < 3 MOVE "素数ではありません" TO KOTAE ELSE MOVE "素数です" TO KOTAE. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. 今度は、わかりますよね? 何が違うのか、理解してください。 もちろん、スペースの取り方じゃないですよ。 等幅フォントじゃないと、見にくくなってしまいますね。 -------------------------------------------------- この下は、参考です。理由は、処理系(コンパイラ)に依存するからです。 PERFORM UNTIL OWARI = "N" MOVE SPACE TO H-ATAI ACCEPT H-ATAI AT 0436 MOVE H-ATAI TO ATAI MOVE 1 TO AMARI PERFORM VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1 OR AMARI = 0 DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI END-PERFORM IF AMARI = 0 OR ATAI < 3 MOVE "素数ではありません" TO KOTAE ELSE MOVE "素数です" TO KOTAE END-IF DISPLAY KOTAE AT 0535 ACCEPT OWARI AT 1045 END-PERFORM. DISPLAY SPACE. STOP RUN. 質問者の使用している処理系の内容がわからないので、この記述方法が使用できるかどうかわかりませんが、書いてみました。 それと、この場を借りまして、 paz777さんへ。 はっきり言って、徹夜明けに返答してますので、知恵が回りません。よって、気にしないです。その証拠に、素数がいくつから始まるのかどうか忘れました。
お礼
ありがとうございます。みなさんのプログラムを参考にスクールに持っていったので すが答えがあまりにもレベルが高くて先生に「自分でつくったものではないね」 と言われました(笑)。 DISPLAY SPACE. DISPLAY "値を入力" AT 0330. DISPLAY "[ ]" AT 0435. DISPLAY "結果"AT 0630. DISPLAY "続ける=>[ ]"1030. DISPLAY " 続ける…Y 終了…N" AT 1130. PERFOM KEISAN UNTIL OWARI = "N". DISPLAY SPACE. STOP RUN. KEISAN. MOVE SPACE TO H-ATAI. ACCEPT H-ATAI AT 0436. MOVE H-ATAI TO ATAI. PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE "素数ではありません" TO KOTAE MOVE ATAI TO N <=ここに値を入力することを先生はおしえてくれました。 ELSE MOVE "素数です"TO KOTAE. この文を使ってもう一つ質問です。 「入力した値が素数ではないとき、入力した一番近い素数を検出」 たとえば10を入れると7、6をいれると5、12をいれると11と言った感じ なのですが、自分の考えではKEISAN2で素数か素数でないかを判定 できたのでPERFORM KEISAN3を作製して PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. PERFORM KEISAN3 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE "素数ではありません" TO KOTAE MOVE ATAI TO N ELSE MOVE "素数です"TO KOTAE. KEISAN3. DIVIDE ATAI BY GIVING HENSU REMAINDER AMARI. ここから分かりません。素数ではない数、たとえば10を入力して 8や9がKEISAN3にもどって7は10に一番近い素数なので表示したい のですが…。 お願いしますこのプログラム文に付き合ってください
- paz777
- ベストアンサー率47% (77/163)
こんにちは。 prof_usagiさんの言われている通りPERFORMが最後まで (ATAI - 1)回ってしまいます。 prof_usagiさんの言われている方法以外にも 1.新しい変数を使用する方法 2.変数[N]を流用する方法 3.変数[KOTAE]を判定する方法 など色々とあります。 (prof_usagiさん、気を悪くしないで下さいね。) それと素朴な疑問として、このプログラムでは0436から 取得したデータが0,1,2の時は計算できませんが良いので しょうか? ちょっと気になったので・・・ ではでは・・・
お礼
paz777さん ありがとうございました。まだスクールに入って日が浅いのでpazさんの 答えがわかりませんでしたがこれから参考にさせていただきます。 プログラムって作成する人によっていろいろ方法がありますね。 また質問の時はアドバイスお願いします。 ありがとうございました。
一番最後の行は、たぶんタイプミスだと思いますので、無視するとします。 このフローは、あなたが作成されたのでしょうか? 言語以前に、このフローチャート自体に問題が有ります。それは何かと言うと、必ず、(ATAI - 1)の数になるまでPERFORMの中から抜けられませんね。だから、「素数です」と言う結果が表示されます。 では、ヒント?です。 KEISAN2のPERFORMの前にAMARIにゼロ以外の数を転送し、ATAI - 1の後ろのピリオドを取り、AMARIがゼロかどうか比較し、どちらかの条件を満たしたときに抜けるようにすれば良い訳ですね。 これでできますね。 おまけ。 最後の4行は、この位置でなくても良いのですが、わかりますか?
お礼
返答ありがとうございます。まだスクールに通って少ししかたっていないので 自分でつくったプログラムです、問題あるみたいですね。 ヒントを読んだんですけどいまいちわかりませんでした。 もう少し分かりやすくおしえてください。 最後の四行はプログラムのながれではどこにあるとよいですか? よろしくおねがいします。
お礼
ありがとうございます。みなさんのプログラムを参考にスクールに持っていったのですが答えがあまりにもレベルが高くて先生に「自分でつくったものではないね」 と言われました(笑)。 DISPLAY SPACE. DISPLAY "値を入力" AT 0330. DISPLAY "[ ]" AT 0435. DISPLAY "結果"AT 0630. DISPLAY "続ける=>[ ]"1030. DISPLAY " 続ける…Y 終了…N" AT 1130. PERFOM KEISAN UNTIL OWARI = "N". DISPLAY SPACE. STOP RUN. KEISAN. MOVE SPACE TO H-ATAI. ACCEPT H-ATAI AT 0436. MOVE H-ATAI TO ATAI. PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE "素数ではありません" TO KOTAE MOVE ATAI TO N <=ここに値を入力することを先生はおしえてくれました。 ELSE MOVE "素数です"TO KOTAE. この文を使ってもう一つ質問です。 「入力した値が素数ではないとき、入力した一番近い素数を検出」 たとえば10を入れると7、6をいれると5、12をいれると11と言った感じ なのですが、自分の考えではKEISAN2で素数か素数でないかを判定 できたのでPERFORM KEISAN3を作製して PERFORM KEISAN2 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. PERFORM KEISAN3 VARYING N FROM 2 BY 1 UNTIL N > ATAI - 1. DISPLAY KOTAE AT 0535. ACCEPT OWARI AT 1045. KEISAN2. DIVIDE ATAI BY N GIVING HENSU REMAINDER AMARI. IF AMARI = 0 MOVE "素数ではありません" TO KOTAE MOVE ATAI TO N ELSE MOVE "素数です"TO KOTAE. KEISAN3. DIVIDE ATAI BY GIVING HENSU REMAINDER AMARI. ここから分かりません。素数ではない数、たとえば10を入力して 8や9がKEISAN3にもどって7は10に一番近い素数なので表示したい のですが…。 お願いしますこのプログラム文に付き合ってください