ページ 1 / 1
char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 09:31
by lily
コード:
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コードの昇順で姓名を一緒に出力するプログラムがどうしても思いつきません。
説明が下手で申し訳ないのですが誰かご教授よろしくお願いします。
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 09:54
by box
こんなのじゃダメですか?
コード:
#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);
}
}
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 10:48
by lily
コード:
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さんのプログラムを参考にこう書いてみたのですが、やはりソート順がめちゃくちゃでした。
どこがおかしいか分かりますでしょうか?
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 11:05
by asd
横から失礼します。
5桁の数字の大小を比較しているstrcmp関数ですが、
双方が一致する場合には0、1番目の引数の方が大きい場合には正の数、2番目の引数の方が大きい場合には負の数がそれぞれ返されます。
lily さんが書きました:コード:
if (strcmp(workers[i].zip, workers[j].zip)) {
上記のif文ですと非0の場合には真になってしまうため、1番目、2番目のいずれかが大きければ入れ替え処理が発生してしまいます。
昇順に並べ替えたいのであれば1番目の引数の方が大きい場合にのみ入れ替えをすればよいので、
strcmp関数の戻り値が正の数の時のみ入れ替えを実行するような条件に変えればよいのではないでしょうか?
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 11:16
by lily
やっと出来ました・・
asdさん、本当にありがとうございます。自分では気づくことが出来なかったです。
boxさん、答えになるプログラムを書いていただき本当にありがとうございました。
また一つ勉強になりました。
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 13:13
by かずま
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桁の数字をソートする方法
Posted: 2018年1月29日(月) 13:24
by かずま
strcmp を使うので、#include <string.h> を追加したほうが良いでしょう。
C は C++ と違って、宣言の無い関数は int を返すものとして、
暗黙の宣言が仮定されるので、なくてもエラーにはなりません。
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 13:46
by かずま
かずま さんが書きました:
#if 0 を #if 1 に変更することもできますが、
すみません。次のように訂正します。
#if 1を #if 0 に変更することもできますが、
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 16:42
by lily
コード:
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桁の数字をソートする方法
Posted: 2018年1月29日(月) 16:57
by かずま
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 だけがソートされて、名前は元のままです。
Re: char型の5桁の数字をソートする方法
Posted: 2018年1月29日(月) 17:46
by lily
今確認したら確かにソートされたのはzipコードだけでした・・
また皆さんのアドバイスを元に考え直します。