基本選択法のプログラムの改善方法を教えてください

このQ&Aのポイント
  • 基本選択法のプログラムを書いていますが、コンパイルは通りますが、うまくソートされません。
  • プログラムの改善方法を教えてください。
  • 課題ではありません。
回答を見る
  • ベストアンサー

基本選択法

宜しくお願いします。 基本選択法のプログラムを書いていますが、コンパイルは通りますが、うまくソートされません。 改良点をご教示ください。 #課題ではありません。 #include <stdio.h> int getMin(int in[], int n, int a); void swap(int *m, int *n); int main(void) {   int a[10] = { 84, 121, 43, 93, 140, 83, 14, 93, 181, 58};   int i, j, k;   for(i=0; i<10; i++){     k = getMin(a, 10, i);     swap(&a[i], &a[k]);     for(j=0; j<10; j++){       printf("a[%d] = %d ", j, a[j]);     }     printf("\n");   }   return 0; } void swap(int *m, int *n) {   int tmp;   tmp = *m;   *m = *n;   *n = tmp; } int getMin(int in[], int n, int a) {   int i, ret, min;   min = in[a];   ret = 0;   for(i = a; i < n; i++)   {     if(in[i] < min){       min = in[i];       ret = i;     }   }   return ret; }

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

  • ベストアンサー
  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

getMin() は a 番目以降で in[] が最小となる場所を戻すということですね。 関数内で ret を 0 に初期化していますが、これを ret = a とすればどうですか? このままでは in[a] が最小であった場合に、戻り値が正しくないでしょう。

hide76318
質問者

お礼

仰るとおりでした。変更したところうまくソートされました。 ありがとうございます。

関連するQ&A

  • 直接選択法

    Cでアルゴリズムの勉強をしているものです。 以下のプログラムを実行して 9 8 7 6 5 4 3 2 1 10 入力すると 10 2 3 4 5 6 7 8 9 9 と帰ってきます。 習いたてでどこが悪いかわからないのでどなたか教えてください 汗。 ////*直接選択法*//// #include <stdio.h> #define MAXDATA 10 void selection(int a[],int n){ int i,j,t; for(i=0 ; i < n ; i++){ for(j=i+1 ; j<n ; j++){ if(a[j] < a[i]) t = a[i]; a[i] = a[j]; a[j] = t; } } } int main(void) { int k,j,sort[MAXDATA]; for(k=0;k < MAXDATA;k++) {printf("sort[%d]:",k); scanf("%d",&sort[k]);} for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); puts("ソートしますか? Yes:1 No:0 ///"); scanf("%d",&j); if(j==1){ selection(sort,MAXDATA); for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); } putchar('\n'); return(0); }

  • 掃出法で連立一次方程式の解を求める

    掃出法で連立一次方程式の解を求めるプログラムを作ってみたのですが、ポインタと浮動小数点のエラーが出てしまい、実行できません。どこが間違っているのかさえ分からず困っています。訂正箇所を教えてください。宜しくお願い致します。 #include<stdio.h> #include<math.h> #include <float.h> #define N 3 #define EPSILON 1.0E-5 #define TRUE 1 #define FALSE 0 void sweep(int *flag); void swap(float *wk1,float *wk2); float a[N][N]={{ 2, 6, 3}, {-1, 5,-2}, {-2,-1, 6}}; float x[N],b[N]={6,3,14}; int flag; void main() { int i,j; for(i=0;i<N;i++) { for(j=0;j<N;j++) printf("%10.4f",a[i][j]); printf("%10.4f\n",b[i]); } flag=TRUE; sweep(&flag); if(flag==TRUE) { printf("連立方程式の解\n"); for(i=0;i=N;i++) printf("x[%d]=%10.4f\n",i+1,x[i]); } else printf("解なし\n"); } void swap(float *wk1,float *wk2) { float w; w=*wk1; *wk1=*wk2; *wk2=w; } void sweep(int *flag) { int i,j,k,ik; float ak,aik; for(k=0;k<N;k++) { ak=a[k][k]; if(fabs(ak)<=EPSILON) { ik=k+1; while((ik<N)&&(fabs(a[ik][k])<EPSILON)) ik++; if(ik<N) { for(j=k;j<N;j++) swap(&a[k][j],&a[ik][j]); swap(b[k],b[ik]); ak=a[k][k]; } else { printf("ピボットが零です\n"); *flag=FALSE; goto end; } } for(j=k;j<N;j++) a[k][j]=a[k][j]/ak; b[k]=b[k]/ak; for(i=0;i<N;i++) { if(i!=k) { aik=a[i][k]; for(j=k;j<N;j++) a[k][j]=a[i][j]-aik*a[k][j]; b[i]=b[i]-aik*b[k]; } } for(k=0;k<N;k++) x[k]=b[k]; end:; } }

  • printfの挿入箇所

    #include <stdio.h> #include <stdlib.h> #define N 500 void bubblesort(int h, int k, int *A); void swap(int i, int j, int *A); int main(void) { int A[N]; int n, i; FILE *file; file=fopen("sortdata", "r"); /* データの読込み */ fscanf(file, "%d", &n); if(n>N) { printf("Illegal array size n = %d for N = %d\n", n, N); exit(1); } for(i=0; i<n; i++) fscanf(file, "%d", &A[i]); /**/ printf("A = "); /**/ printf("\n"); bubblesort(0, n-1, A); /* 配列A[0]からA[n-1]の整列 */ return(0); } /* A[k],...,A[h]の要素をバブルソートによって整列 */ void bubblesort(int h, int k, int *A) { int i, j, p; int no; int test; /* test==1; すでに整列済み */ for(i=h; i<k; i++) /* バブル操作の反復 */ { test=1; for(j=k; j>=i+1; j--) { for(no=0; no<j; no++) printf(" %d",A[no]); if(A[j]<A[j-1]) { printf(" > %d ",A[j]); swap(j, j-1, A); test=0; } else { printf(" < %d ",A[j]); } for(no=j+1; no<=k; no++) printf(" %d ",A[no]); printf("\n"); } printf("\n"); if(test==1) return; } return; } /* Swap A[i] and A[j]. */ void swap(int i, int j, int *A) { int temp; temp=A[i]; A[i]=A[j]; A[j]=temp; return; } 以上のプログラムを A = パス1: 7 5 1 2 8 > 3 7 5 1 2 < 3 8 7 5 1 < 2 3 8 7 5 > 1 2 3 8 7 > 1 5 2 3 8 1 7 5 2 3 8 パス2: 1 7 5 2 3 < 8 1 7 5 2 < 3 8 1 7 5 > 2 3 8 1 7 > 2 5 3 8 1 2 7 5 3 8 パス3: 1 2 7 5 3 < 8 1 2 7 5 > 3 8 1 2 7 > 3 5 8 1 2 3 7 5 8 パス4: 1 2 3 7 5 < 8 1 2 3 7 > 5 8 1 2 3 5 5 8 パス5: 1 2 3 5 7 < 8 1 2 3 5 7 8 比較は15回でした。 交換は8回でした。 と表示させたいのですがうまくいきません。 どなたかご指導よろしくお願いします

  • selection

    /*単純選択ソート*/ #include <stdio.h> #define swap(type, x, y) do {type t = x; x = y; y = t; } while (0) /*--- 単純選択ソート ---*/ void selection(int a[], int n) { int i, j; for (i = 0; i < n - 1; i++) { int min = i; for (j = i + 1; j < n; j++) if (a[j] < a[min]) min = j; swap(int, a[i], a[min]); } } int main(void) { int i; int x[7]; int nx = sizeof(x) / sizeof(x[0]); printf("%d個の整数を入力せよ。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d] : ", i); scanf("%d", &x[i]); } selection(x, nx); /* 配列xを単純選択ソート */ puts("昇順にソートしました。"); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); return (0); } をswapなしで書き換えるにはどこを書き換えればいいですか?

  • ピボット選択がどのように行われてるか確かめたいので

    ピボット選択がどのように行われてるか確かめたいので 関数pivotを呼び出す前と呼び出して式を入れ替えた後のakk,ak+1k,...,ankを調べたいのですが どうすればいいのでしょうか? int gauss(double *x, double *a, double *b, int n) { int i,j,k; double tmp,p,sum; /* step 1: 前進消去 */ for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); /* ピボットの選択 */ /*** 追加(2):ピボット選択前,選択して式を入れ替えた後それぞれの * a(k,k), a(k+1,k), ... , a(n-1,k) * を表示して,ピボット選択がどのように行なわれたか調べる. ***/ /*--- ピボット選択前の位置 ---*/ printf("-- before --\n"); /* a(k,k), a(k+1,k), ... , a(n-1,k) を表示させる.*/ /*----------------------------*/ j = pivot(a,n,k); /* j: ピボットとして選ばれたa(j,k)の行番号 */ if(j == ERROR) { return ERROR; } else { if(j != k) { /* ピボットにはa(k,k)ではなくa(j,k)が選ばれた.式の入れ替えが必要 */ /* Aのk行とj行の入れ替え.*/ for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } /* b[k] と b[j] の入れ替え */ tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } /*--- ピボット選択をし,式の入れ替えをした直後の位置 ---*/ printf("-- after --\n"); /* a(k,k), a(k+1,k), ... , a(n-1,k) を表示させる. /*------------------------------------------------------*/ /* x[k] の消去 */ for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } /*--- 追加(1):第k段によって x[k] を消去した後の,各式の状態を表示する. ---*/ /* a(1,1),a(1,2),...,a(1,n),b(1); a(2,1),a(2,2),... a(2,n),b(2), ... */ printf("k=%d\n",k); /*--------------------------------------------------------------------------*/ }/* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS) return(ERROR); sum=0.0; for(j=k+1; j<n; j++) sum+=a[n*k+j]*x[j]; x[k]=(b[k] - sum)/a[k*n+k]; } return 0; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • C言語の問題です!!

    すみません。 詳細表示をする際に、未ソート部の先頭要素の上に記号文字「*」を表示し、未ソート部の最小要素の上に記号文字「+」を表示したいと思い、以下のソースプログラムを作成したのですが、結果が何か違う気がします…。どこが違うのか、教えていただけませんか? また、プログラムを修正していただけませんか? #include<stdio.h> #include<stdlib.h> #include<time.h> #define swap(type,x,y) do{type t=x;x=y;y=t;}while(0) /*--- 単純選択ソート ---*/ void selection(int a[], int n) { int i, j,k,flg; char *disp[]={" ","[* ]","[ +]","[*+]"}; for (i = 0; i < n - 1; i++) { int min = i; for (j = i + 1; j < n; j++) { if (a[min] > a[j]) { min = j; } } for (k = 0; k < n; k++) { flg=0; if(k==i) flg|=1; if(k==min) flg|=2; printf("%s",disp[flg]); } printf("\n"); for (k = 0; k < n; k++) printf("[%2d]", a[k]); printf("\n"); swap(int, a[i], a[min]); } } int main(void) { int i, nx; int *x; printf("要素数 : "); scanf("%d", &nx); x = calloc(nx, sizeof(int)); srand(time(NULL)); for (i = 0; i < nx; i++) { x[i] = rand() % 100; printf("x[%d] = %d\n", i, x[i]); } selection(x, nx); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); free(x); return 0; }

  • Gaussの消去法のプログラムなんですがこれを利用して、消去法による行

    Gaussの消去法のプログラムなんですがこれを利用して、消去法による行列式の計算プログラムをつくりたいのですが難しくてよくわかりません。。。 教えていただきたいです。 困ってるのでよろしくお願いします。 int gauss(double *x, double *a, double *b, int n) { int i,j,k,m; double tmp,p,sum; for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); printf("-- before --\n"); for( m = k;m < n;m++){ printf("%lf\n",a[n * m + k]); } printf("-- --\n"); j = pivot(a,n,k); if(j == ERROR) { return ERROR; } else { if(j != k) { for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } printf("-- after --\n"); for( m = k;m < n;m++){ printf("%lf \n",a[n * m + k]); } for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } printf("k=%d\n",k); /*--------------------------------------------------------------------------*/ } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS){ return(ERROR); } sum=0.0; for(j=k+1; j<n; j++){ sum+=a[n*k+j]*x[j]; } x[k]=(b[k] - sum)/a[k*n+k]; } return 0; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • n個の要素を持つ配列xをシェルソートで昇順に整列

    穴埋め問題ですが、for文の j -= k の考えで立ち止まります。 #include <stdio.h> #define swap(X, Y) 【 1 】 ← X ^= Y, Y ^= X, X ^= Y void shell(int x[ ], int n); void main() {     int x[12] = {23, 67, 54, 82, 13, 28, 55, 61, 50, 32, 29, 44};     int n = 12, i ;     printf("配列(整列前)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]);       shell(x, n);     printf("配列(整列後)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]); } void shell(int x[ ], int n) {     int i, j, k = n ;     while( 【 2 】 ){ ← k > 0         【 3 】 ← k /= 2;         for( i = 0; 【 4 】; i++)             for( j = i; 【 5 】; j -= k)               swap(x[j], x[j + k]);     } } 【 1 】【 2 】は自信があるのですが【 3 】はあまり自信がないです。 【 4 】と【 5 】はどうすれば出来ますか教えてください。お願いします。

  • c言語 行列のn階乗のプログラム

      1 2 -1 D= 3 0 -2   -1 1 2 の3次正方行列のn乗を計算するプログラムを作成しています。 いろいろと試してみましたがうまくいきません。 どなたか教えていただけるとうれしいです。 よろしくおねがいします。 #include <stdio.h> int main(void) { int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int s[3][3]; int m,n; int i,j,k; printf("[A]^n;n = ");scanf("%d",&n); for (m=2;m <= n;m++){ for (i=0;i<3;i++){ for (j=0;j<3;j++){ s[i][j] = 0; for(k=0;k<3;k++){ s[i][j] =s[i][j] + a[i][k] * b[k][j]; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j]=s[i][j]; } } printf("%3d",s[i][j]); putchar('\n'); } return (0); }

  • c言語 select sort

    最大値検索法のプログラムコードです。 どこがおかしいのでしょうか? 分かる方、教えてください。 よろしくおねがいします。 swapのプログラムコード #include <stdio.h> void swap(int *px,int *py); int main (void) { FILE *fp; if ((fp=fopen("file.txt","rt"))==NULL){ printf("File open error.\n"); return 0; } int i,a[100]; for(i=0;i<100;i++){ fscanf(fp,"%d,",&a[i]); //ファイルから読み込み処理。// } fclose(fp); for(i=0;i<10;i++) printf("[%d]=%d\n",i,a[i]); /*1.ソートすべきデータの中で最大のデータを見つけ、 2.そのデータを最後のデータと入れ替える。 最大データは配列のどこにあるのか⇒maxi              その値⇒max とする。*/ //データが10個の場合 int max,maxi,j; max=a[0],maxi=0; for(i = 0;i < 9; i++){ if(a[i + 1] > max){ max = a[i + 1]; maxi = i + 1; } swap(&a[maxi],&a[9-j]); /* コマンド $cc sort.c swap.c */ for(j=0;j<9;j++){ printf("%d\n",j); max=a[0], maxi=0; for(i=0;i<9-j;i++){ //最大値をもつデータ探索;(カウンタ変数) max++; } //最大データと探索範囲最後のデータとの入れ替え: //void swap(int *px, int *py){ int n,*px,*py; n = *px; *px = *py; *py = n; // } if((fp=fopen("file.txt","wt"))==NULL){ printf("File open error.\n"); return 0; } for(i=0;i<100;i++){ fprintf(fp,"%d",a[i]); } fclose(fp); } } sort.cのプログラムコード #include<stdio.h> void swap (int *px,int *py); int main(void) { int a[0],b,maxi,j,max; max=a[0],maxi=0; printf("input \"a\" as integer = "); scanf("%d",&a); printf("input \"b\" as integer = "); scanf("%d",&b); printf("Before swap...\n"); printf("a - b = %d, a / b = %d...%d\n",a-b,a-b,a-b); // swap(&px,&py); swap(&a[maxi],&a[9-j]); printf("After swap...\n"); printf("a - b = %d, a / b = %d...%d\n",a-b,a-b,a-b); return 0; } void swap (int *px,int *py) { int n; n = *px; *px = *py; *py = n; } 実行結果 /tmp/ccBGIpCi.o(.text+0x0): In function `main': : multiple definition of `main' /tmp/ccMCttJd.o(.text+0x0): first defined here /usr/bin/ld: Warning: size of symbol `main' changed from 304 in /tmp/ccMCttJd.o to 641 in /tmp/ccBGIpCi.o collect2: ld はステータス 1 で終了

専門家に質問してみよう