char型の5桁の数字をソートする方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
lily

char型の5桁の数字をソートする方法

#1

投稿記事 by lily » 6年前

コード:

void sortzip(Employees workers[], int size){
    
    int i,j,temp;
    
      for (i=1;i<size;i++){
        
        temp=*workers[i].zip;
        j=i-1;
        while (j>=0&&temp<*workers[j].zip){
            *workers[j+1].zip=*workers[j].zip;
            j=j-1;
        }
        *workers[j+1].zip=temp;
    }
    
    printf("\nk)\n");
  
    for (i=0;i<size;i++){
            printf("%s %s %s\n",workers[i].zip,workers[i].first,workers[i].last);
           
        }
}
この関数は姓名とzipコードの入ったworkersという構造体を引数でもらいその中のzipコードとした5桁のchar型の配列を昇順にソートして、その順に他の姓名も一緒に出力するプログラムを書こうとしたところです。

このまま出力してもzipコードの1桁目だけ昇順になったものしか出力されず、char型なのが原因だと思うのですが、atoi関数などで一度int型に変換して昇順に直しても、その後、zipコードの昇順で姓名を一緒に出力するプログラムがどうしても思いつきません。

説明が下手で申し訳ないのですが誰かご教授よろしくお願いします。

box
記事: 2002
登録日時: 13年前

Re: char型の5桁の数字をソートする方法

#2

投稿記事 by box » 6年前

こんなのじゃダメですか?

コード:

#include <string.h>

void sortzip(Employees workers[], int size)
{
    Employees t;
    int i, j;

    for (i = 0; i < size - 1; i++) {
        for (j = i; j < size; j++) {
            if strcmp(workers[i].zip, workers[j].zip) {
                t = workers[i], workers[i] = workers[j], workers[j] = t;
            }
        }
    }
    printf("\nk)\n");
    for (i = 0; i <size; i++) {
        printf("%s %s %s\n",workers[i].zip, workers[i].first, workers[i].last);
    }
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

lily

Re: char型の5桁の数字をソートする方法

#3

投稿記事 by lily » 6年前

コード:

void sortzip(Employees workers[], int size){
    Employees t;
    int i, j;
    
    for (i=0;i<size;i++) {
        for (j=i;j<size;j++) {
            if (strcmp(workers[i].zip, workers[j].zip)) {
                strcpy(t.zip, workers[i].zip);
                strcpy(workers[i].zip, workers[j].zip);
                strcpy(workers[j].zip,t.zip);
            }
        }
    }
    printf("\nk)\n");
    for (i = 0; i <size; i++) {
        printf("%s %s %s\n",workers[i].zip, workers[i].first, workers[i].last);
    }
なるほど、ありがとうございます!
しかしboxさんのプログラムを参考にこう書いてみたのですが、やはりソート順がめちゃくちゃでした。
どこがおかしいか分かりますでしょうか?

アバター
asd
記事: 319
登録日時: 13年前

Re: char型の5桁の数字をソートする方法

#4

投稿記事 by asd » 6年前

横から失礼します。

5桁の数字の大小を比較しているstrcmp関数ですが、
双方が一致する場合には0、1番目の引数の方が大きい場合には正の数、2番目の引数の方が大きい場合には負の数がそれぞれ返されます。
lily さんが書きました:

コード:

            if (strcmp(workers[i].zip, workers[j].zip)) {
上記のif文ですと非0の場合には真になってしまうため、1番目、2番目のいずれかが大きければ入れ替え処理が発生してしまいます。
昇順に並べ替えたいのであれば1番目の引数の方が大きい場合にのみ入れ替えをすればよいので、
strcmp関数の戻り値が正の数の時のみ入れ替えを実行するような条件に変えればよいのではないでしょうか?
Advanced Supporting Developer
無理やりこじつけ(ぉ

lily

Re: char型の5桁の数字をソートする方法

#5

投稿記事 by lily » 6年前

やっと出来ました・・
asdさん、本当にありがとうございます。自分では気づくことが出来なかったです。

boxさん、答えになるプログラムを書いていただき本当にありがとうございました。
また一つ勉強になりました。

かずま

Re: char型の5桁の数字をソートする方法

#6

投稿記事 by かずま » 6年前

lily さんが書きました:やっと出来ました・・
出来たプログラムをぜひ貼り付けてください。
lily さんが書きました: boxさん、答えになるプログラムを書いていただき本当にありがとうございました。
box さん。なぜ、挿入ソートを選択ソートに
変更したのか教えていただけませんか?

元のプログラムのソートには何も問題はありません。
問題点を整理すると、次の 2点でした。
・文字列 zip の比較を strcmp ではなく、< 演算子で行っていた。
・配列の要素全体を交換せず、メンバの zip の先頭文字だけを交換していた。

表示は、ソートの中で行わず、呼び出し元で行うほうが良いでしょう。

コード:

#include <stdio.h>
 
#if 1
typedef struct {
    char *zip, *first, *last;
} Employees;
#else
typedef struct {
    char zip[6], first[12], last[12];
} Employees;
#endif

Employees workers[] = {
    { "31415", "George", "Washington" },
    { "14142", "Abraham", "Lincoln" },
    { "27182", "William", "Clinton" },
    { "22360", "Barack", "Obama" },
    { "16180", "Donald", "Trump" },
};

void sortzip(Employees workers[], int size)
{
    int i, j;
    for (i = 1; i < size; i++) {
        Employees t = workers[i];
        for (j = i-1; j >= 0 && strcmp(t.zip, workers[j].zip) < 0; j--)
            workers[j+1] = workers[j];
        workers[j+1] = t;
    }
}

int main(void)
{
    int i, n = sizeof(workers) / sizeof(workers[0]);
    sortzip(workers, n);
    for (i = 0; i < n; i++)
        printf("%s %s %s\n", workers[i].zip, workers[i].first, workers[i].last);
}
#if 0 を #if 1 に変更することもできますが、
配列の要素のサイズが大きくなって効率が少し下がります。

かずま

Re: char型の5桁の数字をソートする方法

#7

投稿記事 by かずま » 6年前

strcmp を使うので、#include <string.h> を追加したほうが良いでしょう。

C は C++ と違って、宣言の無い関数は int を返すものとして、
暗黙の宣言が仮定されるので、なくてもエラーにはなりません。

かずま

Re: char型の5桁の数字をソートする方法

#8

投稿記事 by かずま » 6年前

かずま さんが書きました: #if 0 を #if 1 に変更することもできますが、
すみません。次のように訂正します。

#if 1を #if 0 に変更することもできますが、

lily

Re: char型の5桁の数字をソートする方法

#9

投稿記事 by lily » 6年前

コード:


void sortzip(Employees workers[], int size){
    Employees t;
    int i, j;
    
    for (i=0;i<size-1;i++) {
        for (j=i+1;j<size;j++) {
            if ((strcmp(workers[i].zip, workers[j].zip)>0)) {
                strcpy(t.zip, workers[i].zip);
                strcpy(workers[i].zip, workers[j].zip);
                strcpy(workers[j].zip,t.zip);
            }
        }
    }
    printf("\nk)\n");
  
    for (i = 0; i <size; i++) {
        printf("%s %s %s\n",workers[i].zip, workers[i].first, workers[i].last);
    }
}
かずまさん、アドバイスありがとうございます。
一応、これでzipコードを昇順にソートした上で姓名も出力出来ました。
色々な話しが聞けて勉強になります。

かずま

Re: char型の5桁の数字をソートする方法

#10

投稿記事 by かずま » 6年前

lily さんが書きました: 一応、これでzipコードを昇順にソートした上で姓名も出力出来ました。
どんなデータでテストしましたか?
main もデータも書いてください。

コード:

#include <stdio.h>
#include <string.h>
 
typedef struct {
    char zip[6], first[12], last[12];
} Employees;
 
Employees workers[] = {
    { "31415", "George", "Washington" },
    { "14142", "Abraham", "Lincoln" },
    { "27182", "William", "Clinton" },
    { "22360", "Barack", "Obama" },
    { "16180", "Donald", "Trump" },
};
 
void sortzip(Employees workers[], int size){
    Employees t;
    int i, j;
    
    for (i=0;i<size-1;i++) {
        for (j=i+1;j<size;j++) {
            if ((strcmp(workers[i].zip, workers[j].zip)>0)) {
                strcpy(t.zip, workers[i].zip);
                strcpy(workers[i].zip, workers[j].zip);
                strcpy(workers[j].zip,t.zip);
            }
        }
    }
    printf("\nk)\n");
  
    for (i = 0; i <size; i++) {
        printf("%s %s %s\n",workers[i].zip, workers[i].first, workers[i].last);
    }
}
 
int main(void)
{
    int n = sizeof(workers) / sizeof(workers[0]);
    sortzip(workers, n);
}
実行結果

コード:


k)
14142 George Washington
16180 Abraham Lincoln
22360 William Clinton
27182 Barack Obama
31415 Donald Trump
zip だけがソートされて、名前は元のままです。

lily

Re: char型の5桁の数字をソートする方法

#11

投稿記事 by lily » 6年前

今確認したら確かにソートされたのはzipコードだけでした・・
また皆さんのアドバイスを元に考え直します。

返信

“C言語何でも質問掲示板” へ戻る