バケットソート
バケットソート
かなり初心者です。
バケットソートのプログラムを作っていてわからなくなったので質問します。
.txtファイルに1000以下のid(数字)が6つ書いてあって
ex)
12
350
159
...
この.txtファイルを読み込んで、バケットソートで昇順に並べ替えたいのですが、以下のコードのコメントの上の行が通りません
最初の void bucket_sort(A* as[], int n) ここは変えずに結果を出したいのです(学校の課題なので)がどうすればよいでしょうか?
コンパイルしてみると、 配列の添字が整数型ではありません と言われます。
void bucket_sort(A* as[], int n)
{
int i;
int j = 0;
A* buckets[1000] = {};
for(i = 0; i< 1000; i++){
buckets = 0;
}
for(i =0; i < n; i++) {
buckets[as] = as;
/*
asは.txtファイルのid それを配列buckets[]のid番目にいれたい
*/
}
for(i = 0; i<1000; i++){
if(0 < buckets){
as[j++] = buckets;
}
}
return;
}
バケットソートのプログラムを作っていてわからなくなったので質問します。
.txtファイルに1000以下のid(数字)が6つ書いてあって
ex)
12
350
159
...
この.txtファイルを読み込んで、バケットソートで昇順に並べ替えたいのですが、以下のコードのコメントの上の行が通りません
最初の void bucket_sort(A* as[], int n) ここは変えずに結果を出したいのです(学校の課題なので)がどうすればよいでしょうか?
コンパイルしてみると、 配列の添字が整数型ではありません と言われます。
void bucket_sort(A* as[], int n)
{
int i;
int j = 0;
A* buckets[1000] = {};
for(i = 0; i< 1000; i++){
buckets = 0;
}
for(i =0; i < n; i++) {
buckets[as] = as;
/*
asは.txtファイルのid それを配列buckets[]のid番目にいれたい
*/
}
for(i = 0; i<1000; i++){
if(0 < buckets){
as[j++] = buckets;
}
}
return;
}
Re: バケットソート
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define name_size 40
#define students_size 10
typedef struct
{
int id;
char name[name_size];
}A;
コードの最初はこんな感じです。
#include<stdlib.h>
#include<string.h>
#define name_size 40
#define students_size 10
typedef struct
{
int id;
char name[name_size];
}A;
コードの最初はこんな感じです。
Re: バケットソート
asは整数じゃないよってのはわかりますが、全体像が見えませんね。
構造体の説明をするか、プログラムの全部を載せるか、情報が不足してます。
初心者とは言っても、構造体やファイル入力まですでに習っているのですし、もう少し詳しく情報を伝えてください。
構造体の説明をするか、プログラムの全部を載せるか、情報が不足してます。
初心者とは言っても、構造体やファイル入力まですでに習っているのですし、もう少し詳しく情報を伝えてください。
non
Re: バケットソート
プログラム全部のせます
いままでのプログラムの A と as は
A → Student
as → students
と考えてください。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define name_size 40
#define students_size 10
typedef struct
{
int id;
char name[name_size];
}Student;
void initialize_student(Student* student, int id,char* name);
int read_students(char* filename, Student* student[]);
void bucket_sort(Student* students[], int n);
void print_names(Student* students[], int n);
int main(void)
{
Student* student[40];
int i;
int students_count; /*ファイルから読み込んだ学生の人数*/
char filename[] = "student.txt";
students_count = read_students(filename,student);
bucket_sort(student, students_count);
print_names(student, students_count);
return 0;
}
void bucket_sort(Student* students[], int n)
{
int i;
int j = 0;
Student* buckets[1000] = {};
for(i = 0; i< 1000; i++){
buckets = 0;
}
for(i =0; i < n; i++) {
buckets[students] = students;
/*
studentsは.txtファイルのid それを配列bucket[]のid番目にいれたい
*/
}
for(i = 0; i<1000; i++){
if(0 < buckets){
students[j++] = buckets;
}
}
return;
}
void initialize_student(Student* student, int id, char* name)
{
student->id = id;
strcpy(student->name, name);
return;
}
int read_students(char* filename, Student* student[])
{
FILE* file;
int read_result;
int count = 0;
int id,result;
char name[name_size];
file = fopen(filename,"r");
if(file == NULL){
printf("File not exists\n");
return 1;
}
do{
result = fscanf(file,"%d %s",&id, name);
if(result == 2){
student[count] = calloc(sizeof(Student),1);
if(student[count] == NULL) exit(EXIT_FAILURE);
initialize_student(student[count],id,name);
count++;
}
} while (result != EOF);
fclose(file);
return count;
}
void print_names(Student* students[],int n)
{
int i;
for(i = 0; i < n; i++){
printf("%s\n",students->name);
}
return;
}
いままでのプログラムの A と as は
A → Student
as → students
と考えてください。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define name_size 40
#define students_size 10
typedef struct
{
int id;
char name[name_size];
}Student;
void initialize_student(Student* student, int id,char* name);
int read_students(char* filename, Student* student[]);
void bucket_sort(Student* students[], int n);
void print_names(Student* students[], int n);
int main(void)
{
Student* student[40];
int i;
int students_count; /*ファイルから読み込んだ学生の人数*/
char filename[] = "student.txt";
students_count = read_students(filename,student);
bucket_sort(student, students_count);
print_names(student, students_count);
return 0;
}
void bucket_sort(Student* students[], int n)
{
int i;
int j = 0;
Student* buckets[1000] = {};
for(i = 0; i< 1000; i++){
buckets = 0;
}
for(i =0; i < n; i++) {
buckets[students] = students;
/*
studentsは.txtファイルのid それを配列bucket[]のid番目にいれたい
*/
}
for(i = 0; i<1000; i++){
if(0 < buckets){
students[j++] = buckets;
}
}
return;
}
void initialize_student(Student* student, int id, char* name)
{
student->id = id;
strcpy(student->name, name);
return;
}
int read_students(char* filename, Student* student[])
{
FILE* file;
int read_result;
int count = 0;
int id,result;
char name[name_size];
file = fopen(filename,"r");
if(file == NULL){
printf("File not exists\n");
return 1;
}
do{
result = fscanf(file,"%d %s",&id, name);
if(result == 2){
student[count] = calloc(sizeof(Student),1);
if(student[count] == NULL) exit(EXIT_FAILURE);
initialize_student(student[count],id,name);
count++;
}
} while (result != EOF);
fclose(file);
return count;
}
void print_names(Student* students[],int n)
{
int i;
for(i = 0; i < n; i++){
printf("%s\n",students->name);
}
return;
}
Re: バケットソート
同じidのものをbuckets入れてしまえば、同じidがあると、nameが上書きされてしまいますが、同一のidはないのでしょうか?
また
Student* buckets[1000] = {};
は、どういう意味で使ってますか?
また
Student* buckets[1000] = {};
は、どういう意味で使ってますか?
non
Re: バケットソート
同一のIDはないという前提でお願いします。
バケットソートのところだけ書く課題で
Student* buckets[1000] = {};
のところは、もともとかいてあったものなんですけど
おそらく、配列buckets[]とは
要素が1000個入る箱を用意したってことだと思います。
バケットソートのところだけ書く課題で
Student* buckets[1000] = {};
のところは、もともとかいてあったものなんですけど
おそらく、配列buckets[]とは
要素が1000個入る箱を用意したってことだと思います。
Re: バケットソート
すると、ポインタの配列を使えってことなのですね。うらはんちょう さんが書きました:同一のIDはないという前提でお願いします。
バケットソートのところだけ書く課題で
Student* buckets[1000] = {};
のところは、もともとかいてあったものなんですけど
Student backets[1000];
ではないのは間違いないですね。
ポインタの配列を1000個用意しているのですよ。うらはんちょう さんが書きました: おそらく、配列buckets[]とは
要素が1000個入る箱を用意したってことだと思います。
実際のバケツは別に用意しなくてはいけません。
Student backets[1000];
の方が簡単なんですねどね。
non
Re: バケットソート
>ポインタの配列を1000個用意しているのですよ。
>実際のバケツは別に用意しなくてはいけません。
>Student backets[1000];
>の方が簡単なんですねどね。
んー、なるほど。
Student* buckets[1000] = {};
は、ポインタの配列で
もうひとつ、配列を用意するですか。。。
わかったような、わからないような、なんですが。
buckets[students] = students;
この、studentsの代入は Student* buckets[1000] = {};
のポインタの配列に代入していいんですか?
違うなら、どのようにすればいいのでしょうか?
studentsをint型にすれば解決するものと思ってたのですが。
>実際のバケツは別に用意しなくてはいけません。
>Student backets[1000];
>の方が簡単なんですねどね。
んー、なるほど。
Student* buckets[1000] = {};
は、ポインタの配列で
もうひとつ、配列を用意するですか。。。
わかったような、わからないような、なんですが。
buckets[students] = students;
この、studentsの代入は Student* buckets[1000] = {};
のポインタの配列に代入していいんですか?
違うなら、どのようにすればいいのでしょうか?
studentsをint型にすれば解決するものと思ってたのですが。
Re: バケットソート
うらはんちょう さんが書きました:>ポインタの配列を1000個用意しているのですよ。
>実際のバケツは別に用意しなくてはいけません。
>Student backets[1000];
>の方が簡単なんですねどね。
んー、なるほど。
Student* buckets[1000] = {};
は、ポインタの配列で
もうひとつ、配列を用意するですか。。。
この、studentsの代入は Student* buckets[1000] = {};
のポインタの配列に代入していいんですか?
いえ、既に使っているcallocなどを使って動的にメモリを確保します。
それより、私は、ポインタ配列にするのは先生の指示かと尋ねたのです。
non
Re: バケットソート
そうですか。それなら、最初から1000個分の領域を確保する方法と、idがあるところの領域だけを確保する方法がうらはんちょう さんが書きました:はい、指示です。
あります。どちらにしますか。
また、
Student* buckets[1000] = {};
は
Student* buckets[1000] ;
ではないかと思うのですが。 ={}; を つけるのも先生の指示ですか?
どっちにしても、
for(i = 0; i< 1000; i++){
buckets = 0;
}
はおかしいです。
buckets はポインタです。
これは、うらはんちょうが考えた部分ですよね。
何をしたかったのですか?
non
Re: バケットソート
>そうですか。それなら、最初から1000個分の領域を確保する方法と、idがあるところの領域だけを確保する方>>法が
>あります。どちらにしますか。
最初から1000個分の領域を確保する方法でおねがいします。
>また、
>Student* buckets[1000] = {};
>は
>Student* buckets[1000] ;
>ではないかと思うのですが。 ={}; を つけるのも先生の指示ですか?
void bucket_sort(Student* students[], int n)
{
int i;
int j = 0;
Student* buckets[1000] = {};
void bucket_sortのここまでは
元から指示されていました。
よって={}; を つけるのも指示です。
>どっちにしても、
>for(i = 0; i< 1000; i++){
>buckets = 0;
>}
>はおかしいです。
>buckets はポインタです。
>これは、うらはんちょうが考えた部分ですよね。
>何をしたかったのですか?
確かにおかしいですね
ここは、省いてもらっていいです。
>あります。どちらにしますか。
最初から1000個分の領域を確保する方法でおねがいします。
>また、
>Student* buckets[1000] = {};
>は
>Student* buckets[1000] ;
>ではないかと思うのですが。 ={}; を つけるのも先生の指示ですか?
void bucket_sort(Student* students[], int n)
{
int i;
int j = 0;
Student* buckets[1000] = {};
void bucket_sortのここまでは
元から指示されていました。
よって={}; を つけるのも指示です。
>どっちにしても、
>for(i = 0; i< 1000; i++){
>buckets = 0;
>}
>はおかしいです。
>buckets はポインタです。
>これは、うらはんちょうが考えた部分ですよね。
>何をしたかったのですか?
確かにおかしいですね
ここは、省いてもらっていいです。
Re: バケットソート
>よって={}; を つけるのも指示です。
そうなんですか。初期値を入れないなら意味がないと思うのですが・・・・。
私が、勉強不足で意味が分からないだけなのでしょう。
>最初から1000個分の領域を確保する方法でおねがいします。
なら、ポインタでない方が簡単なのですが、
先生としては、最終的な形として、リスト構造にしたいのかもしれませんね。
では、
for(i = 0; i< 1000; i++){
buckets = 0;
}
の部分で、callocしてメモリを確保してください。
また
>buckets[students] = students;
は
buckets[students->id] = *students;
になりますが、意味が分かりますか?
そうなんですか。初期値を入れないなら意味がないと思うのですが・・・・。
私が、勉強不足で意味が分からないだけなのでしょう。
>最初から1000個分の領域を確保する方法でおねがいします。
なら、ポインタでない方が簡単なのですが、
先生としては、最終的な形として、リスト構造にしたいのかもしれませんね。
では、
for(i = 0; i< 1000; i++){
buckets = 0;
}
の部分で、callocしてメモリを確保してください。
また
>buckets[students] = students;
は
buckets[students->id] = *students;
になりますが、意味が分かりますか?
non
Re: バケットソート
>では、
>for(i = 0; i< 1000; i++){
> buckets = 0;
> }
>の部分で、callocしてメモリを確保してください。
callocと言うのは、はじめて聞いたのですが、ググってみて大体意味はわかりました。
idがあるところの領域だけを確保する方法と言うのを使うと
callocというのは使わなくていいのですか?
どちらにしても使うなら、どう書けば良いかご教授おねがいします。
>また
>buckets[students] = students;
>は
>buckets[students->id] = *students;
>になりますが、意味が分かりますか?
アロー演算子ですね、
構造体のメンバをポインタが指すとき使うやつ
でも、要はbuckets[]のなかのid番目にstudentsが入ったってことですか?
>for(i = 0; i< 1000; i++){
> buckets = 0;
> }
>の部分で、callocしてメモリを確保してください。
callocと言うのは、はじめて聞いたのですが、ググってみて大体意味はわかりました。
idがあるところの領域だけを確保する方法と言うのを使うと
callocというのは使わなくていいのですか?
どちらにしても使うなら、どう書けば良いかご教授おねがいします。
>また
>buckets[students] = students;
>は
>buckets[students->id] = *students;
>になりますが、意味が分かりますか?
アロー演算子ですね、
構造体のメンバをポインタが指すとき使うやつ
でも、要はbuckets[]のなかのid番目にstudentsが入ったってことですか?
Re: バケットソート
すでに、あなたが使っているから、callocを使うように指示したのですよ。うらはんちょう さんが書きました: callocと言うのは、はじめて聞いたのですが、ググってみて大体意味はわかりました。
idがあるところの領域だけを確保する方法と言うのを使うと
callocというのは使わなくていいのですか?
どちらにしても使うなら、どう書けば良いかご教授おねがいします。
何をわけのかからないことを・・・
non
Re: バケットソート
>すでに、あなたが使っているから、callocを使うように指示したのですよ。
>何をわけのかからないことを・・・
つかってるところありますね
でも、そこは課題を渡されたときから書いてあったので
私が使えていたわけではないです。
do{
result = fscanf(file,"%d %s",&id, name);
if(result == 2){
student[count] = calloc(sizeof(Student),1);
if(student[count] == NULL) exit(EXIT_FAILURE);
initialize_student(student[count],id,name);
count++;
}
} while (result != EOF);
ここですね
こんな感じで書けばいいと
>何をわけのかからないことを・・・
つかってるところありますね
でも、そこは課題を渡されたときから書いてあったので
私が使えていたわけではないです。
do{
result = fscanf(file,"%d %s",&id, name);
if(result == 2){
student[count] = calloc(sizeof(Student),1);
if(student[count] == NULL) exit(EXIT_FAILURE);
initialize_student(student[count],id,name);
count++;
}
} while (result != EOF);
ここですね
こんな感じで書けばいいと
Re: バケットソート
配列を 1000個用意しているのではありません。non さんが書きました: ポインタの配列を1000個用意しているのですよ。
実際のバケツは別に用意しなくてはいけません。
Student backets[1000];
の方が簡単なんですねどね。
要素がポインタで、それが 1000個ある配列を 1個用意しています。
バケツはポインタだけで十分です。別に用意する必要はありません。
Student *backets[1000]; の方が簡単です。
データの領域は、読み込み時にすでに行われているので、もうこれ以上non さんが書きました: そうですか。それなら、最初から1000個分の領域を確保する方法と、idがあるところの領域だけを確保する方法が
あります。どちらにしますか。
確保する必要はありません。
おそらく、授業では gcc を使っているんだと思います。non さんが書きました: また、
Student* buckets[1000] = {};
は
Student* buckets[1000] ;
ではないかと思うのですが。 ={}; を つけるのも先生の指示ですか?
確かに、標準の C では、値が一つもない初期化子は許されませんが、
gcc では許されています。
Student* buckets[1000] = { 0 };
または、
Student* buckets[1000] = { NULL };
と書くほうがよいと思います。
値を一つ書いておけば、残りの 999個もすべて NULL で初期化されます。
宣言時に初期化していますから、次の for 文で 0 を代入する必要はありません。
元のプログラムは、
buckets[students] = students; を
buckets[students->id] = students; にすることと、
if(0 < buckets){ を
if (buckets != NULL) { にすることだけで正しいプログラムになります。
もっとも、read_students() が読み込んだデータの個数を返すのに、
フィルのオープンに失敗したときに 1 を返すのは変ですが。
うらはんちょう さんが書きました: .txtファイルに1000以下のid(数字)が6つ書いてあって
ex)
12
350
159
...
12 名前1
350 名前2
159 名前3
...
ですよね。
Re: バケットソート
かずまさんへ、
私がやりかたを勘違いしていました。ポインタを使って並び替えを変えるだけでよかったのですね。
別の領域をバケツで用意し、そちらに値を転送した後、studentに戻すのかと思ってました。
うらはんちょう さんへ
勘違いして、面倒な方法をお伝えしてしまいました。失礼しました。
私がやりかたを勘違いしていました。ポインタを使って並び替えを変えるだけでよかったのですね。
別の領域をバケツで用意し、そちらに値を転送した後、studentに戻すのかと思ってました。
うらはんちょう さんへ
勘違いして、面倒な方法をお伝えしてしまいました。失礼しました。
non
Re: バケットソート
この部分は、頭の中では、間違っていたわけではありませんが、表現方法がよくなかったですね。かずま さんが書きました:配列を 1000個用意しているのではありません。non さんが書きました: ポインタの配列を1000個用意しているのですよ。
要素がポインタで、それが 1000個ある配列を 1個用意しています。
誤解を生みました。
「要素がポインタで、それが 1000個ある配列を 用意しています。」
「1個」は書かない方が良いかと。
non
Re: バケットソート
>おそらく、授業では gcc を使っているんだと思います。
そうです、gccをつかっています。
>確かに、標準の C では、値が一つもない初期化子は許されませんが、
>gcc では許されています。
Cでも使っているものによって変わってくるんですね。今度質問する機会があったらgccを使っていると書きたいとおもいます。
>Student* buckets[1000] = { 0 };
>または、
>Student* buckets[1000] = { NULL };
>と書くほうがよいと思います。
>値を一つ書いておけば、残りの 999個もすべて NULL で初期化されます。
>宣言時に初期化していますから、次の for 文で 0 を代入する必要はありません。
Student* buckets[1000] = { 0 };
のとことは、={}でも、ちゃんとした答えがでてきました。
={NULL}で全部初期化できるんですね、覚えておきます。
>元のプログラムは、
>buckets[students] = students; を
>buckets[students->id] = students; にすることと、
>if(0 < buckets){ を
>if (buckets != NULL) { にすることだけで正しいプログラムになります。
おっしゃるとおり、正しいプログラムになりました。ありがとうございます。
if(0 < buckets){
はなぜいけないのでしょうか?
そうです、gccをつかっています。
>確かに、標準の C では、値が一つもない初期化子は許されませんが、
>gcc では許されています。
Cでも使っているものによって変わってくるんですね。今度質問する機会があったらgccを使っていると書きたいとおもいます。
>Student* buckets[1000] = { 0 };
>または、
>Student* buckets[1000] = { NULL };
>と書くほうがよいと思います。
>値を一つ書いておけば、残りの 999個もすべて NULL で初期化されます。
>宣言時に初期化していますから、次の for 文で 0 を代入する必要はありません。
Student* buckets[1000] = { 0 };
のとことは、={}でも、ちゃんとした答えがでてきました。
={NULL}で全部初期化できるんですね、覚えておきます。
>元のプログラムは、
>buckets[students] = students; を
>buckets[students->id] = students; にすることと、
>if(0 < buckets){ を
>if (buckets != NULL) { にすることだけで正しいプログラムになります。
おっしゃるとおり、正しいプログラムになりました。ありがとうございます。
if(0 < buckets){
はなぜいけないのでしょうか?
Re: バケットソート
ハッカーさん、かずまさん
貴重なお時間を使って、質問に答えていただきありがとうございました。
色々勉強になりました。
もっと、Cを勉強しようとおもいます。
もし、また質問に来たときはご指導ご鞭撻のほどをよろしくお願いします。
貴重なお時間を使って、質問に答えていただきありがとうございました。
色々勉強になりました。
もっと、Cを勉強しようとおもいます。
もし、また質問に来たときはご指導ご鞭撻のほどをよろしくお願いします。
Re: バケットソート
うらはんちょう さんが書きました: if(0 < buckets){
はなぜいけないのでしょうか?
bucketsはポインタですからアドレスが入ります。
確かに、NULLは0ですから、動くとは思いますが、0番地を指しているという意味ではなく
構造体を指していないよという意味でNULLにします。
non