Cプログラミングで困っています><

このQ&Aのポイント
  • 配列の要素を条件に基づいてグループ化する方法が分かりません。
  • x, y, zの座標値を持つ配列があり、条件を満たすグループを見つけたいです。
  • 求めたい情報は、グループの数と各グループの要素数です。
回答を見る
  • ベストアンサー

Cプログラミングで困っています><

添付した画像のように配列がx>y>zの順に並べ替えられました。実際はもっとデータありますが、省略します。 よくご覧いただけるとうれしいですが、二つのx座標の絶対値差が2以内かつ二つのy座標の絶対値差が2以内かつstate==1かつstate Flag==3であれば、(x,y固定)z方向に伸びる一つのグループ(何個かの球体が構成する直線)と見なします。(それぞれ行のx,y,z座標値は球体それぞれの中心座標である) さらに直線のグループ数とグループを構成する球体数を数えて、出力します。 以上のことですが質問の内容です。 まず配列を作り、例えばx[N]配列を作ったとします,座標の絶対値の差をdiff1,y[N]配列を作り、座標の絶対値差をdiff2と定義し, さらにz[N]配列を作ります。 for(i=0;i<N;i++){ diff1=x[i+1]-x[i]; diff2=y[i+1]-y[i]; } if(diff1<2&&diff2<2&&state==1&&stateFlag==3){ for(i=0;i<N;i++){ printf(“%lf”,x[i]); printf(“%lf”,y[i]); } } でもこの考えだとindexの番号がもともとバラバラなので、配列の番号として理解できないし、表示もちょく座標だけをx,y座標の表示だけして終わり、z方向に伸びるグループ数もわからないし、それぞれのグループを構成する球体数もわかりません。 よろしければ、ご教授いただければ幸いです。

noname#237746
noname#237746

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

  • ベストアンサー
noname#208507
noname#208507
回答No.3

intやdoubleのような基本データ型の配列ではなく、構造体の配列にするとよいでしょう。下記のようにして。 typedef struct Sphere { int index; int status; int flag; double x; double y; double z; } Sphere; Sphere data[N]; i番目の球をdata[i]とすれば、あるグループを構成する i を数えれば、そのグループの球体数が分かります。 しかしグループ数を調べる方法、球体をグループ分けする方法については何とも言えません。もっとグループの定義をはっきりさせないと。例えば球体aとbの中心の距離が2、bとcの距離が2、aとcの距離が4のとき、a,b,cは同じ1つのグループでしょうか? それともaとb、bとcの2グループでしょうか。 それと細かいことですが、画像の配列の並びはx>y>zの順ではなくxの昇順に見えます。

その他の回答 (2)

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

質問の趣旨とはすこし離れますが、クラスタ分析法の考え方を使えば解決できるように思います。 参考 https://www1.doshisha.ac.jp/~mjin/R/28/28.html プログラムを自分で作るのが目的でなければそこで使われているRを使ってみてください。 重心法でできると思いますが、例にあげられているように離れたデータであれば、どの方法でもできると思います。

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

>座標の絶対値の差をdiff1,座標の絶対値差をdiff2と定義し, 本当にそうなっていますか? 現実には、「次の座標と今の座標との差」であって、 絶対値に関する記載はそのコードのどこにも見当たらないように見えます。 絶対値に関する記載は、例えば if ((-2 < diff1 && diff1 < 2) && (-2 < diff2 && diff2 < 2) ... 以下省略 こんな風になりませんか?abs()系の関数あるいはマクロを使ってもいいかもしれません。

関連するQ&A

  • C言語のプログラミングがうまくいきません!

    先日のプログラムを作り直しました。アドバイスのおかげでエラーは減りましたが、まだ完ぺきではないようです。恐らく、elseのところがいけないと思うのですが、どうしたらいいか分かりません。 ご指摘お願いします。 #include <stdio.h> #include <math.h> void main(void) { double x ,y ,z ,error ,menseki ; double ans; printf("x ?"); scanf("%lf", &x); printf("y ?"); scanf("%lf", &y); printf("z ?"); scanf("%lf", &z); if(x<y+z || y<x+z || z<x+y) { ans=(x+y+z)/2; menseki=sqrt(ans*(ans-x)*(ans-y)*(ans-z)); } if(x==y && y==z && z==x) { printf("正三角形です"); printf("面積は%lfです" , menseki); } else if(x==y || y==z || z==x) { printf("二等辺三角形です"); printf("面積は%lfです" , menseki); } else { printf("三角形です"); printf("面積は%lfです" , menseki); } else { printf("error"); } }

  • このプログラミングって正しい?

    与えられた実行列X,Y,Z(配列名x、y、z)から、X-YZを計算して、行列W(配列名w)に格納するメソッドを完成する。 Public static void XminusXY( double[][] x,double[][] y,double[][] z, double[][] w){ double wij; int el=z[0].length, m=y.length, n=z.length; for(int i = 0; i<m; i++){ for(int j = 0; j<n-1; j++){ wij=xij for(int k=0; k<el; k++) wij += -y[i][k]*z[k][j]; w[i][j]=wij; } } }

  • c言語 プログラミング

    以下のプログラムで分からないところがあります。 数式をxpyの形式で入力して、(x,y:整数、p:x,-,*,/のいずれかの演算記号) 答えを表示するというプログラムなのですが、 5行目と9行目にある”-'0'”の意味が分からないので教えてください。 01: int x=0,y=0,z,i;char a[30],p; 02: printf("式を入力してください。:);gets(a); 03: for(i=0;a[i];i++) 04:  if('0'<=a[i] && a[i]<='9') 05:   x=10*x+a[i]-'0'; 06:  else{p=a[i]-'0';break;} 07: for(i++;a[i];i++) 08:  if('0'<=a[i] && a[i]<='9') 09:   y=10*y+a[i]-'0'; 010: switch(p){ 11:  case '+':z=x+y;break; 12:  case '-':z=x+y;break; 13:  case '*':z=x*y;break; 14:  case '/':z=x/y;break; 15:  default:puts("入力エラーです。");return 0; 16: } 17: printf("%d%c%d=%d\n",x,p,y,z); よろしくお願いします。(読みにくかったらメモ帳などにコピペしてください)

  • 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プログラミングの質問なのですが,

    Cプログラミングの質問なのですが, 以下のプログラムで正規乱数を発生させたいのですが,どこがおかしいのでしょうか? fp1のransuuはきちんとtxtで作成されています。 至急お助けください。 #include <stdio.h> #include<stdlib.h> #include<math.h> #define PI 3.141592653589793238 int main (void) { FILE *fp1,*fp2; int i,n; unsigned int x1,x2; double y1,y2; fp1=fopen("ransu.txt","r"); fp2=fopen("seikiransu.txt","w"); for(i=0;i<n;i++) { fscanf(fp1,"%lf",&x1); fscanf(fp1,"%lf",&x2); y1=sqrt(2)*sqrt(-2*log(x1))*cos(2*PI*x2); fprintf(fp2,"%lf\n",y1); } fclose(fp1); fclose(fp2); return 0; }

  • プログラミングのことで困っています。助けて下さい。

    プログラミングの問題がどうしても分からず、本当に困っています。 ・2x+y+3z=13 ・x+3y+2z=13 ・3x+2y+z=10 (解:x=1,y=2,z=3) を掃き出し法で解くプログラミングの問題で、次の(1)~(5)が何が当てはまるかどうしても分からないんです。 #include <stdio.h> #define N 3 /*未知数の個数*/ int main(void) { int i,j,k; double pivot,del; double a[N][n+1]={{2,1,3,13},{1,3,2,13},{3,2,1,10}}; /*係数行列*/ for(i=0;i<N;i++) { (1)____ /*ピボット係数*/ for(j=0;j<N+1;j++) /*ピボット行をピボットで割る*/ (2)____ for(k=0;k<N;k++) /*ピボット列の掃き出し*/ { if((3)____) { del=a[k][i]; for(j=i;j<N+1;j++) (4)____ } } } for(i=0;i<N;i++) (5)____ /*計算結果の表示*/ return 0; } 実行結果は x0=1.00 x1=2.00 x2=3.00 と表示させたいのですが、(1)~(5)の所がどうしても分からず、困っています。どなたか助けて下さい。お願いします。

  • 数学 積分

    (1)I=∬D tan[{π(x^2+y^2)}/4]dxdy D:0≦x^2+y^2≦1 (1)は極座標変換を用いること (2)I=∬D zsin[{π(x^2+y^2+z^2)}/2]dxdydz D:0≦x^2+y^2≦1,0≦z≦1 (2)は円柱座標変換を用いること (3)I=∬D 1/(x^2+y^2+z^2)^(1/2)dxdydz D:1≦x^2+y^2+z^2≦16,x≧0,y≧0,z≧0 (3)は球面座標変換を用いること 回答、よろしくお願いします

  • ラグランジュの補間法のCプログラム

    昨日学校でラグランジュの補間法の問題をC言語のプログラムで解けという課題が出されました しかし、友達と相談してもよくわかりませんでした 課題は以下の問題です sin関数6点、(0.92+0.01x)、x=0,1,2,3,4,5を求めて、ラグランジュの方法でsin(0.923)を計算せよ ちなみに答えは、0.79742です 先生からサンプルのプログラムをもらいました 以下のサンプルプログラムを参考にして解いてくださいと言われたのですが、どうしても解けません すいませんが分かる方、よろしくお願いします #include <stdio.h> #include <math.h> #define N 6 //データ数 double x[N]={ 0.0,1.0,2.0,3.0,3.1,5.0}; //X座標 double y[N]={0.0,1.1,2.5,4.0,4.1,5.0}; //Y座標 double lagrange( double); int main() { double xx,yy; //補間計算 printf("XX\t\tYY\n"); for( xx=0.0; xx<=5.0; xx+=.2 ) { yy = lagrange( xx); printf("%8.2lf\t%8.2lf\n", xx, yy ); } return 0; } //補間サブルーチン double lagrange( double xx ) { double z[N]; double yy=0.0; int i,j; for( i=0; i<N; i++ ) { z[i] = 1.0; //係数計算 for( j=0; j<N; j++ ) if( i!=j ) z[i]*=(xx-x[j])/(x[i]-x[j]); //補間値計算 yy+=z[i]*y[i]; } return yy; } 上記はあくまでサンプルプログラムなので、中に入っている数値は適当です よろしくお願いします

  • 球ベクトルで困ってます;;

    球面 x^2 + y^2 + z^2 =3 が直線 x=y/2=z-1 から切り取る線分の長さを求めよという問題があるのですが、なかなか答えが見えてきません;; 詳しく教えていただけたら幸いです 僕なりに色々考えたのですが、まず球体がありそれを直線が横切ると思っています。 すると、その切り取られた部分は“弧”の形になるのは間違っていませんよね?? その弧の長さを求めようとするには2つの式を連立させて接点(二箇所)を求め、その二点の座標の差が線分の長さになる・・・ と思うのですが結局良く分かりません 詳しい方が居られたら教えを乞いたいのですが 教科書等を読んだのですが球ベクトルについては詳しく触れていないため困っています;; どうか、よろしくお願いします

  • 広義積分 球面座標変換 数学

    (1)~(3)の広義積分を解いてください、お願いします (1) I=∬∫D 1/(x^2+y^2+z^2)^2 dxdydz D:1≦x^2+y^2+z^2,x≧0,y≧0,z≧0 (1≦x^2+y^2+z^2≦a^2,x≧0,y≧0,z≧0として球面座標変換を行う) (2)I=∬D {log(x^2+y^2)}/(x^2+y^2)^(1/2) dxdy D:0≦x^2+y^2≦4,x≧0,y≧0 (3)I=∬D {e^-(x^2+y^2+z^2)}/(x^2+y^2+z^2)^(1/2) D:1≦x^2+y^2+z^2,x≧0,y≧0,z≧0 (4) I=∬[D] 1/(x^2+y^2+z^2)^(1/2)dxdydz D:{(x,y,z)|1≦x^2+y^2+z^2≦16,x≧0,y≧0,z≧0} 球面座標変換を用いること 球面座標変換 x=rcosφsinθ, y=rsinθsinθ, z=rcosθ を用いること D ⇒ E:{(r,θ,φ)| 0≦r≦4, 0≦φ≦π/2, 0≦θ≦π/2} E:{(r,θ,φ)| 1≦r≦4, 0≦φ≦π/2, 0≦θ≦π/2}なぜこうならないのかも教えてください

専門家に質問してみよう