do while文の問題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: do while文の問題

Re: do while文の問題

#16

by かずま » 6年前

みけCAT さんが書きました:こう変更しても、

コード:

⇒ 8352 (= 8730 - 0378)
のようになってしまい(余計な0が付く)、

コード:

⇒ 8352 (= 8730 - 378)
とはならないでしょう。
そうですね。

それから、

コード:

⇒ 6174 (= 8532 - 2358)
のようになってしまい(⇒の次が全角スペース)、

コード:

⇒ 6174 (= 8532 - 2358)
とはならないでしょう。

Re: do while文の問題

#15

by みけCAT » 6年前

ととさん さんが書きました:以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
21行目のscanfで数字を読んだ後、22行目のscanfで入力待ちになっているのでしょう。
かずま さんが書きました:printf("%d"); で、何かの数字を表示します。
n とは書いていないので、どんな値になるかわかりません。
printfで書式に対しデータが足りないので、未定義動作になります。
定義上何が起こってもおかしくありません。
かずま さんが書きました:

コード:

        printf("%04d = %04d - %04d\n", n, max, min); // for debug

コード:

        printf("⇒ %04d (= %04d - %04d)\n", n, max, min); // for debug
に変更しないと、そんな出力にはなりません。
こう変更しても、

コード:

⇒ 8352 (= 8730 - 0378)
のようになってしまい(余計な0が付く)、

コード:

⇒ 8352 (= 8730 - 378)
とはならないでしょう。

Re: do while文の問題

#14

by かずま » 6年前

ちょっと説明が間違っていました。
ととさん さんが書きました: Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
打った数字は、一つ目の scanf で n に入ります。
そのあと、何も出力されないのは、二つ目の scanf が
入力を待っているからです。

そこで、もう一度、数字を入力すると、先に進み、
printf("%d"); で、何かの数字を表示します。
n とは書いていないので、どんな値になるかわかりません。

そして、return 0; でプログラムは終了します。
ととさん さんが書きました: Enter 'n' :1234
1234
⇒ 3087 (= 4321 - 1234)
⇒ 8352 (= 8730 - 378)
⇒ 6174 (= 8532 - 2358)
3 time(s)

と実行したいのですが

コード:

        printf("%04d = %04d - %04d\n", n, max, min); // for debug

コード:

        printf("⇒ %04d (= %04d - %04d)\n", n, max, min); // for debug
に変更しないと、そんな出力にはなりません。

プログラムは、思った通りには動くのではなく、
書いたとおりに動くのです。

Re: do while文の問題

#13

by かずま » 6年前

ととさん さんが書きました: と実行したいのですが以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
26行目に return 0; があるので、ここでプログラムは終了します。

21行目と22行目に、scanf が 2つあるのは変です。
どちらかひとつで十分。if のあるほうは、数字以外の入力への対策。

25行目: 最初の質問(No.1) では、printf(" %5d\n", n); なのに。
27行目: 最初の質問(No.1) では、count = 0; /*初期値の設定*/ なのに。
29行目: No.6 で、do { にするように指示しているのに。
55行目: No.6 で、} while (n != MAGIC); にするように指示しているのに。

scanf で if がないとき、数字以外を入力するとどうなりますか?

Re: do while文の問題

#12

by ととさん » 6年前

ととさん さんが書きました:Conditions
1. 'n' is a natural number less than 10000
2. 'n' is not divisible by 1111

Enter 'n' :1234
1234
⇒ 3087 (= 4321 - 1234)
⇒ 8352 (= 8730 - 378)
⇒ 6174 (= 8532 - 2358)
3 time(s)

と実行したいのですが以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
プログラムをコンパイルして実行できる環境はあります。

コード:

#include <stdio.h>
#define   MAGIC   6174
#define   KETA       4

 int main()
 {
   int n;
   int a[KETA];
   int count ;
   int max, min, tmp, i, j, k;

/*条件を満たすnが入力を繰り返す部分*/
  printf("Conditions\n"
  "1. 'n' is a natural number less than 10000.\n"
  "2. 'n' is not divisible by 1111.\n");

printf("\n");  

  do{
    printf("Enter 'n' : ");
    scanf("%d", &n);
    if (scanf("%d", &n) != 1) return 1;
    } while (n < 0 || n > 9999 || n % 1111 == 0);
  
    printf("%d" );
     return 0;
     /*初期値の設定*/

/*ここから*/
    count++;

/*nの各くらいをバラバラにする部分*/
        a[0] = n % 10;
        a[1] = n / 10 % 10;
        a[2] = n / 100 % 10;
        a[3] = n / 1000;


/*配列aの値を大きい順に並べる部分*/
        for (i = 0; i < KETA - 1; i++) {
            k = i;
            for (j = i + 1; j < KETA; j++)
                if (a[j] > a[k]) k = j;
            tmp = a[i], a[i] = a[k], a[k] = tmp; 
        }


/*最大値をmaxへ、最小値をminへ、その差をnに代入する部分*/
        max = a[0]*1000 + a[1]*100 + a[2]*10 + a[3];
        min = a[3]*1000 + a[2]*100 + a[1]*10 + a[0];
        n = max - min;
        printf("%04d = %04d - %04d\n", n, max, min); // for debug


/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/

  printf("%d time(s)\n", count);

  return 0;
}

Re: do while文の問題

#11

by ととさん » 6年前

Conditions
1. 'n' is a natural number less than 10000
2. 'n' is not divisible by 1111

Enter 'n' :1234
1234
⇒ 3087 (= 4321 - 1234)
⇒ 8352 (= 8730 - 378)
⇒ 6174 (= 8532 - 2358)
3 time(s)

と実行したいのですが以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
プログラムをコンパイルして実行できる環境はあります。

Re: do while文の問題

#10

by かずま » 6年前

1111で割り切れない10000未満の自然数に対して、
各桁をバラバラにして組合せ、
最大値から最小値をひく
という操作を何回も行うと6174になること
を確かめよ。
ただし4桁未満の数の場合は上の桁に0を補って4桁と考える。
[1] 自然数とは、正の整数で、1, 2, 3, ...
[2] 10000未満の自然数とは、1, 2, 3, ..., 9998, 9999
[3] そのうち、1111 で割り切れるのは、1111, 2222, 3333, ..., 9999

1111で割り切れない10000未満の自然数を、
何でもいいから一つ挙げてみましょう。
例えば、2017

[4] 各桁をバラバラにすると、2, 0, 1, 7
[5] これらを組み合わせると、
  0127, 0172, 0217, 0271, ..., 7201, 7210

[6] 最大値は 7210、最小値は 0127
  (127 は 4桁未満なので 0 を補っている)
[7] 引き算をする。7210 - 0127 = 7083
[8] [4]~[7]の操作を繰り返す
  8730 - 0378 = 8352
  8532 - 2358 = 6174 <<< 6174 になった
  7641 - 1467 = 6174 <<< これ以上やっても無駄

上の [1]~[8] のうち、どこまでわかりますか?

今はもうプログラムが書けますか?
プログラムをコンパイルして実行できる環境を持っていますか?

Re: do while文の問題

#9

by ととさん » 6年前

まず、(1) の問題の意味ですが、

入力が 1234 だったら
 4321 - 1234 -> 3087
 8730 - 0378 -> 8352
 8532 - 2358 -> 6174

入力が 1 だったら
 1000 - 0001 -> 0999
 9990 - 0999 -> 8991
 9981 - 1899 -> 8082
 8820 - 0288 -> 8532
 8532 - 2358 -> 6174

といったことは確かめてみましたか?

上の計算の出し方がわからず、確かめられていません(-_-;)

Re: do while文の問題

#8

by かずま » 6年前

ととさん さんが書きました:それぞれ何型(if文やdo while文など)を使えばよいかもわからず、
全くの手つかず状態です(-_-;)
(2) までは分かるが、(3) からあとが分からないということですか?

まず、(1) の問題の意味ですが、

入力が 1234 だったら
 4321 - 1234 -> 3087
 8730 - 0378 -> 8352
 8532 - 2358 -> 6174

入力が 1 だったら
 1000 - 0001 -> 0999
 9990 - 0999 -> 8991
 9981 - 1899 -> 8082
 8820 - 0288 -> 8532
 8532 - 2358 -> 6174

といったことは確かめてみましたか?

(2) の処理は、すでに書かれています。

コード:

    - 条件を満たすまで、n への入力を繰り返す [ scanf(%d", &n); ]
    - n の表示 [ printf(" %5d\n", n); ]
    - カウンタに初期値を設定 [ count = 0; ]
    - ここから繰り返しが始まる
        - カウンタを 1増やす [ count++; ]
        - nの各くらいをバラバラにする [ n = 1234 から a[4] = {1,2,3,4}  ]
        - 配列aの値を大きい順に並べる [ a[4] = {4,3,2,1 } ]
		- 最大値から最小値を引いて、それを n とする [ n = max - min ]
    - n が MAGICの値と等しくなるまで繰り返す
    - カウンタを表示 [ printf("%d time(s)\n", count); ]
(3) コードを書く
nの各くらいをバラバラにする

コード:

		a[0] = n % 10;
		a[1] = n / 10 % 10;
		a[2] = n / 100 % 10;
		a[3] = n / 1000;
配列aの値を大きい順に並べる

コード:

		for (i = 0; i < KETA - 1; i++) {
			k = i;
			for (j = i + 1; j < KETA; j++)
				if (a[j] > a[k]) k = j;
			tmp = a[i], a[i] = a[k], a[k] = tmp; 
		}
最大値をmaxへ、最小値をminへ、その差をnに代入する

コード:

		max = a[0]*1000 + a[1]*100 + a[2]*10 + a[3];
		min = a[3]*1000 + a[2]*100 + a[1]*10 + a[0];
		n = max - min;
		printf("%04d = %04d - %04d\n", n, max, min); // for debug
今までの回答者のすべてのアドバイスからプログラムを書いてみてください。

Re: do while文の問題

#7

by ととさん » 6年前

かめのこのこのこ さんが書きました:まずは、この問題を解く上で何が分からないのか切り出していきましょう。

① 問題文の言っていること (何をどうして、どういう結果が出ればよいのか) が分からない。

② ①は分かるが、どのような処理をやればよいのか (フローチャート) が分からない。

③ ②までは分かったか、それをどのように C 言語 (または C++) で書けばよいのか分からない。

④ ③まで出来たが、予想通りの結果が得られない。

質問に質問で返して悪いのですが、どこまでできているのか教えてください。
それぞれ何型(if文やdo while文など)を使えばよいかもわからず、
全くの手つかず状態です(-_-;)
色々説明を見てみたのですがお手上げ状態です…

Re: do while文の問題

#6

by かずま » 6年前

ととさん さんが書きました:あとは何をどうすればよいのか全く手つかずです(;´Д`)
/*ここから*/ を

コード:

    do {
に、/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/ を

コード:

    } while (n != MAGIC);
にします。これは、while文ではなく、do-while文です。

[url=http://dixq.net/board/board.html]フォーラムルール[url]の 4.義務行為に
・回答者のコメントの中に複数質問があった場合、出来る限りその全てに答えるようにしましょう。
とあります。No.2 のかめのこのこのこさんの質問にもぜひ答えてください。
よろしくお願いいたします。

Re: do while文の問題

#5

by かずま » 6年前

ととさん さんが書きました:/*条件を満たすnが入力を繰り返す部分*/をdo while文で出力するというところまで分かったのですが、このようにしか思いつきませんでした…
do{
printf("Conditions 1.'n' is a natural number less than 10000. 2.'n' is not divisible by 1111");
while(!(n % 1111 && n < 1000);
}
入力の scanf がありません。
それから、codeタグを使ってください。

次のコードを試してみてください。

コード:

#include <stdio.h>

int main(void)
{
    int n;
    do {
        printf("Conditions\n"
               " 1. 'n' is a natural number less than 10000.\n"
               " 2. 'n' is not divisible by 1111.\n"
               "Enter 'n': ");
        if (scanf("%d", &n) != 1) return 1;
    } while (n < 0 || n > 9999 || n % 1111 == 0);
    printf("n = %d\n", n);
    return 0;
}
実行結果

コード:

Conditions
 1.'n' is a natural number less than 10000.
 2.'n' is not divisible by 1111.
Enter n: 0
Conditions
 1.'n' is a natural number less than 10000.
 2.'n' is not divisible by 1111.
Enter n: 10000
Conditions
 1.'n' is a natural number less than 10000.
 2.'n' is not divisible by 1111.
Enter n: 9999
Conditions
 1.'n' is a natural number less than 10000.
 2.'n' is not divisible by 1111.
Enter n: 1234
n = 1234

scanf("%d", &n); だけでもいいんだけど、
間違って数字以外の文字を入力するとたいへんなことに
なってしまうので、if で返却値をチェックしています。
if がない場合も試してみてください。
何でもやってみることです。

Re: do while文の問題

#4

by purin52002 » 6年前

こんにちは

あとは
/*nの各くらいをバラバラにする部分*/
/*配列aの値を大きい順に並べる部分*/
/*最大値をmaxへ、最小値をminへ、その差をnに代入する部分*/
/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/
を実装できればいいわけですね。

/*nの各くらいをバラバラにする部分*/
例えば n=1234 だったとして、
{1,2,3,4} を取り出す方法を考えてみましょう。
一の位を取り出すのは簡単です。 10 で割ったあまりになります。
n mod 10 = 4
十の位を取り出すにはどうすればいいでしょうか?
一の位を取り出す方法はわかったので、 n を 123 にしてしまえばできそうです。
1234 を 123にするにはどうすればいいでしょうか?
C言語なら 10 で割るだけで 123 になります。(int型は小数点以下を切り捨てるから)
あとはこれを繰り返せば各位を取り出せそうです。
取り出した各位の値を 配列a に代入します。
代入する時点では順番はバラバラでも構いません。
n=1423 だったら a[4]={1,4,2,3} でも a[4]={3,2,4,1} でも大丈夫です。

/*配列aの値を大きい順に並べる部分*/
a[4]={1,4,2,3} だったとして、大きい順に並べ替えて a[4]={4,3,2,1} にしたいです。
大きい順に並べる方法(ソート)はいくつか種類がありますが、
今回は選択ソート(であってるかな?)を使います。
まず a[0](=1) と a[1](=4) を比較します。
a[1] の方が大きいので a[0] と a[1] を入れ替えます。(a[4]={4,1,2,3})
次に a[1](=1) と a[2](=2) を比較します。
a[2] の方が大きいので a[1] と a[2] を入れ替えます。(a[4]={4,2,1,3})
次に a[2](=1) と a[3](=2) を比較します。
a[3] の方が大きいので a[2] と a[3] を入れ替えます。(a[4]={4,2,3,1})
これを何度も繰り返すと最終的に a[4]={4,3,2,1} になります。

/*最大値をmaxへ、最小値をminへ、その差をnに代入する部分*/
最大値は 4321 、最小値は 1234 になりそうです。
これは 配列a の値を先頭から読みだした値、後方から読みだした値と等しくなりそうです。
{4,3,2,1} から 4321 に変換するにはどうすればいいでしょう?
めんどくさくなってきたので自分で考えてみてください^p^

/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/
while文で行けそうですね。
ところで、No.3のdo~while分の書き方は間違っている気がします。

コード:

do { 処理 }while( 判定 );
が正しいとおもいます^^

ふぁいと^p^

Re: do while文の問題

#3

by ととさん » 6年前

/*条件を満たすnが入力を繰り返す部分*/をdo while文で出力するというところまで分かったのですが、このようにしか思いつきませんでした…
do{
printf("Conditions 1.'n' is a natural number less than 10000. 2.'n' is not divisible by 1111");
while(!(n % 1111 && n < 1000);
}

あとは何をどうすればよいのか全く手つかずです(;´Д`)

Re: do while文の問題

#2

by かめのこのこのこ » 6年前

まずは、この問題を解く上で何が分からないのか切り出していきましょう。

① 問題文の言っていること (何をどうして、どういう結果が出ればよいのか) が分からない。

② ①は分かるが、どのような処理をやればよいのか (フローチャート) が分からない。

③ ②までは分かったか、それをどのように C 言語 (または C++) で書けばよいのか分からない。

④ ③まで出来たが、予想通りの結果が得られない。

質問に質問で返して悪いのですが、どこまでできているのか教えてください。

do while文の問題

#1

by ととさん » 6年前

問)1111で割り切れない10000未満の自然数に対して、各桁をバラバラにして組合せ、最大値から最小値をひくという操作を何回も行うと6174になることを確かめよ。ただし4桁未満の数の場合は上の桁に0を補って4桁と考える。

#include <stdio.h>
#define MAGIC 6174
#define KETA 4

int main()
{
int n;
int a[KETA];
int count ;
int max, min, tmp, i, j, k;

/*条件を満たすnが入力を繰り返す部分*/


printf(" %5d\n", n);
count = 0; /*初期値の設定*/

/*ここから*/
count++;

/*nの各くらいをバラバラにする部分*/
/*配列aの値を大きい順に並べる部分*/
/*最大値をmaxへ、最小値をminへ、その差をnに代入する部分*/


/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/

printf("%d time(s)\n", count);

return 0;
}

という問題なのですが全く手に負えません。
助けていただきたいです汗

ページトップ