ソート部分がどうしてもできません。
またソートは以下のアルゴリズムで行うものです
与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。
1.リストAの要素の中で、最大値をもつ要素Cを探す。
2.要素CをリストAから削除する。
3.要素CをリストBの先頭に挿入する。
4.リストAが空であれば終了。空でなければ 1. にもどる。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct physical Physical;
struct physical {
char name[41];
int age;
float height;
float weight;
Physical *next;
};
void read_data(char *file,Physical *p,Physical *tail);
int comp1(const Physical *, const Physical *);
int comp2(const Physical *, const Physical *);
int comp3(const Physical *, const Physical *);
int comp4(const Physical *, const Physical *);
void sort(char *arg,Physical *p,Physical *q);
Physical *listsort(Physical *p, int (*compar)(const void *, const void *));
int main(void) {
char s[20],t,u[20];
Physical *p,*tail,*q;
p=malloc(sizeof(Physical));
q=malloc(sizeof(Physical));
tail=malloc(sizeof(Physical));
while(1)
{ printf("CMD>");
fflush(stdout);
fgets(s,20,stdin);
sscanf(s,"%c %s",&t,u);
switch(t){
case 'q':exit(0);
case 'r':read_data(u,p,tail);
break;
case 's':sort(u,p,q);
break;
case 'd':
while(q!=NULL)
{ printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight );
q=q->next;}
break;
}
}
free(p);
return 0;
}
void read_data(char *file,Physical *p,Physical *tail){
FILE *fp;
char string[100];
Physical header;
tail=&header;
header.next = NULL;
p->next = NULL;
tail->next = p;
tail = p;
if ((fp = fopen(file, "r")) == NULL)
{ exit(1); }
while(fgets(string,sizeof(string),fp)!= NULL)
{ sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight);
Physical *tail2;
tail2=malloc(sizeof(Physical));
tail2->next=NULL;
p->next=tail2;
p=tail2;
}
fclose(fp);
}
void sort(char *arg,Physical *p,Physical *q){
if(strcmp(arg,"name") == 0)
q=listsort(p,(int(*)(const void*, const void*))comp1);
if(strcmp(arg,"age") == 0)
q=listsort(p,(int(*)(const void*, const void*))comp2);
if(strcmp(arg,"height") == 0)
q=listsort(p,(int(*)(const void*, const void*))comp3);
if(strcmp(arg,"weight") == 0)
q=listsort(p,(int(*)(const void*, const void*))comp4);
}
Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){
Physical *q, *max,*s,*head;
s=malloc(sizeof(Physical));
head=malloc(sizeof(Physical));
head=NULL;
while(p->next){max = p, q = p->next;
while( q->next ) {
if( compar(q->next,max->next) )
max = q;
q = q->next;}
s=max->next;
max->next=max->next->next;
if(head==NULL)
{head=s;}
s->next=s;
}
return head;
}
int comp1(const Physical *a, const Physical *b){
return (strncmp(a->name,b->name,sizeof(Physical)));
}
int comp2(const Physical *a, const Physical *b){
if(a->age > b->age) return 1;
else return 0;
}
int comp3(const Physical *a, const Physical *b){
if(a->height > b->height) return 1;
else return 0;
}
int comp4(const Physical *a, const Physical *b){
if(a->weight > b->weight) return 1;
else return 0;
}
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
>またソートは以下のアルゴリズムで行うものです
>与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。
>1.リストAの要素の中で、最大値をもつ要素Cを探す。
>2.要素CをリストAから削除する。
>3.要素CをリストBの先頭に挿入する。
>4.リストAが空であれば終了。空でなければ 1. にもどる。
リストA、リストBとありますが、リストAだけの方が簡単だと思います。
「やはりリストBも用いて、手順どおりに」でしたら、以降無視して下さい。
++++++++++++++++++++++++++++++++
☆リストAだけのもので、ソート機能を確認することを主目的に、簡便化したものを投稿します。
・この手の処理では、構造体(頭)はグローバルが易しいかと。
・リスト「入れ換え」の注意点として、アドレスは入れ換えない(◆)ことです(入れ物はそのままで、中身のみ入り換え)。
なお、comp1() は、思うように機能しませんでした・・残念。
用いたデータ( test.txt )
abc 18 170.2 68.3
xxx 19 173.4 65.1
nnn 55 170.1 80.4
yyy 30 172.3 66.2
++++++++++++++++++++++++++++++++
#1 さんへ
ひょっとして
#include <stdio.h>
void foo(int *x)
{
*x = 4;
}
int main()
{
int x = 3;
foo(&x);
printf("%d\n", x);
return 0;
}
というプログラムで、「4」が出力されると質問者様は、確信しているのでは?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _cell{
char name[ 32 ]; // 奇数キライ
int age;
float height;
float weight;
struct _cell *next;
}PHYSICAL;
PHYSICAL sgHead;
int comp1( const PHYSICAL *a, const PHYSICAL *b ){
return ( strncmp( a->name, b->name, sizeof(PHYSICAL) ) );
}
int comp2( const PHYSICAL *a, const PHYSICAL *b ){
if( a->age > b->age ) return 1;
return 0;
}
int comp3( const PHYSICAL *a, const PHYSICAL *b ){
if( a->height > b->height ) return 1;
return 0;
}
int comp4( const PHYSICAL *a, const PHYSICAL *b ){
if( a->weight > b->weight ) return 1;
return 0;
}
void read_data( char *file )
{
FILE *fp;
char string[ 64 ];
PHYSICAL *p, *q, *new_p;
if( ( fp = fopen( file, "r" ) ) == NULL ) exit( 1 );
while( fgets( string, sizeof( string ), fp ) != NULL ){
p = sgHead.next;
q = &sgHead;
while( NULL != p ){
q = p;
p = p->next;
}
new_p = (PHYSICAL *)malloc( sizeof(PHYSICAL) ); // 1人分のメモリ確保
sscanf( string, "%s %d %f %f", new_p->name, &new_p->age, &new_p->height, &new_p->weight );
new_p->next = NULL;
q->next = new_p;
}
fclose( fp );
}
void listsort( int (*compar)( const PHYSICAL *, const PHYSICAL * ) )
{
PHYSICAL *q, *s, tmp;
long lTmp;
for( q = sgHead.next; NULL != q; q = q->next ){
for( s = q->next; NULL != s; s = s->next ){
if( compar( q, s ) ){
tmp = *q;
*q = *s;
*s = tmp;
lTmp = (long)q->next; // ◆アドレスを戻す
q->next = s->next;
s->next = (PHYSICAL *)lTmp;
}
}
}
}
void sort( char *arg )
{
if( strcmp( arg, "name" ) == 0 ) listsort( ( int(*)( const PHYSICAL *, const PHYSICAL * ) )comp1 );
if( strcmp( arg, "age" ) == 0 ) listsort( ( int(*)( const PHYSICAL *, const PHYSICAL * ) )comp2 );
if( strcmp( arg, "height" ) == 0 ) listsort( ( int(*)( const PHYSICAL *, const PHYSICAL * ) )comp3 );
if( strcmp( arg, "weight" ) == 0 ) listsort( ( int(*)( const PHYSICAL *, const PHYSICAL * ) )comp4 );
}
void Output( void )
{
PHYSICAL *q;
q = sgHead.next;
while( q != NULL ){
printf( "%-16s %d %.1f %.1f\n", q->name, q->age, q->height, q->weight );
q = q->next;
}
printf( "\n" );
}
void AllDeleteList( void )
{
PHYSICAL *p;
while( NULL != sgHead.next ){
p = sgHead.next;
sgHead.next = p->next;
free( p );
}
}
void main( void )
{
sgHead.next = NULL;
read_data( "test.txt" );
Output(); // 出力
sort( "height" ); // 身長でソート
Output(); // 出力
AllDeleteList(); // メモリ解放
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.2
- 回答日時:
ソースコードをすべて見たわけではありませんが、
気になる点があります。
listsort関数の下記コードで
>head=malloc(sizeof(Physical));
>head=NULL;
mallocでせっかく確保した領域が、直後の文でムダになるとともに、
メモリリークを起こしています。
これはまずいです。
この2つの文を連続して書いた理由は、どういったものですか?
また、mallocの呼び出し全般についていえることは、
mallocによる領域確保は必ず成功する「とは限りません」。
戻り値をチェックすることは必須です。
No.1
- 回答日時:
「ソート部分がどうしてもできません。
」というのはどのような状態を指しているのでしょうか?あと, ひょっとして
#include <stdio.h>
void foo(int x)
{
x = 4;
}
int main()
{
int x = 3;
foo(x);
printf("%d\n", x);
return 0;
}
というプログラムで「4」が出力されると思ってはいないですよね?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
C# Controls.Addで動的に配置し...
-
Notepad++の関数リスト表示の変...
-
C++にてtemplateで受け取った任...
-
C# KeyDownイベントでショート...
-
C/C++でのScene管理について
-
静的でないメンバ関数の呼び出...
-
void*型の配列について
-
const_castのつかいどころを教...
-
C#でラジオボタンを設定に記録...
-
VisualStudio2005C++の某参考書...
-
VC++でGetKeyboardStateがうま...
-
C言語 プロトタイプ宣言
-
こんなコンパイルエラーがでます。
-
LNK2019:未解決の外部シンボル ...
-
int main()、void main()、void...
-
C#でテンキーの操作は可能でし...
-
VC++ DirectShow グラフにフ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
静的でないメンバ関数の呼び出...
-
C++にてtemplateで受け取った任...
-
戻り値を返す関数の前に(void)...
-
多重定義が起きている?--lnk20...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
int main()、void main()、void...
-
const_castのつかいどころを教...
-
C# KeyDownイベントでショート...
-
VC++でGetKeyboardStateがうま...
-
void*型の配列について
-
C#でラジオボタンを設定に記録...
-
Notepad++の関数リスト表示の変...
-
_beginthreadにて発生するコン...
-
ArduinoでMouse関数を使用して...
-
ウインドウの移動禁止
-
コールバックって・・・
-
構造体を宣言と共に初期化する方法
おすすめ情報