• ベストアンサー

C言語での質問

プログラミングの課題をやっているのですが、一部どうしてもわからないことがあるので質問させて下さい。 課題では100個の点のX座標、Y座標を0から5の間でランダムに設定し、ファイルに書き出すといった内容なのですが、この点を設定した時、任意の2点のX座標、Y座標の差が0.01以下になる場合は設定し直さないといけません。 これは後々の課題に関係してくるから、みたいなのですが。 そこで点の設定の関数として以下のようなプログラムを考えてみました。(ちなみに構造体pointを前に宣言してあり、p[].xは点のX座標、p[].yは点のY座標です。また、NUM=100と最初に宣言してあります。) void tensettei(point p[], int num){ int i, j, k; double sa; for(i=0; i < num; i++){ p[i].x = ((double) rand()) / ((double) RAND_MAX) * 5; p[i].y = ((double) rand()) / ((double) RAND_MAX) * 5; } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(p[j].x > p[k].x) sa = p[j].x - p[k].x; else sa = p[k].x - p[j].x; if(sa < 0.01) tensettei(p, NUM) } } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(mp[j].y > mp[k].y) sa = mp[j].y - mp[k].y; else sa = mp[k].y - mp[j].y; if(sa < 0.01) tensettei(p, NUM) } } } しかし、実行してもエラーが起こったのかすぐに終了してしまい、この後に点データを出力するプログラムを書いているのですが、ちゃんと出力されません。 いろいろプログラムを変えて試した結果、原因は「tensettei(p, NUM)」にあることはわかりました。 それさえ変えればすればうまく動作しましたので。 再帰と同じ感じでいけるかと思ったのですがどうやら駄目のようです。 そこで質問なのですが、ループの中である条件が起こったら最初からやり直し、てなプログラムはどんな風にすればいいのでしょうか?

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.9

>任意の2点のX座標、Y座標の差が0.01以下になる場合 という定義が少しあいまいなので、認識が間違っているかも しれません。2点というのは、今まで設定された座標と 今設定しようとしている座標の事だとして、 今までに登録されたX,Yとこれから登録するX,Yの誤差が 0.01未満ならば再設定不要であると言うことでよいでしょうか? つまり、登録されるX,Yの差異が全て0.01以上になれば良いと 判断します。 以下サンプル /* * WinXP Pro SP2 VC++6.0 */ #include <math.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXARRAYCOUNT (100) #define OUTPERMISSION (0.01) //許容外数値設定 typedef struct{  double x;  double y; }point; void tensettei( point *p, int num ) {  int i,j;  double diff = 0.0;  printf( "Out Permission Setting = %f \n", OUTPERMISSION);  for( i=0; i<num; i++ ){   // X軸,Y軸を配列にセット   p[i].x = ( 5.0 * rand()/RAND_MAX );   p[i].y = ( 5.0 * rand()/RAND_MAX );      //自身の座標X/Yが0.01以下    diff = fabs( p[i].x - p[i].y );   if( diff< OUTPERMISSION ){    i--;    continue;   }   //既存設定要素内と照合   for( j=0; j<i; j++ ){    //任意2点のXが0.01以下    diff = fabs( p[j].x - p[i].x );    if( diff< OUTPERMISSION ){     break;    }    //任意2点のX/Yが0.01以下    diff = fabs( p[j].x - p[i].y );    if( diff< OUTPERMISSION ){     break;    }    //任意2点のY/Xが0.01以下    diff = fabs( p[j].y - p[i].x );    if( diff< OUTPERMISSION ){     break;    }    //任意2点のYが0.01以下     diff = fabs( p[j].y - p[i].y );    if( diff< OUTPERMISSION ){     break;    }   }   //任意要素1つのXまたはYの誤差が0.01以下なので再設定   if( j != i ){    i--;    continue;   }  }//for } int main( int argc, char* argv[] ) {  int i, j;  double diff = 0.0;  point p[MAXARRAYCOUNT];  //乱数生成  srand(time(NULL));  srand(rand()/RAND_MAX);  //初期化  memset( p, 0, sizeof(p));  //問題の箇所  tensettei( p, MAXARRAYCOUNT );  printf( "----- Result Check -----\n" );  //Debug 既存設定要素内と照合確認し全ての要素の座標において重複が無いか確認  //もし配列内に1つでも差異0.01未満があれば何番目と何番目の差異がどれだけあるかを表示する  for( i=0; i<MAXARRAYCOUNT; i++ ){   for( j=0; j<MAXARRAYCOUNT; j++ ){    if( i != j ){     diff = fabs( p[j].x - p[i].x );     if( diff< OUTPERMISSION ){      printf( "[OUTPERMISSION] => X[%03d]:%f X[%03d]:%f Diff:%f\n", j, p[j].x, i, p[i].x, diff );     }     diff = fabs( p[j].x - p[i].y );     if( diff< OUTPERMISSION ){      printf( "[OUTPERMISSION] => X[%03d]:%f Y[%03d]:%f Diff:%f\n", j, p[j].x, i, p[i].y, diff );     }     diff = fabs( p[j].y - p[i].x );     if( diff< OUTPERMISSION ){      printf( "[OUTPERMISSION] => Y[%03d]:%f X[%03d]:%f Diff:%f\n", j, p[j].y, i, p[i].x, diff );     }     diff = fabs( p[j].y - p[i].y );     if( diff< OUTPERMISSION ){      printf( "[OUTPERMISSION] => Y[%03d]:%f Y[%03d]:%f Diff:%f\n", j, p[j].y, i, p[i].y, diff );     }    } else {     diff = fabs( p[i].x - p[i].y );     if( diff< OUTPERMISSION ){      printf( "[OUTPERMISSION] => X[%03d]:%f Y[%03d]:%f Diff:%f\n", j, p[i].x, i, p[i].y, diff );     }else{      printf( "[%03d]X:%f Y:%f \n", i, p[i].x, p[i].y );     }    }   }  }  return 0; }

swmarimo
質問者

お礼

「任意の2点のX座標、Y座標の差が0.01以下」というのは任意の2点のX座標の差が0.01以下、または任意の2点のY座標の差が0.01以下、ということです。 わかりにくくて申し訳ありませんでした。 ただ、プログラム自体は最終的に作った物と同じ感じです。 ありがとうございました。

その他の回答 (9)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.10

#9です。 コメントがうそがいっぱいありますね。。。 以下のように読み替えてください。 座標X/Yが0.01以下 >> 座標X/Yの『差異』が0.01『未満』 また、OUTPERMISSIONの値を大きくすると、 乱数の発生する数値の総数が100個以下になり、 無限ループに陥ります。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.8

再帰は必要ないように思います 0から5までで 任意の2要素の差が 0.01より大きくしたいなら 500個のフラグを用意して これを参照しながら各要素を決定してみてはいかがでしょう char flagX[500]; int n = 0, i = 0; for( n=0; n<500; n++ ) {  flagX[n] = 1; } n = 0; while ( n < NUM ) {  double rndX = 5.0 * rand() / RAND_MAX;  i = (int)(rndX * 100);  // 要素rndXが使用済みか  if ( flagX[i] ) {   // 要素rndXが 1以上か   if ( i>0 ) {    // 要素rndX-0.01は使用済みか    if (flagX[i-1]) {     // 要素rndXが 4.99未満か     if (i<499) {     // 要素rndX+0.01は使用済みか      if ( flagX[n+1] ) {       p[n].x = rndX;       n++;       flagX[i-1] = flagX[i] = flagX[i+1] = 0;      }     } else {      // 要素rndXが4.99の場合      p[n].x = rndX;      n++;     }    }   } else {    // 要素rndXが0の場合    if ( flagX[i+1] ) {     p[n] = rndX;     n++;     flagX[i] = flagX[n+1] = 0;    }   }  } } Y側も同様の処理で可能だと思います

swmarimo
質問者

お礼

こういう考え方もアリですね。 ただ、やっぱり1個作るたびに判定して・・・のほうがプログラムとしてはすっきりするので。。。 ありがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.7

★修正。 ・問題文を間違って理解してしまったようです。  0.01 以下で再設定でしたね。  下に修正版を載せます。 修正版: void tensettei( point p[], int num ) {  double diff, rndX, rndY;  int i;    // 最初だけ 0~5 の乱数  p[ 0 ].x = (5.0 * rand() / RAND_MAX);  p[ 0 ].y = (5.0 * rand() / RAND_MAX);    for ( i = 1 ; i < num ; i++ ){   // X軸の乱数   do {    rndX = (5.0 * rand() / RAND_MAX); // 0~5の乱数    diff = fabs( p[i - 1].x - rndX ); // 差を計算   } while ( diff < 0.01 );      // Y軸の乱数   do {    rndY = (5.0 * rand() / RAND_MAX); // 0~5の乱数    diff = fabs( p[i - 1].y - rndY ); // 差を計算   } while ( diff < 0.01 );      // X軸,Y軸を配列にセット   p[ i ].x = rndX;   p[ i ].y = rndY;  } }

swmarimo
質問者

お礼

下のお礼に挙げた理由で採用は出来ませんが、とりあえずこのプログラムでも動作はすると思います。 ありがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★アドバイス ・再帰処理と書かれていますが、普通にループでも出来ますが…。  あと最初に 100 個の点を乱数で発生させるよりも1つ1つ乱数で発生させるときに  0.01 を越えないように乱数の段階で制御して 100 個の点を配列にセットすれば楽だと思います。 ・つまり、最初の1つ目だけ 0~5 の乱数でそれ以降の 99 個は 0 ~ 0.02 の範囲に設定します。  そして、前の点に加算して 0~5 の範囲に制御すれば良いと思います。 ・下にそのサンプルを載せておきます。 サンプル: void tensettei( point p[], int num ) {  double px, rndX;  double py, rndY;  int i;    // 最初だけ 0~5 の乱数  p[ 0 ].x = (5.0 * rand() / RAND_MAX);  p[ 0 ].y = (5.0 * rand() / RAND_MAX);    for ( i = 1 ; i < num ; i++ ){   // -0.01~+0.01 までの乱数   rndX = (0.02 * rand() / RAND_MAX) - 0.01;   rndY = (0.02 * rand() / RAND_MAX) - 0.01;      // 新しいX軸,Y軸   px = p[i - 1].x + rndX;   py = p[i - 1].y + rndY;      // 新しいX軸,Y軸の 0~5 補正   px = (px >= 5.0) ? 5.0 : (px < 0.0) ? 0.0 : px;   py = (py >= 5.0) ? 5.0 : (py < 0.0) ? 0.0 : py;      // 補正したX軸,Y軸を配列にセット   p[ i ].x = px;   p[ i ].y = py;  } }

swmarimo
質問者

お礼

下のお礼にも書いたとおり、最初に100個の点を作ったのが問題だったのですが、Oh-Orangeさんの考え方だと次の課題に影響が出てくるので・・・ 結局1個新しい点を作るたびにそれまで作った点と比較して、差が0.01以下のものがあれば--iしてやってやり直し、というプログラムにしました。

  • fatbowler
  • ベストアンサー率48% (26/54)
回答No.5

まず1つ、再帰呼出しから戻ってきた後、諦めたはずなのにさっきのforループを 続けてしまう、という問題があります。 それを解消するには色々策がありますが、質問者のやりたいことに近いだろうと 思われるコードを書いてみました。 ポイントは、差を評価する部分を関数化して「forループ2つを一気に終了させる」 ことを可能にした点です。 (ちなみに、C言語ではgoto文は蛇蝎のごとく嫌われるので、極力使わない方がいいです。) 一応これで動いているのですが、残念ながら100個の点全てのx座標、y座標が うまく散らばることは非常に難しいらしく、何度も再帰呼出しを繰り返した末、 スタックが不足してエラーが起こっているようです。 ダメだったら最初からやり直し、というやり方に無理があるように思います。 #include <stdio.h> #include <stdlib.h> #define NUM 100 typedef struct _point { double x; double y; } point; int check_points(point p[], int num) { int j,k; double sa; for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(p[j].x > p[k].x) sa = p[j].x - p[k].x; else sa = p[k].x - p[j].x; if(sa < 0.01) return(0); } } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(p[j].y > p[k].y) sa = p[j].y - p[k].y; else sa = p[k].y - p[j].y; if(sa < 0.01) return(0); } } return(1); } void tensettei(point p[], int num) { int i; for(i=0; i < num; i++){ p[i].x = ((double) rand()) / ((double) RAND_MAX) * 5; p[i].y = ((double) rand()) / ((double) RAND_MAX) * 5; } if(check_points(p, num) == 0) tensettei(p, num); } void main(void) { point points[100]; int i; tensettei(points, NUM); for(i=0 ; i<NUM ; i++) printf("points[%3d} = (%2.3lf, %2.3lf)\n", i, points[i].x, points[i].y); }

swmarimo
質問者

お礼

はい、結局「残念ながら100個の点全てのx座標、y座標がうまく散らばることは非常に難しいらしく、何度も再帰呼出しを繰り返した末、スタックが不足してエラーが起こっている」ということが問題でした。 根本的な間違いだったわけです。 ありがとうございました。

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

再帰呼出しでもできそうな気もするが、試してないので以下適当な意見。 再帰で呼出すとき、tensetti(p, NUM) となっているけど、これは tensettei(p, num) の誤記ですよね。 あと、戦略として 100個の点を p[] に格納してから、2点の差を検証して 0.01 を下回ったら、再度 100個の点を p[] に再設定するということですね。 そうであれば、 for の 2重ループで 2点間の最小の差を sa に格納し終ってから loop の外側で if ( sa < 0.01 ) tensettei(p, num); とした方がわかりやすいと思います。 >ループの中である条件が起こったら最初からやり直し、 >てなプログラムはどんな風にすればいいのでしょうか? 私なら最初からやり直すのではなしに、配列 p[] に点を格納する際に、「それまで格納した点と今 rand() 関数で得られた点の最小距離」を計算する関数 distance(point* p, size_t size, point new_pt); を作成して do {  p[i].x = ((double) rand()) / ((double) RAND_MAX) * 5;  p[i].y = ((double) rand()) / ((double) RAND_MAX) * 5; } while ( distance(p, i-1, p[i]) < 0.01 ); のような感じでループを回すのかなぁ。(これまた適当)

swmarimo
質問者

お礼

はい、誤記です。(まぁどっちでも結果は同じですが。) 結局いろいろな人にアドバイスを受けて 「私なら最初からやり直すのではなしに、配列 p[] に点を格納する際に、「それまで格納した点と今 rand() 関数で得られた点の最小距離」を計算する関数distance(point* p, size_t size, point new_pt); を作成して」 に近いプログラムに変更してちゃんと動作するようになりました。 ありがとうございました。

回答No.3

関数用意する時、少数を使う場合は float型とかじゃないとできないとかではないでしょうか?

swmarimo
質問者

お礼

いえ、そういうことではないです。

noname#38837
noname#38837
回答No.2

デバッガを使ってエラー位置を特定してみてください >それさえ変えればすればうまく動作しましたので どう変更したらうまく実行できましたか? コンパイルは通っているのですか? コンパイラによるのかもしれませんが tensettei(p, NUM); としなくてもコンパイル通るんでしょうか >ループの中である条件が起こったら最初からやり直し ある条件でgotoを使うとか? 再帰というか再呼び出しでもいいと思いますけども。 結果さえちゃんと順に返してあげれば。

swmarimo
質問者

お礼

0.01以下判定部分を削除したら問題なく動作しましたので。 コンパイラは通ってます。 問題は文法とかじゃなくてもっと根本的な考え方の部分にありました。

noname#50176
noname#50176
回答No.1

void tensettei(point p[], int num){ start: int i, j, k; double sa; for(i=0; i < num; i++){ p[i].x = ((double) rand()) / ((double) RAND_MAX) * 5; p[i].y = ((double) rand()) / ((double) RAND_MAX) * 5; } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(p[j].x > p[k].x) sa = p[j].x - p[k].x; else sa = p[k].x - p[j].x; if(sa < 0.01) goto start; } } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(mp[j].y > mp[k].y) sa = mp[j].y - mp[k].y; else sa = mp[k].y - mp[j].y; if(sa < 0.01) goto start; } } } のような単一ループはだめですか?

swmarimo
質問者

お礼

goto文は出来るだけ使いたくないのですが・・・ 試してみましたが結局結果は同じでした。

関連するQ&A

  • C言語のプログラムで質問です。

    C言語のプログラムで質問です。 下のプログラム(最小二乗法の計算)を実行したところ -1.#IND00 というエラーが出てしまいます。 どこを直せばいいのでしょうか、教えてください。 #include <stdio.h> #include <math.h> /* gauss33.c */ #define N 3 main(){ double A[N][N],Aa[N][N]; double b[N],x[N], bb[N], e[N]; int n=N; int i, j, k; double akk, aik, s; double y[N]; double xx,yy; for(i=0;i<n;i++){ /*変数の初期化*/ x[i]=y[i]=0; for(j=0;j<n;j++) A[i][j]=0; } for(i=0;i<5;i++){ /*データ点は5点*/ printf("\n(x,y)="); scanf("%lf,%lf",&xx,&yy); A[0][0]+=xx*xx*xx*xx; /*Σx^4*/ A[0][1]+=xx*xx*xx; /*Σx^3*/ A[0][2]+=xx*xx; /*Σx^2*/ A[0][1]=A[1][0]; A[0][2]=A[1][1]=A[2][0]; A[1][2]+=xx; /*Σx*/ A[1][2]=A[2][1]; A[2][2]=n; y[0]+=xx*xx*yy; /*Σx^2y*/ y[1]+=xx*yy; /*Σxy*/ y[2]+=yy; /*Σy*/ } /* save original coefficients */ for(i=0; i<n; i++){ for(j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for(k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for(j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for(k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for(i=0; i<n; i++){ s=0.0; for(j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("\nx(%d)=%f error=%f\n",i, x[i], e[i]); } }

  • 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言語について質問です。

    ソートについて勉強していて、乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力するのはどうやってやるのですか?教えてください。以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。これに処理時間を出力するようにしてもらいたいのですが、どうしたらいいですか?解説とソースファイルをよろしくお願いします。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); return 0; }

  • 座標をランダムに表示させてx座標順にソートするプログラムを考えています

    座標をランダムに表示させてx座標順にソートするプログラムを考えています とりあえず、以下の様に決まった数の座標でソートすることはできたのですが、ランダムにするとなるとどうすればいいのかわかりません。 ------------------------------------------------- #include <stdio.h> int makepoints(int * pn, double * x, double * y){ double xp,yp; int k; int i,j; int n; n = 7; *pn = n; xp = 1; for(k=0;k<n;k++) { xp = xp/2; yp = xp*xp; x[k] = xp; y[k] = yp; } printf("初期座標列:\n"); for(k=0;k<n;k++) { printf("%f_%f\n",x[k],y[k]); } for(j=1;j<n;j++) { for(i=0;i<j;i++) { if(x[i]>x[j]){ xp=x[i];x[i]=x[j];x[j]=xp; yp=y[i];y[i]=y[j];y[j]=yp; } } } printf("整列後の座標列:\n"); for(k=0;k<n;k++) { printf("%d %f %f\n",k ,x[k],y[k]); } return 0; } ------------------------------------------------- なんとなくrand関数を使えばいいのかな、というのはわかるのですが、プログラミングに弱く困っています。 この後のプログラミング教えてくださる方いればよろしくお願いします。

  • C言語について質問です。

    前に質問した訂正です。前の質問に関しては質問の意図が伝わりにくい文章で本当に申し訳ないと思っています。 乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力させることはできたんですが、単位がわかりません。教えてください。 以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); clock_t start , finish; double duration; start = clock(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); finish = clock(); duration = (double)(finish-start) / CLOCKS_PER_SEC; printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); printf ( "%lf\n" , duration ); return 0; } 実行結果: >gcc rand.c bubblesort.c (ソートは省略) count of comparisons : 499500 count of swap : 14848 2.950000 と出力されたのですが読み方?単位が分かりません。教えてください。自分の答えとしては2分55秒だと思うんですが合ってますか?連続質問ですいません。

  • 画像の合成プログラム

    現在、飛行機の羽の左側と、右側の羽で撮った2枚の航空写真を合成するプログラムを作っています。これらの画像には若干のずれがあり、合成するには、左の写真に写っている場所と対応する同じ点を右側の写真から探索する必要があります。今の段階で作っているプログラムでは全ての点を走査することができず、画像の一部だけしか走査されません。 以下のプログラムをどのように変更したら、画像全体を走査できるかアドバイスください。お願いします。 /*対応点の探索*/ for (x = 0; x < 512; x+=25) { for (y= 0; y < 512; y+=25) { for (i = 0; i < 30; i++) { for (j = 0; j < 30; j++) { block1[i][j] = image1[x - 30 / 2 + i][y - 30 / 2 + j]; } } min = 99999; x1 = x*2; if(x1 > 512){ x1 = 512; } y1 = y*2; if(y1 > 512){ y1 = 512; } for (i = 30 / 2; i < x1 - 30 / 2; i++) { for (j = 30 / 2; j < y1- 30 / 2; j++) { sa = 0; for(k = 0; k < 30; k++) { for(l = 0; l < 30; l++) { sa += abs(block1[k][l] - image2[i - 30 / 2 + k][j - 30 / 2 + l]); } } if (min > sa) { min = sa; min_i = i; min_j = j; } } } if(x-15 < min_i && min_i < x+15){ if(y-15 < min_j && min_j < y+15){ printf("File_1の座標点( %d, %d )の対応点は ( %d, %d ) である。\n",y,x, min_j, min_i); } } } } return 0; }

  • C言語について質問です。

    ソートについて勉強していて、乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力させることはできたんですが、単位がわかりません。教えてください。 以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); return 0; } 実行結果: (ソートは省略) count of comparisons : 499500 count of swap : 14848 2.950000 と出力されたのですが読み方?単位が分かりません。教えてください。2分ぐらいかかった気がします。

  • C言語について質問です

    C言語について質問です #include <stdio.h> int main(){ int i,j; double a[8][8],p[8][8],x[8]; for(i=0;i<8;i++){ for(j=0;j<8;j++){ a[i][j]=0.0; } } x[8]={0.182289,0.063801,0.125440,0.097210,0.128485,0.080488,0.189581,0.132706}; p[8][8]={{0,25,24,14,19,5,25,10}, {24,0,50,52,15,40,20,11}, {59,18,0,35,37,24,45,12}, {34,3,28,0,22,51,43,3}, {29,31,21,33,0,22,30,15}, {37,7,75,24,38,0,28,31}, {40,8,32,15,16,21,0,21}, {26,28,28,25,24,18,36,0}}; for(i=0;i<8;i++){ for(j=0;j<8;j++){ a[i][j]=1-(x[i]/(x[i]+x[j]))/(p[i][j]/(p[i][j]+p[j][i])); printf("%f\n",a[i][j]); } } } がコンパイル出来ません。コンパイラはvisual stadio2008です。 ご指摘お願いします。

  • c言語 ファイル出力について

    このようなプログラムを作成しました。 エクセルでファイルを出力したいのですが… ファイルは作成できたものの、内容が書かれていません。 とても困っています↓ 自分の力不足なのでしょうがどなたかお願いします。 #include <stdio.h> #include <process.h> #define S 256 #define I 100 #define J 100 #define K 3 //グループの数 void sum(int u[][J],int N,int n); void sort(int y[],int N,int u[][J],int n); void group(int num[],int u[][J],int N,int n); void passege(int groupm[][J],int groupn,int u[][J],int n,int N); void main (void) { FILE *fp; int N=0,i=0,j=1,kou=0,n; //N:人数 n:問題数 static int u[I][J]; char buf[S]; //ファイルオープン if ((fp=fopen("data_i2_3.csv","r"))==NULL){ printf("Can't open File\n"); exit(1); } // 問題数のカウント fgets(buf,S,fp); N+=1; while(buf[i]!='\n'){ kou=kou++; i+=1; } for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } n=kou/2+1; // レコードの読み込み while (fgets(buf,256,fp)!=NULL){ N+=1; // 文字型から数値型へ変換 j=1; for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } } sum(u,N,n); fclose(fp); } void sum(int u[][J],int N,int n) { static int y[I]; int i,ii; //学習者iの得点の初期化 for(i=0;i<=I;i++) y[i]=0; //学習者iの得点の計算 for(i=1;i<=N;i++){ for(ii=1;ii<=n;ii++){ y[i]+=u[i][ii]; } } sort(y,N,u,n); } void sort(int y[],int N,int u[][J],int n) { int left,right,i,shift,t,v; static int num[I]; //学習者の番号記憶用変数numの初期化 for(i=0;i<=I;i++) num[i]=0; for(i=1;i<=N;i++) num[i]=i; //シェーカーソート left=0; right=N; while (left<right){ for(i=left;i<right;i++){ if(y[i]>y[i+1]){ t=y[i]; v=num[i]; y[i]=y[i+1]; num[i]=num[i+1]; y[i+1]=t; num[i+1]=v; shift=i; } } right=shift; for(i=right;i>left;i--){ if(y[i]<y[i-1]){ t=y[i]; v=num[i]; y[i]=y[i-1]; num[i]=num[i-1]; y[i-1]=t; num[i-1]=v; shift=i; } } left=shift; } group(num,u,N,n); } void group(int num[],int u[][J],int N,int n) { int groupn,i,j,k=1; //groupn:グループの人数 static int groupm[K][I]; //groupm:グループのメンバー groupn=N/K; for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ groupm[i][j]=num[k]; k+=1; } } passege(groupm,groupn,u,n,N); } void passege(int groupm[][J],int groupn,int u[][J],int n,int N) { FILE *f; int i,j,k=0,l,tt; static int t[I]; //各グループの正解率 double p[K][J],pp=0.0; //初期化 for(i=0;i<K;i++){ for(j=0;j<J;j++){ p[i][j]=0; t[i]=0; } } for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ t[k]=groupm[i][j]; k+=1; } } k=0; for(i=0;i<K;i++){ for(j=1;j<=n;j++){ for(l=0;l<groupn;l++){ tt=t[k]; pp=pp+u[tt][j]; k+=1; } p[i][j]=pp/groupn; pp=0.0; if(i==0) k=0; else k=groupn*i; } k=groupn*(i+1); } //ファイル出力 f=fopen("test1.csv","w"); //確認 putchar('\n'); for(i=0;i<K;i++){ for(j=1;j<=n;j++){ printf("%d群の項目%dの正解率は%fです\n",i,j,p[i][j]); } } //ファイルを閉じる fclose(f); }

  • c言語です。

    c言語です。 実行結果 式 3 X1 + 2 X2 + 1 X3 = &g 2 X1 + 5 X2 + 2 X3 = &g 1 X1 + 4 X2 + 1 X3 = &g 解 X1 = 1 X2 = 2 X3 = 3 を 式 3 X1 + 2 X2 + 1 X3 = 10 2 X1 + 5 X2 + 2 X3 = 18 1 X1 + 4 X2 + 1 X3 = 12 解 X1 = 1 X2 = 2 X3 = 3 に直したいのですが&gの所をどのようにしたら10.18.12になりますか? #include <stdio.h> #include <float.h> #define N 3 double A[N][N] = {{3,2,1}, {2,5,2}, {1,4,1}}; double b[N] = { 10, 18, 12 }; void Gauss_J( int, double*, double* ); void main(void) { int i; printf( "%d式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g X1 + %g X2 + %g X3 = &g \n", A[i][0], A[i][1], A[i][2], b[i] ); } printf("解\n"); Gauss_J(N, (double *)A, (double *)b ); printf("X1 = %g \n", b[0]); printf("X2 = %g \n", b[1]); printf("X3 = %g \n", b[2]); } void Gauss_J(int n, double *a, double *b) { int p, i, j,I ; double pivot, c ; for ( p = 0 ; p < n ; p++ ) { pivot = a[ p*n + p ]; for ( i = p ; i < n ; i++ ) { a[ p*n + i ] /= pivot; } b[ p ] /= pivot; for ( I = 0 ; I < n ; I++) { if (I != p) { c = a[ I*n + p]; for ( j = p ; j < n; j++ ) { a[ I*n + j] -= c * a[ p*n + j ]; } b[ I ] -= c * b[ p ]; } } } return ; }