do while文の問題
do while文の問題
問)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;
}
という問題なのですが全く手に負えません。
助けていただきたいです汗
#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;
}
という問題なのですが全く手に負えません。
助けていただきたいです汗
Re: do while文の問題
まずは、この問題を解く上で何が分からないのか切り出していきましょう。
① 問題文の言っていること (何をどうして、どういう結果が出ればよいのか) が分からない。
② ①は分かるが、どのような処理をやればよいのか (フローチャート) が分からない。
③ ②までは分かったか、それをどのように C 言語 (または C++) で書けばよいのか分からない。
④ ③まで出来たが、予想通りの結果が得られない。
質問に質問で返して悪いのですが、どこまでできているのか教えてください。
① 問題文の言っていること (何をどうして、どういう結果が出ればよいのか) が分からない。
② ①は分かるが、どのような処理をやればよいのか (フローチャート) が分からない。
③ ②までは分かったか、それをどのように C 言語 (または C++) で書けばよいのか分からない。
④ ③まで出来たが、予想通りの結果が得られない。
質問に質問で返して悪いのですが、どこまでできているのか教えてください。
Re: do while文の問題
/*条件を満たす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);
}
あとは何をどうすればよいのか全く手つかずです(;´Д`)
do{
printf("Conditions 1.'n' is a natural number less than 10000. 2.'n' is not divisible by 1111");
while(!(n % 1111 && n < 1000);
}
あとは何をどうすればよいのか全く手つかずです(;´Д`)
- purin52002
- 記事: 235
- 登録日時: 7年前
- 連絡を取る:
Re: do while文の問題
こんにちは
あとは
/*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分の書き方は間違っている気がします。 が正しいとおもいます^^
ふぁいと^p^
あとは
/*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分の書き方は間違っている気がします。 が正しいとおもいます^^
ふぁいと^p^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^
Re: do while文の問題
入力の scanf がありません。ととさん さんが書きました:/*条件を満たす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);
}
それから、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
間違って数字以外の文字を入力するとたいへんなことに
なってしまうので、if で返却値をチェックしています。
if がない場合も試してみてください。
何でもやってみることです。
Re: do while文の問題
/*ここから*/ を に、/*ここまでをnがMAGICの値と等しくなるまで繰り返す*/ を にします。これは、while文ではなく、do-while文です。ととさん さんが書きました:あとは何をどうすればよいのか全く手つかずです(;´Д`)
[url=http://dixq.net/board/board.html]フォーラムルール[url]の 4.義務行為に
とあります。No.2 のかめのこのこのこさんの質問にもぜひ答えてください。・回答者のコメントの中に複数質問があった場合、出来る限りその全てに答えるようにしましょう。
よろしくお願いいたします。
Re: do while文の問題
それぞれ何型(if文やdo while文など)を使えばよいかもわからず、かめのこのこのこ さんが書きました:まずは、この問題を解く上で何が分からないのか切り出していきましょう。
① 問題文の言っていること (何をどうして、どういう結果が出ればよいのか) が分からない。
② ①は分かるが、どのような処理をやればよいのか (フローチャート) が分からない。
③ ②までは分かったか、それをどのように C 言語 (または C++) で書けばよいのか分からない。
④ ③まで出来たが、予想通りの結果が得られない。
質問に質問で返して悪いのですが、どこまでできているのか教えてください。
全くの手つかず状態です(-_-;)
色々説明を見てみたのですがお手上げ状態です…
Re: do while文の問題
(2) までは分かるが、(3) からあとが分からないということですか?ととさん さんが書きました:それぞれ何型(if文やdo while文など)を使えばよいかもわからず、
全くの手つかず状態です(-_-;)
まず、(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); ]
nの各くらいをバラバラにする 配列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;
}
Re: do while文の問題
まず、(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
といったことは確かめてみましたか?
上の計算の出し方がわからず、確かめられていません(-_-;)
入力が 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文の問題
[1] 自然数とは、正の整数で、1, 2, 3, ...1111で割り切れない10000未満の自然数に対して、
各桁をバラバラにして組合せ、
最大値から最小値をひく
という操作を何回も行うと6174になること
を確かめよ。
ただし4桁未満の数の場合は上の桁に0を補って4桁と考える。
[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文の問題
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':後に数字を打った後何も出力されません。
何が原因かわかっていません。
プログラムをコンパイルして実行できる環境はあります。
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文の問題
ととさん さんが書きました: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文の問題
26行目に return 0; があるので、ここでプログラムは終了します。ととさん さんが書きました: と実行したいのですが以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
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文の問題
ちょっと説明が間違っていました。
そのあと、何も出力されないのは、二つ目の scanf が
入力を待っているからです。
そこで、もう一度、数字を入力すると、先に進み、
printf("%d"); で、何かの数字を表示します。
n とは書いていないので、どんな値になるかわかりません。
そして、return 0; でプログラムは終了します。
に変更しないと、そんな出力にはなりません。
プログラムは、思った通りには動くのではなく、
書いたとおりに動くのです。
打った数字は、一つ目の scanf で n に入ります。ととさん さんが書きました: Enter 'n':後に数字を打った後何も出力されません。
何が原因かわかっていません。
そのあと、何も出力されないのは、二つ目の scanf が
入力を待っているからです。
そこで、もう一度、数字を入力すると、先に進み、
printf("%d"); で、何かの数字を表示します。
n とは書いていないので、どんな値になるかわかりません。
そして、return 0; でプログラムは終了します。
をととさん さんが書きました: Enter 'n' :1234
1234
⇒ 3087 (= 4321 - 1234)
⇒ 8352 (= 8730 - 378)
⇒ 6174 (= 8532 - 2358)
3 time(s)
と実行したいのですが
に変更しないと、そんな出力にはなりません。
プログラムは、思った通りには動くのではなく、
書いたとおりに動くのです。
Re: do while文の問題
21行目のscanfで数字を読んだ後、22行目のscanfで入力待ちになっているのでしょう。ととさん さんが書きました:以下のプログラムだと
Enter 'n':後に数字を打った後何も出力されません。
printfで書式に対しデータが足りないので、未定義動作になります。かずま さんが書きました:printf("%d"); で、何かの数字を表示します。
n とは書いていないので、どんな値になるかわかりません。
定義上何が起こってもおかしくありません。
こう変更しても、 のようになってしまい(余計な0が付く)、 とはならないでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)