2012年4月29日星期日

データのソートについて

データのソートについて

たとえば、下のようなデータがあるとして

flow0_0 0.00 0.00 edge1_0 1.5 0 0

flow0_0 1.00 1.48 edge1_0 1.5 0 0

flow0_0 2.00 4.64 edge1_0 1.5 0 0

flow0_0 3.00 10.23 edge1_0 1.5 0 0

flow0_0 4.00 17.52 edge1_0 1.5 0 0

flow0_0 5.00 26.32 edge1_0 1.5 0 0

flow0_1 6.00 0.00 edge1_0 1.5 0 0

flow0_0 6.00 36.79 edge1_0 1.5 0 0

flow0_1 7.00 1.67 edge1_0 1.5 0 0

flow0_0 7.00 48.75 edge1_0 1.5 0 0

flow0_1 8.00 5.30 edge1_0 1.5 0 0

flow0_0 8.00 62.29 edge1_0 1.5 0 0

flow0_2 9.00 0.00 edge1_0 1.5 0 0

flow0_1 9.00 11.09 edge1_0 1.5 0 0

flow0_0 9.00 77.03 edge1_0 1.5 0 0

flow0_2 10.00 2.20 edge1_0 1.5 0 0

flow0_1 10.00 18.48 edge1_0 1.5 0 0

flow0_0 10.00 93.32 edge1_0 1.5 0 0

flow0_2 11.00 6.54 edge1_0 1.5 0 0

flow0_1 11.00 27.48 edge1_0 1.5 0 0



このデータを並び替えて



flow0_0 0.00 0.00 edge1_0 1.5 0 0

flow0_0 1.00 1.48 edge1_0 1.5 0 0

flow0_0 2.00 4.64 edge1_0 1.5 0 0

flow0_0 3.00 10.23 edge1_0 1.5 0 0

flow0_0 4.00 17.52 edge1_0 1.5 0 0

flow0_0 5.00 26.32 edge1_0 1.5 0 0

flow0_0 6.00 36.79 edge1_0 1.5 0 0

flow0_0 7.00 48.75 edge1_0 1.5 0 0

flow0_0 8.00 62.29 edge1_0 1.5 0 0

flow0_0 9.00 77.03 edge1_0 1.5 0 0

flow0_0 10.00 93.32 edge1_0 1.5 0 0

flow0_1 6.00 0.00 edge1_0 1.5 0 0

flow0_1 7.00 1.67 edge1_0 1.5 0 0

flow0_1 8.00 5.30 edge1_0 1.5 0 0

flow0_1 9.00 11.09 edge1_0 1.5 0 0

flow0_1 10.00 18.48 edge1_0 1.5 0 0

flow0_1 11.00 27.48 edge1_0 1.5 0 0

flow0_2 9.00 0.00 edge1_0 1.5 0 0

flow0_2 10.00 2.20 edge1_0 1.5 0 0

flow0_2 11.00 6.54 edge1_0 1.5 0 0

のような形にしたいのですが

そのプログラムがわかりません。教えてください。

flow0_0

flow0_1

flow0_2の順番にしたいです。



たとえば、flow0_300までデータがあってでもソートできますか?



よろしくお願いします。







/* 読み込み行の、第1番目と2番目の2項目データについて一括ソートする例です。

なお、メモリサイズは malloc()により動的となっており、読み込み行数はあなたのマシン容量となっています。



実行は

./×××.exe data.txt

○○○.txtファイルにしまいたければ

./×××.exe data.txt >○○○.txt

*/

#include <stdio.h> /* printf(), fgets(), sprintf() */

#include <string.h> /* strcmp() */

#include <stdlib.h> /* malloc() */

#include <errno.h> /* errno */

#define SIZE 128 /* 読み込みメモリ容量 */

#define RETU 40 /* 1行の文字列長さ */



struct view {

char code[6];

char val[10];

char pocket[RETU];

};



/* プロトタイプ宣言 */

void setup_data(char *a, char *b, char *p);

int compare(const void *ta, const void *tb);



int main(int argc, char *argv[])

{

FILE *fp;

char *file_name, temp[SIZE];

struct view (*dat);

int line_size, n_gyo, n, i;



/* 1)ファイル名を特定 */

if(argc!=2){

fprintf(stderr, "Parameter error.\n");

exit(EXIT_FAILURE);

}

file_name=argv[--argc];

/* 2)ファイルを開く */

if( (fp=fopen(file_name,"r")) == NULL){

fprintf(stderr, "%s\n", strerror(errno));

exit(EXIT_FAILURE);

}

/* 3)1行の大きさとその行数から、配列を動的に割り当て. */

fgets(temp, SIZE, fp);

line_size = strlen(fgets(temp, SIZE, fp));

fseek(fp, 0, SEEK_END);

n_gyo = ftell(fp) / line_size;

if((dat = (struct view *)malloc(n_gyo * sizeof(*dat))) == NULL){

fprintf(stderr, "%s\n", strerror(errno));

exit(EXIT_FAILURE);

}

fseek(fp, 0, SEEK_SET);

/* 4)ファイルの終わりまで配列を読み込み、その都度表示する */

n = 0;

while(i < n_gyo && fgets(dat[n].pocket, SIZE, fp) != NULL){

setup_data(dat[n].code, dat[n].val, dat[n].pocket);

fprintf(stderr, "%s\n", dat[n].pocket); //表示はお好きなように

n++;

}

fprintf(stderr, "\n");

/* 5)ファイルを閉じる */

fclose(fp);

/* 6)ソート(内部qsort()関数を使う) */

qsort(dat,n,sizeof(dat[0]), compare);

/* 7)結果の出力 */

for(i=0; i<n; i++){

printf("%s\n", dat[i].pocket);

}

/* 8)malloc()後のメモリ解法を忘れぬこと */

free(dat);



return 0;

}



void setup_data(char *a, char *b, char *p)

{

char buff[12], *x;

int c;

while(*p++ != '_');

x = buff;

while((*x++ = *p++) != ' ');

*x = '\0';

sprintf(a, "%4s", buff); //右詰めで4文字の長さ

while(*p == ' ') p++; //スペースをスキップ

x = buff;

while((*x++ = *p++) != ' ');

*x = '\0';

sprintf(b, "%8s", buff); //右詰めで8文字の長さ

while(*p != '\n') p++; //末尾を探し

*p = '\0'; //改行コードを抹消する

}



int compare(const void *ta, const void *tb)

{

struct view *a=(struct view *)ta, *b=(struct view *)tb;

int flag;

if((flag=strcmp(a->code, b->code)) == 0){ //codeについて

return strcmp(a->val, b->val); //valについて

} else return flag;

}







----- ./a.out data.txt 2>/dev/null -----

flow0_0 0.00 0.00 edge1_0 1.5 0 0

flow0_0 1.00 1.48 edge1_0 1.5 0 0

flow0_0 2.00 4.64 edge1_0 1.5 0 0

flow0_0 3.00 10.23 edge1_0 1.5 0 0

flow0_0 4.00 17.52 edge1_0 1.5 0 0

flow0_0 5.00 26.32 edge1_0 1.5 0 0

flow0_0 6.00 36.79 edge1_0 1.5 0 0

flow0_0 7.00 48.75 edge1_0 1.5 0 0

flow0_0 8.00 62.29 edge1_0 1.5 0 0

flow0_0 9.00 77.03 edge1_0 1.5 0 0

flow0_0 10.00 93.32 edge1_0 1.5 0 0

flow0_1 6.00 0.00 edge1_0 1.5 0 0

flow0_1 7.00 1.67 edge1_0 1.5 0 0

flow0_1 8.00 5.30 edge1_0 1.5 0 0

flow0_1 9.00 11.09 edge1_0 1.5 0 0

flow0_1 10.00 18.48 edge1_0 1.5 0 0

flow0_1 11.00 27.48 edge1_0 1.5 0 0

flow0_2 9.00 0.00 edge1_0 1.5 0 0

flow0_2 10.00 2.20 edge1_0 1.5 0 0

flow0_2 11.00 6.54 edge1_0 1.5 0 0








> ごめんなさい、プログラムはあまり勉強していないのでわかりません。



プログラムを勉強することが目的でないなら、sort コマンドとか使えばいいじゃん。結構 OS 標準で使えるでしょ。それでスクリプトでもでっち上げれば、入力データが毎回変わっても対応できるし。







#include <stdio.h>

#include <stdlib.h>



int cmp(const void *a, const void *b)

{

return strtol(*(char **)a + 6, NULL, 10) - strtol(*(char **)b + 6, NULL, 10);

}



int main(void)

{

const char *s[] = {"flow0_0 0.00 0.00 edge1_0 1.5 0 0",

"flow0_0 1.00 1.48 edge1_0 1.5 0 0",

"flow0_0 2.00 4.64 edge1_0 1.5 0 0",

"flow0_0 3.00 10.23 edge1_0 1.5 0 0",

"flow0_0 4.00 17.52 edge1_0 1.5 0 0",

"flow0_0 5.00 26.32 edge1_0 1.5 0 0",

"flow0_1 6.00 0.00 edge1_0 1.5 0 0",

"flow0_0 6.00 36.79 edge1_0 1.5 0 0",

"flow0_1 7.00 1.67 edge1_0 1.5 0 0",

"flow0_0 7.00 48.75 edge1_0 1.5 0 0",

"flow0_1 8.00 5.30 edge1_0 1.5 0 0",

"flow0_0 8.00 62.29 edge1_0 1.5 0 0",

"flow0_2 9.00 0.00 edge1_0 1.5 0 0",

"flow0_1 9.00 11.09 edge1_0 1.5 0 0",

"flow0_0 9.00 77.03 edge1_0 1.5 0 0",

"flow0_2 10.00 2.20 edge1_0 1.5 0 0",

"flow0_1 10.00 18.48 edge1_0 1.5 0 0",

"flow0_0 10.00 93.32 edge1_0 1.5 0 0",

"flow0_2 11.00 6.54 edge1_0 1.5 0 0",

"flow0_1 11.00 27.48 edge1_0 1.5 0 0"};

int i;

const int n = sizeof s / sizeof s[0];



for(i = 0; i < n; ++ i) puts(s[i]);

putchar('\n');

qsort(s, n, sizeof s[0], cmp);

for(i = 0; i < n; ++ i) puts(s[i]);

return 0;

}







できますよ。



あなたはどこまで考えたのですか?

質問の補足で

あなたの考えたプログラムを見せて下さい。

それを見た上で、お教えしてもいいです。

没有评论:

发表评论