• ベストアンサー

シェルソート(Cプログラミング)

シェル・ソート 基本挿入法により、データを昇順にソートする。 というプログラムを実行したいと思ったのですが、エラーがでてしまいコンパイルできません。 書いたプログラムは以下の通りです。 #include<stdio.h> #include<math.h> #define N 100 int main (void) { int a[N],i,j,t; for (i=0;i<N;i++) a[i]=rand(); for (i=1;i<N;i++){ for (j=j-1;j>=0;j--){ if (a[j]>a[j+1]){ t=a[j]; a[j]=a[j+1]; a[j+1]=t; } else break; } } for (i=0;i<N;i++) printf("%8d",a[i]); } エラーメッセージは以下のようにでました。 警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main ) 警告 W8070 sample.c 22: 関数は値を返すべき(関数 main ) どうすれば出来るのでしょうか、お答えよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.2

エラーではなく警告ですので、コンパイルできています。 ただ、 > for (j=j-1;j>=0;j--){ この行に誤りがあるため、実行時に落ちます。 さらに、乱数の初期化を行なっていないため、 正しく実行できたとしても毎回同じ結果を得ます。 それでもよければかまわないのですが、srand()を使って 乱数を初期化した方が毎回違った結果を得ることができて おもしろいでしょう。 ちなみに、2つ目の警告が出ないようにするには、 main()の最後に return 0; を加えてください。

その他の回答 (8)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.9

>for ((j=N-1)--;j>=0;j--){ >でいくはずですが、コンパイラの違いでしょうか・・・? j = N-1 という代入式に対してデクリメント演算子を適用しようとしていますが、 通常は代入式は lvalue を持たないのでデクリメント演算子を適用できません。 できるコンパイラがあるならそれが拡張されているかしているのでしょう。 #C++でのは扱いは覚えてません

noname#50176
noname#50176
回答No.8

>エラー E2277 sample.c 14: 左辺値が必要(関数 main ) >*** 1 errors in Compile *** >と出てしまいました(´;ェ;`) for ((j=N-1)--;j>=0;j--){ でいくはずですが、コンパイラの違いでしょうか・・・? for (j=N-2;j>=0;j--){ としてみてください。

noname#50176
noname#50176
回答No.7

>アドバイス通りに書き換えましたら、実行することができました。 >実行結果が以下のようになってしまったのですが、これ間違ってま >すよね?(略) 大変、失礼いたしました!(謝) for (j=j-1;j>=0;j--){ は for ((j=N-1)--;j>=0;j--){ です、すみません・・・。 >ダメです。 >main関数の戻り値は、C言語の規格でint型であると決まっています。 もちろん、既知の上です。 ただ、“void でも一応動作はする”と言うことで 「この書き方も出来ます」と言うニュアンスですので void にしてください、ということではありません。 でもご指摘ありがとうございました!

doratao
質問者

補足

for ((j=N-1)--;j>=0;j--){ に書き直してコンパイルしてみたら、 警告 W8065 sample.c 11: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main ) エラー E2277 sample.c 14: 左辺値が必要(関数 main ) *** 1 errors in Compile *** と出てしまいました(´;ェ;`) 何回もすみません。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.6

> 「It(訳注:main関数のことです) shall be defined with a return type of int (以下略)」 shall は「~するべし」という意味ですので、 「int以外の型にしたとき、何が起きても知らないよ」という ニュアンスを含んでいると思われます。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.5

> main関数の戻り値は、C言語の規格でint型であると決まっています。 「根拠を示せ」と言われる前に、提示しておきます。 ISOの規格番号「ISO/IEC 9899:1999」に、 「It(訳注:main関数のことです) shall be defined with a return type of int (以下略)」 という記述があります。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.4

> void main (void) > でも良いですね。 ダメです。 main関数の戻り値は、C言語の規格でint型であると決まっています。

noname#50176
noname#50176
回答No.3

int main (void) は引数なく戻り値の必要がないので、 void main (void) でも良いですね。 あと、 for (j=j-1;j>=0;j--){ は for (j=N-1;j>=0;j--){ ですね。 あと再帰を使ったシェルソートを作ってみたので 参考にしてみてください。 #include <stdio.h> int _SonyuSort(int S[],int t,int n,int d,int max,unsigned int *k)// ここでの n は個数 { int r,i; if (n<t) return t; r=_SonyuSort(S,t,n-d,d,max,k); if (n>max) return n; if (S[r-1]>S[n-1]) { S[r-1]-=S[n-1]=(S[r-1]=S[r-1]+S[n-1])-S[n-1],(*k)++; printf("%d回目:",*k); for (i=0;i<max;i++) printf("%d ",S[i]);printf("\r\n"); _SonyuSort(S,t,n,d,max,k); } else return n; } int ShellSort(int S[],int n,unsigned int *k) { int i,j; for (i=n>>1;i;i>>=1) //i&=(~((i=n>>1)&1)) では増えることに注意 { printf("グループ数:%d\r\n",i); for (j=1;j<=n;j++) _SonyuSort(S,j,n-(n%i)+j,i,n,k); } return 0; } int SonyuSort(int S[],int n,unsigned int *k) // ここでの n は個数-1 { int r; if (!n) return 0; if (S[(r=SonyuSort(S,n-1,k))]>S[n]) { S[r]-=S[n]=(S[r]+=S[n])-S[n],(*k)++; SonyuSort(S,n,k); } else return n; } int main(void) { int S[]={-5,-768,768,56,9,-98,45,7,509,8,-98,80,444,-1234,9800,9,-678}; unsigned int k=0; // k=挿入ソート回数 int i,n=sizeof(S)/sizeof(int); printf("整列前:"); for (i=0;i<n;i++) printf("%d ",S[i]);printf("\r\n\r\n"); ShellSort(S,n,&k); printf("\r\n整列後:"); for (i=0;i<n;i++) printf("%d ",S[i]);printf("\r\n\r\n"); printf("ソート回数:%d 回\r\n",k); return 0; }

doratao
質問者

補足

アドバイス通りに書き換えましたら、実行することができました。 実行結果が以下のようになってしまったのですが、これ間違ってますよね?(^^;) 130 10982 1090 11656 7117 17595 6415 22948 31126 9004 14558 3571 22879 18492 1360 5412 26721 22463 25047 27119 31441 7190 13985 31214 27509 30252 26571 14779 19816 21681 19651 17995 23593 3734 13310 3979 21995 15561 16092 18489 11288 28466 8664 5892 13863 22766 5364 17639 21151 20427 100 25795 8812 15108 12666 12347 19042 19774 9169 5589 26383 9666 10941 13390 7878 13565 1779 16190 32233 53 13429 2285 2422 8333 31937 11636 13268 6460 6458 6936 8160 24842 29142 29667 24115 15116 17418 1156 4279 15008 15859 19561 8297 3755 22981 21275 29040 28690 1401 18137

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.1

> 警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main ) rand関数はstdlib.hで定義されているかと思いますので、 #include <stdlib.h> をインクルードしてください。 お手元のリファレンスマニュアルなどでrand関数を確認してください。

関連するQ&A

  • javaのシェルソートについて質問です

    //Sample482 import java.util.Random; class Sample482{ static int shellSort1(int[] x){ int n = x.length; int cnt = 0; for(int h = n/2;h > 0;h /= 2){ for(int i = h;i < n;i++){ int tmp = x[i]; int j; for(j = i;j > h-1 && x[j-h] > tmp;j -= h){ cnt++; x[j] = x[j-h]; } x[j] = tmp; } } return cnt; } public static void main(String[] args){ Random rand = new Random(); int n = 20000; int[] x = new int[n]; for(int i = 0;i < n;i++){ x[i] = rand.nextInt(1000000); } int cnt = shellSort1(x); System.out.println("昇順にソートしました。"); for(int i = 0;i < n;i++){ System.out.println("x[" + i + "]=" + x[i]); } System.out.println("要素の移動回数" + cnt); } } //Sample483 import java.util.Random; class Sample483{ static int shellSort2(int[] x){ int n = x.length; int cnt = 0; int h; for(h = 1;h < n/9;h = 3*h+1); for(;h > 0;h /= 3){ for(int i = h;i < n;i++){ int j; int tmp = x[i]; for(j = i-h;j >= 0 && x[j] > tmp;j -= h){ x[j+h] = x[j]; cnt++; } x[j+h] = tmp; } } return cnt; } public static void main(String[] args){ Random rand = new Random(); int n = 20000; int[] x = new int[n]; for(int i = 0;i < n;i++){ x[i] = rand.nextInt(1000000); } int cnt = shellSort2(x); System.out.println("昇順にソートしました。"); for(int i = 0;i < n;i++){ System.out.println("x[" + i + "]=" + x[i]); } System.out.println("要素の移動回数:" + cnt); } } 上記のSample482とSample483はどちらもシェルソートを扱ったコードです。 参考書やネットの情報によると、後者のSmple483のシェルソートの方がより高速にソート することができるらしいのですが、実際に実行してみると、要素の移動回数は Sample482よりSample483の方が多くなります。 要素の移動回数が多いということは、それだけソートに時間がかかると私は思うのですが、 何故、後者のシェルソートの方が高速に動くといえるのでしょうか?

  • シェルソートのプログラムが分かりません

    教科書どおり下のようなプログラムを作ったのですが、ちゃんとソートされません。 打ち間違いなどを探しているのですが見つからないんです・・・ それと、プログラム11行目のj=j-hが何のためにあるのか分かりません。もしかしたら幼稚な質問かもしれませんがどうかよろしくお願いします。 #include<stdio.h> void shell(int n,int a[]) { int i,j,x,h; h=n/2; while(h<0) { for(i=h;i<=n;i++) { x=a[i]; for(j=i-h;j>=0;j=j-h) { if(a[j]>x) { a[j]=a[j+h]; a[j+h]=x; } } } h=h/2; } } main() { int a[]={30,20,60,29,10,90}; int n=6; int i; shell(n,a); for(i=0;i<n;i++) { printf("%4d",a[i]); } printf("\n"); }

  • C++ ソートのやり方

    僕が作ったプログラムで、これはバブルソートなのかわからないので教えてください。 また、ほかのソートの仕方も教えてください。 よろしくお願いします。 汎用関数を使っているのでわかりにくいかもしれないですがお願いします。 #include <iostream> using namespace std; template <class X>void Sort(X *data, int size) { X temp; for (int i = 0; i < size; i++){ for (int j = i + 1; j < size; j++){ if (data[i]>data[j]){ temp = data[i]; data[i] = data[j]; data[j] = temp; } } } } int main() { int i[10]{1, 4, 3, 5, 2, 10, 2, 7, 6, 8}; char c[10]{'c', 'b', 'z', 'a', 'x', 'y', 'j', 'n', 'm', 'r'}; Sort(c, 10); Sort(i, 10); for (int j = 0; j < 10; j++){ cout << i[j] << ' '; } cout << endl; for (int j = 0; j < 10; j++){ cout << c[j] << ' '; } cout << endl; getchar(); return 0; }

  • クイックソートについて

    下記のソースプログラムのquick_sort_coreの部分がわかりません。 わかる方助けてください。 あとこのソースを降順にした場合の変更点も教えていただけると助かります。 #include <stdio.h> /* printf()利用のため */ #include <stdlib.h> /* rand()利用のため */ #include <time.h> /* clock()利用のため */ #define N 10 /* 整列対象要素数 */ /** * 配列の中身を表示する関数 * @param a 表示する配列 * @param n 配列の要素数 */ void print_array(const int a[], int n) { int i; for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } /** * 整列されているかどうか確認する関数 * @param a 確認対象配列 * @param n 配列の要素数 */ void is_sorted(const int a[], int n) { int i; for (i = 0; i < n - 1; i++) { if (a[i] > a[i + 1]) { printf("昇順に整列されていません\n"); return; } } printf("昇順に整列されています\n"); } /** * クイックソートの本体 * @param a 整列対象配列 * @param l 対象の最初の要素番号 * @param r 対象の最後の要素番号 */ void quick_sort_core(int a[], int l, int r) { /* ここを実装する */ } /** * これまでの整列関数のインターフェースにあわせるクイックソート呼び出し関数 * @param a 整列対象配列 * @param n 配列の要素数 */ void quick_sort(int a[], int n) { quick_sort_core(a, 0, n - 1); } int main(void) { int i; int n = N; /* 整列対象要素数 */ int a[N]; clock_t start,end; /* 0からRAND_MAXの一様乱数をn個生成し、配列aに格納 */ for (i = 0; i < n; i++) { a[i] = rand(); /* 出力確認(print_array)するときは a[i]=rand()%100 としておくと見やすい */ } /* 昇順にソートされているか確認(デバッグ用) */ is_sorted(a, n); /* 配列の中身を確認(デバッグ用) */ print_array(a, n); /* 開始時刻の取得 */ start = clock(); /* クイックソート関数の呼び出し */ quick_sort(a, n); /* 終了時刻の取得 */ end = clock(); /* 配列の中身を確認(デバッグ用) */ print_array(a, n); /* 昇順にソートされているか確認(デバッグ用) */ is_sorted(a, n); /* 実行時間の表示 */ printf("%d 個の要素のクイックソートの実行に %f [秒]かかりました\n", n, (double)(end - start) / CLOCKS_PER_SEC); return 0; }

  • C言語プログラミングについて

    皆さんのお力をお貸しください 問題 1~20番のナンバーの車が200週の耐久レースをする。ENTERKEYを押すたびにコースを一周するものとし、一周するごとに20台のうち一台がランダムに選ばれ、選ばれた車は1~6のランダムに選ばれた数字の数だけ順位を上げるプログラムをかいてください。 ※ただしグローバル変数、ポインタは使わずif,for,while,配列のみで書くこと。 実行結果は #(選ばれた車のナンバー)   over(抜いた台数) 現在の周回数( ) 順位 1   (車のナンバー)     2   (車のナンバー)     3   (車のナンバー)        ・        ・          ・                    ()の中身はenterを押すたびに変化する となるようにしてください ポインタありのサンプルプログラムは組めたのですが、※の条件が付けられて、戸惑っています。 恥を忍んで皆さんにお願い申し上げます。 以下、サンプル(インデントの狂いやコメントに関してはご容赦ください) #include <stdio.h> #include <stdlib.h> #include <time.h> #define my_rand(n) (int)((n) * (rand() / (RAND_MAX + 1.0))) void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } void up_rank(int a[], int m, int n) { while(n --){ if(!m --) break; swap(&a[m], &a[m + 1]); } } void print(int car[], int n) { int i; int j = 0; for(i = 0; i < n; ++ i) { j++; printf("[%2d] %d\n",j, car[i]); } /*putchar('\n');*/ } int main(void) { int car[] = {95,43,86,8,52,28,64,58,76,70,4,34,63,92,35,33,56,80,54,74},i;               //各車のナンバー。皆さんは1~20でかまいません srand((unsigned)time(NULL)); printf("Start\n"); print(car, 20); system("pause"); system("cls"); for(i = 0; i < 201; ++ i) { int c, m = my_rand(20), n = my_rand(6) + 1; if(i<200) { printf("#%d, Overtake +%d\n",car[m] , n); printf("raps = %d\n",i+1); } else { printf("Finishing Positions\n"); } up_rank(car, m, n); print(car, 20); system("pause"); system("cls"); } return 0; }

  • クイックソート

    #include<stdio.h> #include<stdlib.h> #define MAX 10 int comp(const void *i,const void *j); int main(void) { int sort[MAX], i ; for(i=0 ; i<MAX ; i++){ sort[i] = rand(); } qsort(sort, MAX, sizeof(int), comp); for( i=0; i<MAX ; i++) printf("%d\n", sort[i]); return 0; } int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } これはクイックソートのプログラムなのですが、 int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } この部分がわかりません。ここでソートしているのですか?

  • クイックソート(C言語)

    こんにちは<_ _> クイックソートについての質問です。 左端を軸にクイックソートでデータを昇順にソートする プログラムを作ったのですがうまく動きません #include<stdio.h> void quick(int *,int,int); #define N 10 int main(void) { static int a[]={41,24,76,11,45,64,21,69,19,36}; int k,b=0; quick(a,0,N-1); for(k=0;k<N;k++) printf(" %d",a[k]); return 0; } void quick(int a[],int left,int right) { int s,t,i,j; t=right; i=left+1; j=a[left]; if(right>left){ while(1){ while(a[++i]>j); while(a[--t]<j && t>0); if(i>=t){ break; } s=a[i]; a[i]=a[t]; a[t]=s; } s=a[i]; a[i]=j; a[left]=s; quick(a,left,t-1); quick(a,t+1,right); } } 値の入れ替え、軸の入れ替えもしましたが結果として 「41 41 76 69 45 64 41 19 0 36」 このような結果で出力されてしまいます・・・ 時間に余裕のある方いましたらご指導をお願いします。 よろしくお願いします。<_ _>

  • レコード型データのソートについて

    (C言語) レコード型のソート(ポインタのソート)をしたいのですが コンパイルしようとするとstrcompでエラーが出てしまいます。 どこが違うのでしょうか教えてください<__> (ソートは名前だけです。 Ann 18 Candy 16   ・   ・    ・  見たいな感じです) #include<stdio.h> #include<string.h> #define N 10 int main(void) { static struct girl{ char *name; int age; }*t,*p[N],a[]={"Ann",18,"Rolla",19,"Nancy",16,"Eruza",17,"Juliet",18, "Machilda",20,"Emy",15,"Candy",16,"Ema",17,"Mari",18}; int i,j,n=10; for(i=0;i<10;i++){ p[i]=&a[i]; } for(i=0;i<n-1;i++){ for (j=i+1;j<n;j++){ if(-1==strcomp(a[j],a[i])){ t=p[j]; p[j]=p[i]; p[i]=t; } } } } Error : undefined reference to `strcomp' collect2: ld returned 1 exit status 当方プログラミング初心者です おねがいします><

  • クイックソートでの整列

    10個~20個程度の数列をキーボードから入力し、降順に整理し途中経過と整列後の状態を表示するプログラムを作りなさい。 このような課題が出ているのですが、よくわかりません。授業中に この2つのプログラムを応用すればできるといわれたプログラムがあるのですが、コンパイルするとエラーがたくさん出てきます。 ヒントを教えてください。 1.c #include <stdio.h> #include <stdlib.h> quick_sort(int a[], int l, int r); main(int argc, char *argv) { int i, x[100], n; n = atoi(argv[1]); for(i = 0;i< n;i++); scanf("%d", %x[i]); quick_sort(x, n); printf("sort\n"); for(i = 0;i<n; i++){ printf("%d\n", x[i]); } return ; } 2.c quick_sort(int a[], int l, int r) { int v,i,j,t; if(r>1) { v=a[r]; i=l-1; j=r; while(1) { while(a[++i]<v); while(a[--j]>v) if(j==l)break; if(i>=j)break; t=a[i];a[i]=a[j];a[j]=t; } a[r]=a[i];a[i]=v; quick_sort(a,l,i-1); quick_sort(a,i+1,r); } }

  • 単純挿入法を入れたいんですけど・・・

    #include <iostream> #include <iomanip> #include <cstdlib> //rand関数を使うので using namespace std; void Sort(int *s, int n); //プロトタイプ int main() { const int N = 100; int a[N], i, r, temp; for(i = 0; i < N; i++) a[i] = i; for(i = 0; i < N; i++){ r = rand() % N; temp = a[i]; a[i] = a[r]; a[r] = temp; } cout << "整列前\n----\n"; for(i = 0; i < N; i++) cout << setw(4) << a[i]; cout << '\n'; Sort(a, N); cout << "整列後\n----\n"; for(i = 0; i < N; i++) cout << setw(4) << a[i]; cout << '\n'; return 0; } void Sort(int *s, int n) { //この部分を補って完成させること }

専門家に質問してみよう