🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

4回答

535閲覧

C言語:文字と整数の入れ替え

zyunnsuke

総合スコア4

C

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

0グッド

0クリップ

投稿2021/02/19 07:44

n S_1 D_1 S_2 D_2 ... S_i D_i ... S_n D_n

S_i は「文字」で、D_i は「整数」。
このような入力が行われるとき、D_iの大きさを基準にしてS_iとD_iを基準にして並び替えたい場合、どこを直したらいいでしょうか?
ただし、Sが被った場合、Sの列の整数を足さなければなりません。
以下は左が入力されたもの、右が出力しなければならないものです。

7 B 75 A 1 A 11 D 6 D 6 C 2 G 4 G 4 C 2 B 70 A 10 B 5

私は以下のようなコードを組んでいます。疑問点は文字が被ったところで整数を足し合わせる処理をしているにも関わらず整数が足されないところ、その後のprintfをどのように処理すればよいかというところです。どうかご教授お願いします。

C

1#include <stdio.h> 2#include <string.h> 3 4void swap_int(int *a,int *b){ 5 int temp = *a; 6 *a = *b; 7 *b = temp; 8} 9 10void swap_str(char *sa,char *sb){ 11 char temp[1000]; 12 strcpy(temp,sa); 13 strcpy(sa,sb); 14 strcpy(sb,temp); 15} 16 17void sort1(char str1[][1000],int num1[],int n1){ 18 int i,j; 19 for(i=0;i<n1-1;i++){ 20 for(j=n1-1;j > i;j--){ 21 if(num1[j-1] < num1[j]){ 22 swap_int(&num1[j-1],&num1[j]); 23 swap_str(str1[j-1] ,str1[j] ); 24 } 25 } 26 } 27} 28 29int main(void){ 30 31 char st[1000][1000],str[1000]; 32 int n,i,j,num[1000]; 33 fgets(str,"%s",stdin); 34 sscanf(str,"%d",&n); 35 for(i=0;i<n;i++){ 36 fgets(str,"%s",stdin); 37 sscanf(str,"%s%d",st[i],&num[i]); 38 } 39 40 sort1(st,num,n); ///一回目のソート 41 for(i=0;i<n;i++){ ///大きいものから順に、文字が被ればその列の整数を足し合わせる。 42 for(j=i+1;j<n;j++){ 43 if(st[i] == st[j]){ 44 num[i] += num[j]; 45 } 46 } 47 } 48 sort1(st,num,n); ///二回目のソート 49 50 for(i=0;i<n;i++){ 51 printf("%s %d\n", st[i],num[i]); 52 } 53 return 0; 54}

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

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

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

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

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

guest

回答4

0

まず初めに文字毎の合計を出す。
その後でソートを行う。
という方がシンプルではないでしょうか?
合計することにより順位も変わってきてしまうので。
もし、「文字」が一文字なのであれば、
それをインデックスにして、直接配列に入れてしまうと、合計が楽にできると思います。

投稿2021/02/19 15:18

amiya

総合スコア1218

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

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

zyunnsuke

2021/02/19 15:58

そうですよね、アドバイスありがとうございます。
guest

0

まず、

if(st[i] == st[j]){

文字列の比較になっていません。
if(strcmp(st[i], st[j]) == 0){ とするか、
一文字という事が明確ならば、 if(*st[i] == *st[j]){ でしょうか。

また、加算した後の後始末してないので、同じ文字が現れます。
num[i] += num[j]; の後に、st[j] = '\0'; とするなどして、同じ文字が再度、参照されないようにする必要があります。

投稿2021/02/19 10:23

pepperleaf

総合スコア6385

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

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

zyunnsuke

2021/02/19 15:55

アドバイスありがとうございます。数時間試みたのですが、わたくしの技量が足らず実行できませんでした。せっかくアドバイスいただいたのにすみません。
guest

0

まずは、文字列と整数をセットにした構造体を作っておいて、
そいつの配列に入力値を入れておきます
そして、その内容に従って入れ替えなり処理を行えばいいって話になりますね

投稿2021/02/19 09:56

y_waiwai

総合スコア88038

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

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

zyunnsuke

2021/02/19 13:42

やはり構造体が適してますよね。ただ、うまく処理できなかったのでこのような形になりました。 アドバイスありがとうございます。
guest

0

ベストアンサー

mainの部分を修正しました。
最初のソートは不要です。
文字の比較はstrcmpを使用します。
同じ文字へ統合したとき、加算側の要素を削除する必要があります。
(加算側の文字を""でクリアしています)
加算側の要素が減った分、全体の要素数も減ります。
""でクリアされた要素は、後ろに持っていき、文字が""でない要素を前づめにします。
その後、2回目のソートを行います。(全体の要素数:nは変わっています)

C

1int main(void){ 2 3 char st[1000][1000],str[1000]; 4 int n,i,j,num[1000]; 5 int delete_ctr = 0; 6 fgets(str,"%s",stdin); 7 sscanf(str,"%d",&n); 8 for(i=0;i<n;i++){ 9 fgets(str,"%s",stdin); 10 sscanf(str,"%s%d",st[i],&num[i]); 11 } 12 13 //sort1(st,num,n); ///一回目のソート 14 for(i=0;i<n-1;i++){ ///大きいものから順に、文字が被ればその列の整数を足し合わせる。 15 if(strcmp(st[i],"") == 0) continue; 16 for(j=i+1;j<n;j++){ 17 if(strcmp(st[j],"") == 0) continue; 18 if(strcmp(st[i],st[j]) == 0){ 19 num[i] += num[j]; 20 strcpy(st[j],""); 21 num[j] = 0; 22 delete_ctr++; 23 } 24 } 25 } 26 //有効な文字列を前に詰める 27 if (delete_ctr > 0){ 28 for (i=0;i<n-1;i++){ 29 if(strcmp(st[i],"") != 0) continue; 30 for(j=i+1;j<n;j++){ 31 if (strcmp(st[j],"") == 0) continue; 32 swap_str(st[i],st[j]); 33 swap_int(&num[i],&num[j]); 34 break; 35 } 36 } 37 } 38 n -= delete_ctr; //削除した要素を減算 39 sort1(st,num,n); ///二回目のソート 40 41 for(i=0;i<n;i++){ 42 printf("%s %d\n", st[i],num[i]); 43 } 44 return 0; 45} 46

実行結果
B 75
A 11
D 6
G 4
C 2

投稿2021/02/20 02:38

編集2021/02/20 02:42
tatsu99

総合スコア5493

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

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

zyunnsuke

2021/02/20 03:07

ありがとうございます!無事解決いたしました。
dodox86

2021/02/20 05:19 編集

>@質問者さん (余計なお世話かもしれませんが) 問題の解決も大切ですが、質問者さんが理解して次はご自身でコードを書けるようになることがより大事なのだと思いますが、その辺りはだいじょうぶでしょうか。
zyunnsuke

2021/02/23 15:53

すみません。返信遅れてしまいました。 コードをなぞりながらどういった意味なのか考えながら使わせていただいているつもりです。また、今後も継続して学習する予定です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問