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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

1642閲覧

9999-9999を0000ではなく0と出力する方法

hagito

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/08/25 03:16

プログラムの目的:
4桁以下の正の整数値に対して,各桁の数を並べ替えてできる「最大の整数値」と「最小の整数値」の差を計算し、整数値を作成。この作業を繰り返すと必ずある整数値に収束する。コマンドライン入力に4桁以下の正の整数値 ???? を入力すると,上記の計算を繰り返し,収束するまでの整数値を標準出力に出力するプログラムを作成したい。

もし桁数が4桁に満たない場合は、0を代入(もし21なら、0021と捉え、最大値2100と最小値12となる)。

質問内容: 4桁の値が全部同じ時(1111,9999など)、差を「0」と出力したいのに「0000」となってしまいます。なので、「4桁の数が全て同じ時は0を出力する」という場合分けで対処しました。ところが、この解答だとダメだということでした。他に0を消す方法が分からないので、教えていただければと思います。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4void sort(char ar[]) { 5 int i, j, tmp, m, n, z; 6 char max[4], min[4], sum[4], final[4]={0}; 7 8 z = 0; 9 for (; z==0;) { 10 11 //まずは最大値 12 for (i=0; i<4; i++) { 13 for (j=3; j>i; j--) { 14 if (ar[j] > ar[j-1]) { 15 tmp = ar[j]; 16 ar[j] = ar[j-1]; 17 ar[j-1] = tmp; 18 } 19 } 20 } 21 for (i=0; i<4; i++) { 22 max[i] = ar[i]; 23 } 24 25 //次に最小値 26 for (i=0; i<4; i++) { 27 28 for (j=3; j>i; j--) { 29 if (ar[j] < ar[j-1]) { 30 tmp = ar[j]; 31 ar[j] = ar[j-1]; 32 ar[j-1] = tmp; 33 } 34 } 35 } 36 37 for (i=0; i<4; i++) { 38 min[i] = ar[i]; 39 40 } 41 //次は、最大値から最小値を引き続ける計算式。 42 m = 0; 43 n = 0; 44 45 //4桁の引き算 46 for (i=3; 0<=i; i--) { 47 if (m + max[i] - min[i] >= 0) { 48 n = m + max[i] - min[i]; 49 m = 0; 50 } else { 51 n = 10 + m + max[i] - min[i]; 52 m = -1; 53 } 54 sum[i] = n; 55 } 56 57 //4桁の数が全て同じの時は、0を一つだけ出力。 58 if (sum[0] == 0 && sum[1] == 0 && sum[2] == 0 && sum[3] == 0) { 59 printf("%d\n", 0); 60 break; 61 } else { 62 for (i=0; i<4; i++) { 63 printf("%d", sum[i]); 64 ar[i] = sum[i]; 65 } 66 } 67 printf("\n"); 68 if(final[0]==ar[0] && final[1]==ar[1] && final[2]==ar[2] && final[3]==ar[3]) { 69 break; 70 } else { 71 for (i=0; i<4; i++) final[i] = ar[i]; 72 } 73 } 74} 75 76int main(int argc, char *argv[]) { 77 int num; 78 char str[4]; 79 80 //4桁以下の整数を受けとり、atoi関数で数値化してnumに代入。 81 if ((0 < atoi(argv[1]) && atoi(argv[1]) < 10000)) num = atoi(argv[1]); 82 83 //numの値を配列strに格納していく。 84 str[0] = num / 1000; 85 str[1] = num % 1000 / 100; 86 str[2] = num % 100 / 10; 87 str[3] = num % 10; 88 89 sort(str); 90 91 return 0; 92} 93

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

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

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

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

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

Zuishin

2021/08/25 03:18

0000 だけではなく 0123 を 123 と表示しなければいけないのでは?
guest

回答5

0

数字の列を数値に変換するのに atoi を、
数値を数字の列に変換するのに sprintf を使うと、

C

1#include <stdio.h> // sprintf, printf 2#include <stdlib.h> // atoi 3 4void swap(char *a, int i, int j) 5{ 6 char t = a[i]; a[i] = a[j], a[j] = t; 7} 8 9void sort4(char *a) 10{ 11 for (int i = 0; i < 3; i++) 12 for (int j = i; ++j < 4; ) 13 if (a[i] > a[j]) swap(a, i, j); 14} 15 16int main(int argc, char *argv[]) 17{ 18 if (argc != 2) return 1; 19 int num = atoi(argv[1]), min, max, prev = -1; 20 if (num <= 0 || num > 9999) return 2; 21 char a[5]; 22 for (;;) { 23 sprintf(a, "%04d", num); 24 sort4(a); 25 min = atoi(a); 26 swap(a, 0, 3); 27 swap(a, 1, 2); 28 max = atoi(a); 29 num = max - min; 30 if (num == prev) break; 31 prev = num; 32 printf("%04d - %04d = %d\n", max, min, num); 33 } 34}

投稿2021/08/26 02:37

編集2021/08/26 02:46
kazuma-s

総合スコア8224

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

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

hagito

2021/08/26 07:36

ご回答ありがとうございます。 sprintf関数というものがあるのですね。知らなかったです。今後の学習の参考にさせていただきます。
guest

0

どのタイミングでどの値を表示するのかがちょっと分かり難いですね。
桁毎に分けた状態を維持しようとして計算等苦労されている様子です。
逆に数値の状態を本来として維持して、最大値最小値を生成する部分でだけ桁分け等の処理をするとスッキリします。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4struct AnagramInfo { 5 int start, delta; 6}; 7struct AnagramInfo AnagramMax = { 0, 1 }; 8struct AnagramInfo AnagramMin = { 10-1, -1 }; 9 10// num を構成する数字を組み替えて出来る値を返す。 11// num が4桁に足りない場合は、上位桁を 0 と見なす。 12int anagrammatic(int num, struct AnagramInfo info) { 13 int a[10] = {0}; 14 for(int i=1; i<=1000; i*=10) a[num/i%10] ++; 15 num = 0; 16 for(int i=1, j=info.start; 10>j && j>=0; ) { 17 if(a[j] > 0) { 18 num += j*i; 19 a[j] --; 20 i *= 10; 21 } else { 22 j += info.delta; 23 } 24 } 25 return num; 26} 27 28void sort(int num) { 29 30 for(int prev=-1; ; prev=num) { 31 //最大値 32 int max = anagrammatic(num, AnagramMax); 33 34 //最小値 35 int min = anagrammatic(num, AnagramMin); 36 37 //計算 38 num = max - min; 39 if(num == prev) break; //収束していたら終了 40 41 //状況表示 42 printf("%d - %d = %d\n", max, min, num); 43 44 if(num == 0) break; //0 なら終了 45 } 46} 47 48int main(int argc, char *argv[]) { 49 50 //4桁以下の整数を受けとり、atoi関数で数値化してnumに代入。 51 int num = atoi(argv[1]); 52 if (0 < num && num <= 9999) sort(num); 53 54 return 0; 55} 56

12 を指定したらこんな感じ

plain

12100 - 12 = 2088 28820 - 288 = 8532 38532 - 2358 = 6174

1111 では

plain

11111 - 1111 = 0

投稿2021/08/25 07:57

編集2021/08/25 08:20
jimbe

総合スコア13168

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

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

hagito

2021/08/26 07:34

ご回答ありがとうございます。 まだ構造体を学んでいないので完全に理解することはできないのですが、今後の学習の参考にさせていただきます。プログラムへのご指摘も助かりました。
guest

0

難しく考えずに、mainにある数値を配列に分けた方法の逆の要領で、配列を1つの数値に戻してから、
printf("%d",num);とすれは、自動的に頭の0は付かなくなるかと。

投稿2021/08/25 03:47

amiya

総合スコア1218

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

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

hagito

2021/08/25 07:33

ご回答ありがとうございます。 ああ、数値に戻すんですね。ちょっとやってみます!
hagito

2021/08/26 07:32

数値に変換して進めたら無事に0が消え、完成させることができました。ありがとうございました!
guest

0

ベストアンサー

//4桁の引き算

のところで、桁ごとに計算するをでなく、一つの数として計算しましょう。
{2,1,0,0}から{0,0,1,2}を引くんじゃなくて、数値の2100から12を引くということです。
その結果を%dで出力すれば良いです。

{2,1,0,0}をどうやって2100というintにするかわかりますか?

投稿2021/08/25 03:41

編集2021/08/25 22:42
otn

総合スコア85762

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

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

hagito

2021/08/25 07:29

ご回答ありがとうございます。 ああ、数値で計算するんですね!atoi関数ですよね、ちょっとやってみます!
hagito

2021/08/25 20:12

いや、atoiじゃないですね。。。{'2','1','0','0'}ならできますが、{2,1,0,0}だと出来ない。 どうやるのでしょうか。
otn

2021/08/25 22:41

((2*10+1)*10+0)*10+0 とか 2*1000+1*100+0*10+0 とか。 普通は前者をループで処理します。
hagito

2021/08/26 07:31

具体的な回答ありがとうございます。 頂いた式を利用して、無事にプログラムを完成させることができました。ありがとうございました!
guest

0

上位から順に出力するとき、0が続いているうちは出力しないようにする。最下位桁が来たら例外的に0を出力。
というコードを組みましょう。

しかし、整数値に変換して出力する、ってのがコード量も少なくていいのでは

投稿2021/08/25 03:40

y_waiwai

総合スコア88024

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

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

hagito

2021/08/25 07:32

ご回答ありがとうございます。 確かにコード量がとても長くて自分でもわかりにくいなと思ってました。やってみます!
y_waiwai

2021/08/25 07:37

まあ、printfの関数はそれを内部でやってるんですね なにげに使ってる関数も、自分でつくろうとするとむずかしいもんです
hagito

2021/08/26 07:30

なるほど。。。本当に難しいです。。。 アドバイス頂いた通りに整数値に変換して取り組んだら、無事にプログラムを完成させることができました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問