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

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

新規登録して質問してみよう
ただいま回答率
85.47%
配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

625閲覧

[C言語]構造体のソート

HYYH

総合スコア16

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2022/07/05 05:40

編集2022/07/05 05:41

構造体のソートを学習する問題です。
チーム名と点数を一緒にソートしたいのですが、ポインタがうまく操作しません。
このソースコードを実行すると、頭文字だけ入れ替わります。
改善策を教えていただけませんか?

C

1#include<stdio.h> 2 3/*構造体の定義*/ 4typedef struct { 5 char name[11]; 6 int point; 7} TEAM; 8 9/*プロトタイプ宣言*/ 10void marge_sort(TEAM*,int,int); 11void marge(TEAM*,int,int,int); 12 13void marge_sort(TEAM*A,int left,int right){ 14 if(left==right){ 15 return; //終了条件 16 } 17 int mid=(left+right)/2; //分割位置(小数点以下切り捨て) 18 marge_sort(A,left,mid); //再帰呼び出し 19 marge_sort(A,mid+1,right); //再帰呼び出し 20 marge(A,left,mid,right); 21} 22 23void marge(TEAM*A,int left,int mid,int right){ 24 int i=left; //左部分の先頭 25 int j=mid+1; //右部部分の先頭 26 int k=0; //作業用配列の先頭 27 TEAM B[10]; //作業用配列 28 while(i<=mid&&j<=right){ //左部分と右部分とが両方あるとき 29 if(A[i].point<=A[j].point){ 30 B[k].point=A[i].point; 31 *B[k].name=*A[i].name; 32 i++; 33 } 34 else{ 35 B[k].point=A[j].point; 36 *B[k].name=*A[j].name; 37 j++; 38 } 39 k++; 40 } 41 if(i==mid+1){ //左部分残り無し 42 while(j<=right){ 43 B[k].point=A[j].point; 44 *B[k].name=*A[j].name; 45 j++; 46 k++; 47 } 48 } 49 else{ //右部分残り無し 50 while(i<=mid){ 51 B[k].point=A[i].point; 52 *B[k].name=*A[i].name; 53 i++; 54 k++; 55 } 56 } 57 int n; 58 for(n=0;n<=k-1;n++){ //コピー 59 A[left+n].point=B[n].point; 60 *A[left+n].name=*B[n].name; 61 } 62} 63 64 65 66int main(void){ 67 int i; 68 TEAM data[]={{"Apple",32},{"Pear",12},{"Strawberry",28},{"Melon",5}, 69 {"Orange",32},{"Peach",16},{"Mango",12},{"Pineapple",32}}; 70 71 marge_sort(data,0,7); 72 73 for(i=0;i<=7;i++){ 74 printf("team:%s,point:%d\n",data[i].name,data[i].point); 75 } 76return 0; 77}

【実行結果】
team:Mpple,point:5
team:Pear,point:12
team:Mtrawberry,point:12
team:Pelon,point:16
team:Srange,point:28
team:Aeach,point:32
team:Oango,point:32
team:Pineapple,point:32

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

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

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

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

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

guest

回答3

0

*B[k].name=*A[i].name;

これ、nameの先頭文字のみの代入ですね

すなおに、
B[k] = A[i]; でいけませんかね

投稿2022/07/05 05:48

編集2022/07/05 05:49
y_waiwai

総合スコア87784

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

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

0

文字列のコピーで代入演算子を使って失敗していると思います.
ALOHAMSさんのおっしゃるようにstrcpyを使うか,
それともy_waiwaiさんのおっしゃるように構造体の代入を使うか.

C

1/* teratail_0y7fmni9wp3orm_revised.c */ 2 3#include <stdio.h> 4#include <stdlib.h> 5 6typedef struct { 7 char name[16]; 8 int point; 9} TEAM; 10 11void merge_sort(TEAM *, int, int); 12void merge(TEAM *, int, int, int); 13void show(TEAM *, int); 14 15int main(void){ 16 TEAM data[] = { 17 {"Apple",32},{"Pear",12},{"Strawberry",28},{"Melon",5}, 18 {"Orange",32},{"Peach",16},{"Mango",12},{"Pineapple",32} 19 }; 20 int n = (sizeof data) / (sizeof data[0]); 21 22 merge_sort(data,0,n-1); 23 show(data,n); 24 25 return 0; 26} 27 28void merge_sort(TEAM *A, int left, int right) { 29 if (left == right) { 30 return; 31 } 32 int mid = (left+right)/2; 33 merge_sort(A,left,mid); 34 merge_sort(A,mid+1,right); 35 merge(A,left,mid,right); 36} 37 38void merge(TEAM *A, int left, int mid, int right) { 39 TEAM *B = (TEAM *)malloc(sizeof(TEAM)*(right+1)); 40 int i = left; 41 int j = mid + 1; 42 int k = 0; 43 44 while (i <= mid && j <= right) { 45 if(A[i].point <= A[j].point) { 46 B[k] = A[i]; 47 i++; 48 } 49 else { 50 B[k] = A[j]; 51 j++; 52 } 53 k++; 54 } 55 if (i == mid + 1) { 56 while (j <= right) { 57 B[k] = A[j]; 58 j++; 59 k++; 60 } 61 } 62 else { 63 while (i <= mid) { 64 B[k] = A[i]; 65 i++; 66 k++; 67 } 68 } 69 int m; 70 for (m = 0; m < k; m++) { 71 A[left+m] = B[m]; 72 } 73 free(B); 74 B = NULL; 75} 76 77void show(TEAM *A, int n) { 78 int i; 79 80 for(i = 0; i < n; i++) { 81 printf("team: %-12s, point: %2d\n",A[i].name,A[i].point); 82 } 83}

投稿2022/07/07 10:20

編集2022/07/07 10:24
obeSolitary

総合スコア106

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

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

0

ベストアンサー

C

1*B[k].name=*A[i].name; 23*A[left + n].name = *B[n].name;

上記の箇所を以下のように修正することで解決すると思います。
#include <string.h>は適当なところに入れておいてください。

C

1#include <string.h>  2strcpy(B[k].name, A[i].name); 3 4strcpy(A[left + n].name, B[n].name);

基本的に配列の要素を他の配列の要素に一度に代入することはできません。(多分)
自力でやるならfor文で1文字ずつnameに代入する形になりますが、面倒なのでstrcpyという関数を使えば一度にコピーしてくれます。

投稿2022/07/05 07:52

編集2022/07/05 08:19
ALOHAMS

総合スコア195

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問