C言語でsqrt(a^2+b^2)のテーブル引き

このQ&Aのポイント
  • C言語でsqrt(a^2+b^2)のテーブル引きについて質問しています。
  • 画像処理のプログラムで処理速度が遅いため、テーブル引きを試しています。
  • 具体的なプログラムの一部も示されており、テーブルの生成と使用に関してアドバイスを求めています。
回答を見る
  • ベストアンサー

C言語でsqrt(a^2+b^2)のテーブル引き

プログラムに悩んでいるものです. とある画像処理のプログラムを組んでいるのですが,処理が遅くテーブル引きを組んでいます. 三角関数などはすんなりできたのですが,質題にもある通りsqrt(a^2+b^2)が実現できず,この場を借りて質問させていただきました. 以下にプログラムの一部を示します. ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー void filter(unsigned char* d, short *dx, short *dy, int w, int h) { ///// テーブル生成 ///// static int c_size = 0; // static 次の呼び出しでも値保持 static double *c_sqrt = NULL; // c_size = 255;              // u,v:0~255 c_sqrt = (double *)malloc(sizeof(double)*c_size*c_size); // 領域確保 for(int i=0; i<c_size; ++i){     // 有りえるすべての値を生成 for(int j=0; j<c_size; ++i){ c_sqrt[i*j] = sqrt( (double)(i*i + j*j) ); } } ///// d = sqrt(dx^2 + dy^2) ///// for(int y = 1; y < h-1; ++y){ for(int x = 1; x < w-1; ++x){ double u = (double)dx[y*w+x]; double v = (double)dy[y*w+x]; int val = (int)c_sqrt[ (int)(u*v) ] /4; if (val>255) val=255; d[y*w+x] = val; } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 見てご察し頂ける(?)と思いますが,この関数は何回も呼び出すので,上のほうででテーブル引きしようとしてます. ただ明らかなプログラム経験不足のためかうまくいってません. 個人的にはc_sqrtを別途関数c_sqrt(u,v)にしたほうがよいのかと思ってます. どういうプログラム記述をすれば,このテーブル引きが実現できるでしょうか? ご回答,お力添え,よろしくお願い致します.

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

  • ベストアンサー
回答No.1

何をやりたいのか今ひとつ見えませんが、 c_sqrt[i*j] = sqrt( (double)(i*i + j*j) ); とやってしまうと、 i=2、j=8の時には c_sqrt[16]=√(2*2+8*8)=√68 i=4、j=4の時は c_sqrt[16]=√(4*4+4*4)=√32 ということで、c_sqrt[16]が上書きされてしまいますが、それで良いんでしょうか? sqrt(a^2+b^2) の値引きテーブルを作るならc_sqrt[a][b]のような二次元配列で用意してやるのが常道ではないかと思います。

apollograffitti
質問者

お礼

ご回答ありがとうございます. 何をやりたいのかわからなくてすいませんでした.説明不足だったと思うし,プログラム構成がダメダメだったと思います. ご指摘の通り,二次元配列をつかったら動作しました. これ関連の質問をしているので,お力添え頂けると幸いです. 質問URL:http://okwave.jp/qa/q7112041.html

その他の回答 (4)

回答No.5

1. static double c_sqrt[c_size][c_size];をグローバルに用意する。 static *double にして動的に確保しても良い。が、めんどい。 まずは静的に作れるようにしてから改造してはどうか。 2. 配列テーブルを作る。 void make_csqrt(){ int i,j; for(i = 0; i < c_size; i++) for(j = 0; j < c_size; j++) c_sqrt[i][j] = sqrt((double)(i*i) + (j*j)); } 3. 呼び出す。 double mysqrt(int a,int b){return c_sqrt[i][j];} 備考: もしも、使用する値に特定の偏りがあるようだったら、「ハッシュ法」を使用すればよい。 サンプルは山ほど落ちている。

apollograffitti
質問者

お礼

ご回答ありがとうございます. ハッシュ法などは知らなかったので,勉強になりました. この質問関係の質問をしているので,お力添え頂けると幸いです. 質問URL:http://okwave.jp/qa/q7112041.html

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

2次元配列を使わないなら 宣言 c_sqrt[ROW][COL] 使用 c_sqrt[row][col] なら →c_sqrt[row * COL + col] という感じです。 同様なことは > d[y*w+x] = val; で使用してますよね。 このプログラムなら COL = c_sizeなので c_sqrt[i*c_size + j] = sqrt( (double)(i*i + j*j) ); あと、これ、何回も呼び出すとありますが、そのたびにc_sqrtを確保→計算するようになってます。これではテーブル引きにした意味がありません

apollograffitti
質問者

お礼

ご回答ありがとうございます. ご指摘の通り,テーブル引きの意味がない状態だったので,助かりました. これ関連の質問をしているので,お力添え頂けると幸いです. 質問URL:http://okwave.jp/qa/q7112041.html

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.3

>個人的にはc_sqrtを別途関数c_sqrt(u,v)にしたほうがよいのかと思ってます. 関数名は置いとくとして、ご自分でも思ってらっしゃる通り別途関数にした方がよいかと思います。 テーブルは一次元配列でやろうとするより、素直に二次元配列の方がわかりやすいのではないでしょうか。 >c_sqrt[i*j] = sqrt( (double)(i*i + j*j) ); それもあって、c_sqrtの添え字が i*j とおかしな事されてるようですし。

apollograffitti
質問者

お礼

ご回答ありがとうございます. ご指摘の通り,二次元配列じゃないとおかしな状態だったので,助かりました. これ関連の質問をしているので,お力添え頂けると幸いです. 質問URL:http://okwave.jp/qa/q7112041.html

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

>c_sqrt[i*j] = sqrt( (double)(i*i + j*j) ); c_sqrt[i*j] としているのがまずいと思います。 【理由】 例として、i が 0 の場合を考えてみます。このとき、j がどの値であっても i*j は 0 です。 その結果、せっかく j を 0 から 254 までループさせても、c_sqrt[0] を255回書き換えるだけです。

apollograffitti
質問者

お礼

ご回答ありがとうございます. ご指摘の通り,c_sqrtがまずかったです. これ関連の質問をしているので,お力添え頂けると幸いです. 質問URL:http://okwave.jp/qa/q7112041.html

関連するQ&A

  • C言語でテーブル引きしたら速度が遅くなった

    プログラムに悩んでいるものです. とある画像処理のプログラムを組んでいるのですが,処理が遅くテーブル引きを組んでいます. この前もこの場を借りて質問しsqrt()のテーブル引きは実現したのですが,処理速度が遅くなってしまい原因が分からないので質問させていただきました. 前の質問URL:http://okwave.jp/qa/q7103550.html 前回から修正した現在のプログラムの一部を示します. ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー void filter(unsigned char* d, short *dx, short *dy, int w, int h) { ///// テーブル生成 ///// static int c_size = 0; // static 値を保持 static double c_sqrt[1020][1020]; if(c_size != 1020){ // 初回呼び出しのみ実行 c_size = 1020; for(int i=0; i<c_size; i++){ // 有りえるすべての値を生成 for(int j=0; j<c_size; j++){ c_sqrt[i][j] = sqrt( (double)(i*i + j*j) ); } } } ///// d = sqrt(dx^2 + dy^2) ///// for(int y = 1; y < h-1; ++y){ for(int x = 1; x < w-1; ++x){ double u = (double)dx[y*w+x]; double v = (double)dy[y*w+x]; if(u<0) u=-u; if(v<0) v=-v; int val = (int)c_sqrt[(int)u][(int)v] /4; if(val>255) val=255; d[y*w+x] = val; } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー テーブル引きをしない場合(プログラム省略)はこの関数の処理時間が約9[ms]だったのに対し,上記のプログラムは約15[ms]となってしまいました. どういう風に修正すれば,テーブル引きの効果が出せるでしょうか? 長い文章を最後までお読みいただきありがとうございます. ご回答,よろしくお願い致します.

  • 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+のsqrt

    icpcの過去問(http://www.deqnotes.net/acmicpc/3006/ja)で、答えを #include <cmath> #include <iostream> using namespace std; #define max 1000000 int main(){ //int max = 100; int a,d,n,number[1000010]; for(int i=0;i<max;i++){ number[i] = 1; } number[0]=0;number[1]=0; for(int i=2;i<=sqrt(max)+1;i++){ if(number[i]){ for(int j=i*2;j<max;j=j+i){ number[j] = 0; } } } while(cin >> a >> d >>n,a||d||n){ int count =0; for(int i=a;i<=max;i=i+d){ if(number[i]){count ++; if(count == n){cout << i << endl;break;} } } } } と書いたところ、PKUで Main.cpp F:\temp\11386803.6056\Main.cpp(15) : error C2668: 'sqrt' : ambiguous call to overloaded function math.h(581): could be 'long double sqrt(long double)' math.h(533): or 'float sqrt(float)' math.h(128): or 'double sqrt(double)' while trying to match the argument list '(int)' F:\temp\11386803.6056\Main.cpp(16) : error C2108: subscript is not of integral type というコンパイルエラーがでます。 sqrtの前後で型が違っているのは分かるのですが、具体的にどうなおせばよいかわかりません。

  • c 言語 B tree

    C言語で B-treeを実装するプログラムを書きました。 まだtreeに挿入する関数しか書いておりませんが。。 まず空の根を作ってからそこにどんどん要素を挿入していくのですが、どうも要素が 挿入されていないように思えます。 どこがいけないのか分かる方いらっしゃいませんか? よろしくお願いします。 #include <stdio.h> #define T 10 struct b_tree{ int key[2*T-1]; struct b_tree *node[2*T]; int size; int leaf;//この節点が葉であったら1とする }; void BTreeCreate(void); void BTreeSplitChild(struct b_tree x,int i,struct b_tree y); void BTreeInsert(struct b_tree t,int k); void BTreeInsertNonfull(struct b_tree x,int k); void PrintBtree(struct b_tree x); struct b_tree root; int main (int argc, const char * argv[]) { // insert code here... /*int t;*/ char command; int key; BTreeCreate(); /*scanf("%d",&t);*/ while (1) { scanf("%c %d",&command,&key); if (command=='E') break; if(command=='I') BTreeInsert(root,key);//木にkeyを挿入 } PrintBtree(root); //木を表示 return 0; } void BTreeCreate(void){//空のB-木の生成 struct b_tree x; x.leaf=1; x.size=0; root=x; } void BTreeSplitChild(struct b_tree x,int i,struct b_tree y){ /*B-木における節点の分割をする節点xのi番目の枝の先にある節点yが飽和であった 場合にyをyの中央値で分ける。yの中央値はxの新たなkeyとなりxの枝数は1つ増える*/ int j; struct b_tree z; z.leaf=y.leaf; //zが葉であるかどうかはyが葉であるかどうかに依る z.size=T-1; //また新しくできるxの子zは最小数のkey(T-1)を持たせる for (j=1; j<= T-1; j++) { z.key[j]=y.key[j+1]; //yの中央値よりおおきい値(T-1個)をzに渡す } if(y.leaf==0){ //またyが個をもつ場合は枝もzに渡す for (j=1; j<=T; j++) z.node[j]=y.node[T+j]; } y.size=T-1; //そしてyのサイズも中央値とzに渡した分小さくなる for (j= x.size+1; j>=i+1; j--) { //xにyの中央値を渡すのでx枝の右半分を1つずつ右へずらす x.node[j+1]=x.node[j]; } x.node[i+1]=&z; //i+1番目の枝に新たな子zのポインタを与える for (j=x.size; j>=i; j--) { //値も右へずらす x.key[j+1]=x.key[j]; } x.key[i]=y.key[T]; //xのi番目の値をyの中央値とする。 x.size=x.size+1; //xは1サイズup } void BTreeInsert(struct b_tree t,int k){ int Tsub=T; //条件部にTが使えなかったのでTsubに退避 struct b_tree r,s; r=t; if (r.size == Tsub) { /*根が飽和だった場合を考える新たな親を必要とするため それをsとする。するとsは葉ではなく、sizeは0, そして元々の根rのポインタを与える*/ s.leaf=0; s.size=0; s.node[1]=&r; root=s; BTreeSplitChild(s,1,r); BTreeInsertNonfull(r,k); } else { BTreeInsertNonfull(r,k); } } void BTreeInsertNonfull(struct b_tree x,int k){ /*未飽和の節点xにkを挿入しようと考える。*/ int i; int Tsub=T; if (x.leaf==1) { /*もし、xが葉であれば大小関係を考えて挿入。その際他のkey を右へ1つずつずらす。またxのサイズを1up*/ while (i>=1 && k<x.key[i]) { x.key[i+1]=x.key[i]; i--; } x.key[i+1]=k; x.size++; } else { /*もしxが葉でなければどこの枝をたどればいいのか考える*/ while (i>=1 && k<x.key[i]) { i--; } i++; if ((*x.node[i]).size == 2*Tsub-1) { /*たどる枝の先が飽和であった場合分割する*/ BTreeSplitChild(x, i, *x.node[i]); if (k > x.key[i]) { i++; } } BTreeInsertNonfull(*x.node[i],k);//枝をたどる } } void PrintBtree(struct b_tree x){ printf("abc"); printf("%d",x.leaf);//実行するとleafが1のままなので、数が挿入されていない? int i,l;        if(x.leaf==1){ for (i=1; i<=x.size; i++) { printf("%d def",x.key[i]); } if(l==0)printf("\n"); }else { for (i=1; i<=x.size; i++) { printf("%d ghi",x.key[i]); } if(l==0)printf("\n"); l++; printf(" jkl"); for (i=1; i <= x.size+1; i++) { PrintBtree(*x.node[i]); } } printf("\n"); }

  • c言語 パスカルの三角形

    c言語でパスカルの三角形を出力するプログラムを作りたいのですが、上手くいきません。 何を直せばいいのか教えてください。 #include <stdio.h> #define N 10 int main(void){ int i, j = 1, x, y; int d[N][N]; /* 三角形を作成 */ for (i = 1 ; i < N ; i++){ d[i][0] = 1; while (j <= i - 1){ d[i][j] = d[i-1][j-1] + d[i-1][j]; j ++; } } /* 三角形の表示 */ for (y = 0; y < N; y++) { for (x = 0; x < N-y; x++) printf(" "); for (x = 0; x < y; x++) printf("%3d ", d[x][y]); printf("\n"); } return 0; } 実行結果 -2147417616 2665208 1629976532 1627572249 1629101723 1 1629982744 2665256 2665548 3407923 1629345053 1627571017 0 3538997 1629739051 10 1629345053 2665368 3670071 2665384 1629739040 1627927140 2665244 1628040295 57 1628810863 1629476960 1628602749 2665560 2665304 1629345053 0 1629739040 1629740576 1628992224 2 4411498 1628040588 -2147417600 0 1629476960 1629740664 1629739040 1 267574 0

  • このプログラムについて。

    #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <string.h> #define NVALUE 30 #define MAXSIZE NVALUE struct City{ float x; float y; }; struct Country{ struct City cities[MAXSIZE]; int size; }; struct Itine{ float quality; int route[MAXSIZE]; int noc; }; float plength(struct Itine *tour,struct Country *pcountry) { int i,j; double dy; double dx; float length=0.0; for(i=0;i<tour->noc;i++){ j=i+1; if(j==tour->noc) j=0; struct City &c1=pcountry->cities[tour->route[i]-1]; struct City &c2=pcountry->cities[tour->route[j]-1]; double dx = c1.x-c2.x; double dy = c1.y-c2.y; length+=(float)sqrt(dx*dx+dy*dy); } return length; } なんか間違っていますか? エラーメッセージは、この部分 struct City &c1=pcountry->cities[tour->route[i]-1]; struct City &c2=pcountry->cities[tour->route[j]-1]; double dx = c1.x-c2.x; double dy = c1.y-c2.y; が、 ';'が'型'の前にありません と出ています。Visual Express 2005です。

  • 放射状ブラー C言語で書いたのですが結果がうまくいっていない

    こんばんは! Windows環境,VS2005で放射状ブラーを以下の様に書きましたが、 結果が添付ファイルの様になってしまい、うまくいきません。 コンパイルは通り実行もできるのですが、結果がうまくいっていないのです。(いろんな画像で試しましたが明らかに うまくいっていない気がするのです) 参考にしたのは、 http://www.sbcr.jp/books/download/art.asp?newsid=2198 の " 第3章 エフェクト処理の応用(その1) IPP_Chap3a.zipの中にある list3_14.cです。 又、web上では、http://d.hatena.ne.jp/matsu4512/20090726/1248575190 参考にしました。 以下が私が書いたものです。Input=24bppのrawファイル名 幅、高さが入った構造体です。 プログラミング思想としては、1次元配列で画像を表しています。 #define NN 17 #define NF 8 int Main24bppToRadialBlur(COMMONDATA *Common_Data_Raw) { FILE *fpt; FILE *fpt_output; int width=Common_Data_Raw->width; int height=Common_Data_Raw->height; int i; unsigned char *layer,*img_output; int rr,gg,bb,oo; int x1=0; int y1=0; int x2=3*width-3; int y2=3*width*height-3*width; WCHAR DebugStr[256]; double ox,oy; ox=(double)(x2-x1)/2.0; oy=(double)(y2-y1)/2.0; double dx,dy; dx=(double)x2-ox; dy=(double)y2-oy; double disMAX; disMAX=sqrt(dx*dx+dy*dy); int x,y; int xx,yy; double rate,rad=0,dis,disI; int pat_sum,pat; double ef=30.0; _wfopen_s(&fpt,Common_Data_Raw->filename,L"rb"); layer=(unsigned char*)malloc(3*width*height*sizeof(unsigned char)); //読み込み fread(&layer[0],sizeof(unsigned char),3*width*height,fpt); img_output=(unsigned char*)malloc(3*width*height*sizeof(unsigned char)); //◆画像処理をするスペース for(y=y1;y<=3*width*height-3*width;y+=3*width) { for(x=x1;x<=3*width-3;x+=3) { rr=gg=bb=oo=0; dx=(double)x-ox; dy=(double)y-oy; if(dx!=0.0) { rad=atan(dy/dx); } else { rad=3.14159265/2.0; } //rad+=(3.14159265/2.0); dis=sqrt(dx*dx+dy*dy); rate=ef*dis/disMAX; rate/=((double)NF); pat_sum=0; for(i=0;i<NN;i++) { if(i==NF) { pat=3; } else { pat=1; } disI=(double)(i-NF)*rate; xx=(int)(disI*cos(rad))+x; yy=(int)(disI*sin(rad))+y; rr+=layer[xx+yy] * pat; gg+=layer[xx+yy+1]* pat; bb+=layer[xx+yy+2]* pat; oo+= pat; pat_sum+=pat; } img_output[x+y]=rr/(oo); img_output[x+y+1]=gg/(oo); img_output[x+y+2]=bb/(oo); }//x }//y _wfopen_s(&fpt_output,L"RGBToRadialBlur.raw",L"wb"); fwrite(&img_output[0],sizeof(unsigned char),3*width*height,fpt_output); fclose(fpt); fclose(fpt_output); free(layer); free(img_output);

  • C言語の問題

    以下はC言語の問題です。お教えください。 1000以下の素数を求めるプログラム prog.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 です。 僕の考えでは、 #include <stdio.h> #include <math.h> main(){ int i; int j; int ix; int k; printf("正の整数を入力して下さい: "); scanf("%d",&i); ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++) { if(i%j==0) { k=1; } } if(k==0) { printf("%d は素数です\n",i); } else { printf("%d は素数ではありません\n",i); } となると思うのですが。どうやら違うようです。全然わからないので、正しい答えを教えてください。

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

  • 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); }

専門家に質問してみよう