• 締切済み

C言語での配列順序を変えたい

C言語で遺伝的アルゴリズムを作ろうと思っています。そのときに「配列の中の値を調べてそれを数字の高い順に別の配列に入れる」というので、並び替える方法がわかりません。 for(i=0;i<10;i++){ //並び替える前をy、並び替えた後をzとする for(j=0;j<10;j++){ if(y[i] < y[j]){ z[i+1] = y[i]; }else{ z[i-1] = y[i]; } } } としてやってみたら、よく考えると上の配列に値があった場合、重なってしまうので、実際表示して見たところ同じような数字が出てきました。

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.7

#5 です。 #3さん>・下手に考えるより、y→zへそのままコピーして z をソートするのが確実 は承知していました。なるほどと。 その意味では、 #4さん>結論としては「ソートについて調べましょう」ですね。 言葉足らずでしたが、一発(コピー + ソート)で決めるには・・と。 その発想自体が無駄でしたね。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

そんな面倒なことをせずとも, あらかじめ y の内容を全部 z にコピーしとけばいいのでは>#5.

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.5

「配列 y を変更してはいけない」ものを作ってみました。 参考までに。 #4さん>結論としては「ソートについて調べましょう」ですね。 「配列 y を変更してはいけない」の場合は、「ソートについて調べ」ただけでは、ダメかもしれません。 3重の for 構文になりそう・・。 「ソート」と同じ、2重でできそうなもんですが、年寄りの夜更かしには思いつかない・・残念。 #include <stdio.h> #define CNT 10 int main( void ) {  double y[ CNT ] = { 0.9, 1.8,-2.7, 3.6, 4.5, 5.4, 6.3,-7.2, 8.1, 9.0 };  double z[ CNT ], dMax;  int iSumi[ CNT ] = { 0 };  int i, j, nn, kk;  for( nn = 0; nn < CNT; nn++ ){   for( j = 0; j < CNT; j++ ){    if( iSumi[ j ] ) continue;    dMax = y[ j ]; // 仮の最大値    kk = j;    for( i = 0; i < CNT; i++ ){     if( iSumi[ i ] ) continue;     if( dMax < y[ i ] ){      dMax = y[ i ];      kk = i;     }    }   }   z[ nn ] = y[ kk ];   iSumi[ kk ] = 1;  }  for( i = 0; i < CNT; i++ ) printf( " %5.1f", y[ i ] );  printf( "\n" );  for( i = 0; i < CNT; i++ ) printf( " %5.1f", z[ i ] );  printf( "\n" );  return( 0 ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

  • LOHA
  • ベストアンサー率52% (203/388)
回答No.4

#3さんへ。 仰るとおりです。 投稿後に#1さんのソートするだけというの見て、あーアホしたと思いましたが(yからzへ入れるということを考えすぎてたようで…)、まぁそれでもひとつの方法としてこんなのもあるという事で、ご容赦を。 結論としては「ソートについて調べましょう」ですね。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

・単純挿入ソートの要領で、一つ一つ並べながらzへ追加する ・下手に考えるより、y→zへそのままコピーして z をソートするのが確実 #2さんへ。 そのやりかただと、配列yの内容が破壊されてしまいますし、yがintでなければ使えないし、計算時間も無駄です。 「配列yを変更していい」のなら、そんな面倒なことしないで、最初から配列yをソートすればいいです。

  • LOHA
  • ベストアンサー率52% (203/388)
回答No.2

こんなんでどうでしょう。 /* 最大の要素番号を返す */ int maxIndex(int* a, int size) {   int i, mi = 0;   for (i = 1; i < size; ++i)     if (a[mi] < a[i])       mi = i;   return mi; } /* ループ部 */ for (i = 0; i < 10; ++i) {   int mi = maxIndex(y, 10);   z[i] = y[mi];   y[mi] = INT_MIN; } #動作確認はしていません。ミスがあったらスミマセン。 #型違ったら適宜変更してください。 #全角スペースにしてるので、コピペの際は注意。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そこで悩むくらいならソートのアルゴリズムを調べた方がはるかに速い.

関連するQ&A

  • 【C言語を教えてください!】2次元配列について

    【C言語を教えてください!】2次元配列について 2次元配列を用いて、コンソール画面(ターミナル)の中央付近に*を表示させるプログラムを作りたいのですがさっぱり分かりません。 画面の大きさは半角で横80 縦25です。 25は奇数ですので40×12に表示したいと思います。 2重ループでなら出来たのですが配列でのやり方がわかりません。 #include<stdio.h> main() { int i,j; for(i=0;i<25;i++){ for(j=0;j<80;j++){ if(i==12&j==39){ putchar('*'); }else{ putchar(' '); } } } return 0; } 回答お願いします!

  • c言語

    c言語で写真の課題を出されたのですが自分のプログラムでは上手くいきません。どこが間違っているのか教えて欲しいです。 自分のプログラム #include<stdio.h> #include<math.h> int main(){ int i,j; double c,d,x,y,z; for(i=0;i<=360;i++){ c=10*cos(i*M_PI/180); d=10*sin(i*M_PI/180); if(c>=0 && d>=0){ for(j=0;j<=1000;j++){ x=0.001*j; y =x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } if(c<=0 && d>=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c<=0 && d<=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c>=0 && d<=0){ for(j=0;j<=1000;j++){ x=0.001*j; y=x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } printf("x=%lf y=%lf z=%lf\n",x,y,z); } return(0); }

  • C言語の2次配列

    4行5列の配列を用意し、その配列の要素をtij(i=1~4, j=1~5)とするとき、tij=i×j となるように配列に値を入れ、 それを表の形で画面に表示するプログラムを作りなさい。  という問題なんですが、自分は下の様に組みましたがうまく動きません。どこが悪いのか教えてください。よろしくお願いします。あまりC言語を理解していないので申し訳ないですが、なるべく簡単に教えて頂ければ幸いです。 #include<stdio.h> int main(void) { int i,j; int t[4][5]; for(i=0;i<=3;i++) { for(j=0;j<=4;j++) t=i*j; printf("%5d",t); printf("\n"); } return 0; }

  • c言語で配列を返したい

    自分がc言語で書いているプログラムの関数で次のようなものがあるのですが、 int CTR(int data[], int* key, long long t){ int buf[sizeof(data)]; int tmp[16]; int bytesoft[128]; int i,j; KeyExpansion(key); for(i=0;i<sizeof(data);i+=16){ for(j=0;j<16;j++){ if(j<sizeof(bytesoft)) tmp[16-j-1]=bytesoft[sizeof(bytesoft)-j-1]; else tmp[16-j-1]=0; } Cipher(data); for(j=0;j<16;j++){ buf[i+j] ^= data[i+j]; } t=t+1; } return buf; } 配列bufを返すためには、ポインタを用いればいいということは調べて分かったのですが具体的にどのように書き換えればいいかよくわかりません。 どなたかご教授いただけないでしょうか?

  • C言語のプログラミング配列・forを使った検索

    C言語のプログラミングで、配列とforを使った検索の表し方がわかりません。 numにはキーボードから任意の数字を入力し、 1ならば25、2ならば30、、、といったように 対応する数字を表示させ、1行目にない数字が入力された時は 「NoData」と表示させたいのですが、上手くいきません; 本当はもっと配列が多いのですが4つでやってみると #include <stdio.h> main() { int data[2][4]{{1,2,3,4},{25,30,45,50}} , num , i ; printf("num?"); scanf(&num); for(i=0; i>4;i++) if(num== data[0][i]){ printf("number is \n",data[1][i]);} else {printf("NoData\n"); } return0 ; } こうかと思ったのですが上手くいきません、、、 どなたかお願いします!

  • c言語配列の問題について

    c言語配列の問題について 以下のプログラムは10個の数値を入力させ重複している文字を表示するプログラムですが match==i[k]でどの様に重複した数値を認識しているのかが解説不足で理解できません。 どの様に処理されているのか詳しく解説できる方がいましたらご教授願います。 #include <stdio.h> int main(void) { int i[10],j,k,match; printf("10個の数字を入力して下さい"); for(j=0;j<10;j++) scanf("%d",&i[j]); for(j=0;j<10;j++){ match=i[j]; for(k=j+1;k<10;k++) if(match==i[k]) printf("%dが重複しています\n",match); } return 0; }

  • C言語を使って、ファイルの読み込みをして切り出して2次元配列に格納した

    C言語を使って、ファイルの読み込みをして切り出して2次元配列に格納したいのです。 1,2行目に配列の行の数と列の数が書かれ、3行目から改行とカンマ、スペースで区切られて配列が書かれているテキストを読み込んで2次元配列に格納する。 テキストの例) 4 3 1.1 1.2 1.3 1.4 1.5 2.1 2.2 2.3 2.4 2.5 3.1 3.2 3.3 4.4 3.5 というプログラムを書いています。色々と参考書やサイトを参考してとりあえずの形にはなったと思ったのですが、実行してもエラーが出ます。 どこまで動いているか調べたところ、一行ごとに読み出してそれを切り出して行くところでおかしな事をしてしまっているようですが、どう変えたらいいものか分かりません。 なので、その点のアドバイスと 大きさの分からないファイルから1,2行目を読み出すのはこれで変な動きをする恐れはないか の2点についてヒントでも構わないので、教えてください。 以下、書いたソースです(申し訳ないのですが、文字数の関係で一部省略しています。) #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[] ) { double ** mainhairetu; int size_x, size_y; /* size_x 行 size_y 列 */ int i,j,count=0,count2; int *cut,*temp2; double temp; char s2[] = " ,"; char gyou[10],*num; FILE *fil; while((fgets(gyou,10,fil)) !=NULL){ if(count == 0){ size_x=atoi(gyou); count++; }else if(count ==1){ size_y=atoi(gyou); count=count+1; }else{ break; } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ここでmallocを使ってcutとmainhairetuの2つの配列を作っています。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ count=0; for (i = 0; i < size_y+2; i++) { mainhairetu[i][0] = atof( strtok( fgets(cut,50,fil),s2 ) ); for (j = 1; j < size_x; j++){ if(count <=1){ count++; break; }else{ mainhairetu[i][j] = atof( strtok( NULL,s2 ) ); } } } for(i=0;i<size_y;i++){ for(j=0;j<size_y;j++){ printf("%f",mainhairetu[i][j]); } printf("\n"); } return(0); }

  • C言語の配列の使い方について質問です。

    以下のプログラムを配列を使って見やすくしたいのですが、どのように作ったら良いでしょうか? 宜しくお願いします。 #include<stdio.h> int main(void) { int a, b, c, d, e, f, g, h, i, j, k, l, m ,n, o; /*5段目の処理*/ for(a = 1; a <= 15; a++) { for(b = 1; b <= 15; b++) { if(a == b) continue; for(c = 1; c <= 15; c++) { if(a == c || b == c) continue; for(d = 1; d <= 15; d++) { if(a == d || b == d || c == d) continue; for(e = 1; e <= 15; e++) { if(a == e || b == e || c == e || d == e) continue; // printf("%d %d %d %d %d\n", a, b, c, d, e); ////4段目//// if(a>b){ f=a-b; } else if(a<b){ f=b-a; } if(b>c){ g=b-c; } else if(b<c){ g=c-b; } if(c>d){ h=c-d; } else if(c<d){ h=d-c; } if(d>e){ i=d-e; } else if(e<d){ i=e-d; } // printf(" %d %d %d %d \n", f, g, h, i); /////3段目//// if(f>g){ j=f-g; } else if(f<g){ j=g-f; } if(g>h){ k=g-h; } else if(g<h){ k=h-g; } if(h>i){ l=h-i; } else if(h<i){ l=i-h; } // printf(" %d %d %d \n", j, k, l); /////2段目//// if(j>k){ m=j-k; } else if(j<k){ m=k-j; } if(k>l){ n=k-l; } else if(k<l){ n=l-k; } // printf(" %d %d \n", m, n); /////三段目///// if(m>n){ o=m-n; } else if(m<n){ o=n-m; } // printf(" %d \n", o); if(a != b != c != d != e != f != g != h != i != j != k != l != m != n != o){ printf("%d %d %d %d %d\n", a, b, c, d, e); printf(" %d %d %d %d \n", f, g, h, i); printf(" %d %d %d \n", j, k, l); printf(" %d %d \n", m, n); printf(" %d \n", o); } } } } } } }

  • C言語。どうしてコンパイルできません^^;

    最近プログラミングの勉強をはじめました。 C言語を勉強しています。 /*入力した値の、平均値・最大値・最小値・を出す。*/ #include <stdio.h> int main(void) { int x[5],i,j,w,x,y,z,sum; printf("5つの実数の平均、最大値、最小値を求めます\n"); sum = 0; for(i=0; i<5; i++){ printf("値%d:",i+1); scanf("%d",&x[i]); sum += x[i]; } for(y=0; y<5; y++){ for(j=0; j<4; j++){ w=j+1; if(x[j] < x[w]){ z = x[i]; x[i] = x[w]; x[w] = z; } } } printf("平均値:%f\n最大値:%d\n最小値:%d\n", (double)sum/5, x[0], x[4]); return 0; } Microsoft Visual C++ 2008 Express Edition でコンパイルをしようとしたのですが、 「error C2040: 'x' : 'int' は 'int [5]' と間接操作のレベルが異なります。」 と出てできませんでした^^; 何度も見直したのですが、どうしても間違っている場所がわかりません^^; どこがいけないのでしょうか^^;

  • c言語です

    c言語初心者です。今大学の課題でc言語のプログラムをかいているのですが、うまくいかないので助けて欲しいです。以下のようなプログラムで調和平均の値を出したいのですがなぜか表示されません。infと表示されてしまいます。あと調和平均とはn/(1/d1+1/d2+1/d3+.........+1/dn)の値です。ここでd1~dnは入力された数のことです。なので0が入力された場合は値を返さないようにしたいです。   どこをどのように直せばいいのか教えてください。よろしくお願いします。 #include <stdio.h> #include<math.h> #define M 1000 int main (int argc, const char * argv[]) { // insert code here... float d[M]; double e[M]; double wa=0.0,av,bun=0,kika=1,tyowa=0; /*avはaverageを,bunは分散を意味します*/ int i=0,j=0; printf("複数の数字を入力してください\n"); printf("数字入力を終了するときはnull文字を入力してください\n"); printf("数字以外が入力されたら\n"); printf("それまでの数字の計算結果を表します\n"); /*数字を入力、和を求める*/ while (scanf("%f",&d[i])!='\0') { wa=wa+d[i]; i++; } if (i!=0) { printf("算術平均は%fです\n",wa/i); av=wa/i; for (j=0; j<i; j++) { kika=kika*d[j]; } printf("幾何平均は%fです\n",pow(kika,1./i)); for (j=0; j<i; j++) { if (d[j]=0) { printf("調和平均は出せません\n"); } else e[j]=1/d[j]; } for (j=0; j<i; j++) { tyowa=tyowa+e[j]; } printf("調和平均は%fです\n",e[1]); for (j=0; j<i; j++) { bun=bun+(d[j]-av)*(d[j]-av); } printf("分散の値は%fです\n",bun/i); } else { printf("数字を入力してください\n"); } return 0; }

専門家に質問してみよう