大学のC言語の演習問題がわからないので質問します。
大学のC言語の演習問題がわからないので質問します。
C言語をはじめて5か月くらいの初心者です。
問題内容は
「2 次元平面上の複数の点の座標をキー入力で順に読み込み、入力された複数の座標点の中の任意
の2 点間で最も近い距離とその2 点の座標の組を表示するプログラムを作成せよ。2 点間の距離
D(X1, Y 1,X2, Y 2) は、以下の式で求まるものとする。
D(X1, Y 1,X2, Y 2) ={(X1-X2)^2+(Y1-Y2)^2}^1/2
但し、以下の仕様を満たすこと。
入力する座標点数はマクロ定義(NUMPOINTS)で与え、この定義を変えることで任意の座標点数で正しく動作するようにすること。
キー入力で与える座標(x; y) のx およびy の値は整数(0~100 の範囲)と想定し、下記の実行例のようにカンマ(,)区切りで一つの座標点を一度に入力できるようにすること。
なお、上記仕様において、入力された値が範囲内であるか、入力書式が合っているかどうかはチェックしなくともよい。また、2 組以上の座標点で最短距離が等しくなる場合には、どれか一つだけ表示できればよいものとする。
===============実行例(NUMPOINTS=5 の場合)========================
kadai> ./a.out
No. 1: x,y = ? 2,3 ← 2,3 がキー入力内容。以下同様。
No. 2: x,y = ? 4,8
No. 3: x,y = ? 9,2
No. 4: x,y = ? 4,5
No. 5: x,y = ? 8,4
Minimum distance = 2.236068 : (9,2)-(8,4)
===============実行例終わり=======================================
」
一つの座標点を一度に入力できるようにする方法と最短距離の出し方がわからなくて困っています。
わかる方がいらっしゃれば教えていただけるとありがたいです。
問題内容は
「2 次元平面上の複数の点の座標をキー入力で順に読み込み、入力された複数の座標点の中の任意
の2 点間で最も近い距離とその2 点の座標の組を表示するプログラムを作成せよ。2 点間の距離
D(X1, Y 1,X2, Y 2) は、以下の式で求まるものとする。
D(X1, Y 1,X2, Y 2) ={(X1-X2)^2+(Y1-Y2)^2}^1/2
但し、以下の仕様を満たすこと。
入力する座標点数はマクロ定義(NUMPOINTS)で与え、この定義を変えることで任意の座標点数で正しく動作するようにすること。
キー入力で与える座標(x; y) のx およびy の値は整数(0~100 の範囲)と想定し、下記の実行例のようにカンマ(,)区切りで一つの座標点を一度に入力できるようにすること。
なお、上記仕様において、入力された値が範囲内であるか、入力書式が合っているかどうかはチェックしなくともよい。また、2 組以上の座標点で最短距離が等しくなる場合には、どれか一つだけ表示できればよいものとする。
===============実行例(NUMPOINTS=5 の場合)========================
kadai> ./a.out
No. 1: x,y = ? 2,3 ← 2,3 がキー入力内容。以下同様。
No. 2: x,y = ? 4,8
No. 3: x,y = ? 9,2
No. 4: x,y = ? 4,5
No. 5: x,y = ? 8,4
Minimum distance = 2.236068 : (9,2)-(8,4)
===============実行例終わり=======================================
」
一つの座標点を一度に入力できるようにする方法と最短距離の出し方がわからなくて困っています。
わかる方がいらっしゃれば教えていただけるとありがたいです。
Re: 大学のC言語の演習問題がわからないので質問します。
これは、studentA さんが書きました: 一つの座標点を一度に入力できるようにする方法
scanf("%d,%d",&x,&y);
でいけます。""内のコンマの部分を変えれば、そういう風に入力しないといけない様にもできます。
こういう風にしてみてください。studentA さんが書きました: 最短距離の出し方がわからなくて困っています。
Re: 大学のC言語の演習問題がわからないので質問します。
一つの座標点を一度に入力する方法としてはOKですが、満たすべき仕様的にはscanf内が少し違います。
それだと、
[入力]3 5
としないと、x=3 y=5となってくれません。改行もなくておkです。
それだと、
[入力]3 5
としないと、x=3 y=5となってくれません。改行もなくておkです。
Re: 大学のC言語の演習問題がわからないので質問します。
参考
#include <stdio.h>
#include <math.h>
#define NUMPOINTS (5)
int main(void)
{
int x[NUMPOINTS], y[NUMPOINTS];
int dist_min, from[2], to[2], i, j;
for (i = 0; i < NUMPOINTS; i++) {
printf("No.%d : x,y = ? ", i + 1), scanf("%d,%d", &x[i], &y[i]);
}
for (dist_min = 100000000, i = 0; i < NUMPOINTS - 1; i++) {
for (j = i + 1; j < NUMPOINTS; j++) {
int xx = x[i] - x[j], yy = y[i] - y[j], w;
if ((w = xx * xx + yy * yy) < dist_min) {
dist_min = w;
from[0] = x[i], from[1] = y[i];
to[0] = x[j], to[1] = y[j];
}
}
}
printf("Minimum distance = %f : (%d,%d)-(%d,%d)\n",
sqrt((double) dist_min), from[0], from[1], to[0], to[1]);
return 0;
}
Re: 大学のC言語の演習問題がわからないので質問します。
少し違います。scanfは「ユーザーが""内の形式通りに入力した時に、%dの位置にあたる数字(だけではないけれど)を変数に入力してくれる」のような意味でとらえてください。
なので、仕様通りにx値とy値の間にコンマを入れるようにしなければならない場合、"%d,%d"のようにする必要があります。
例えば、scanf("%da%d",&x,&y);とすると、4a5と入力することでxに4,yに5が入るはずです。いろいろやって試してみましょう。
student A さんが書きました:また最短距離についてですが、すべての座標点i,jの意味がよくわからないので説明をお願いします。
上記の方法で事前に入力した座標点がありますね。
それは配列に格納されていますよね。
x[0]=3, y[0]=1
x[1]=4, y[1]=2
x[2]=5, y[2]=6
x[3]=6, y[3]=2
こんな感じで!
同じ配列番号の(x,y)で一つの点を示すようになっていると思いますが、
iとかjでその配列番号を選ぶわけです。
たとえば上の数字を使として、i=2, j=3なら、
iは(5,6) jは(6,2)の座標点を指すのです。
Re: 大学のC言語の演習問題がわからないので質問します。
あ、i==jでは「iとjが同じ時」という意味になってしまいますよ!
あと、Dの求める式も良いところまでいってますが、少しだけ違うようです。
>D(X1, Y 1,X2, Y 2) ={(X1-X2)^2+(Y1-Y2)^2}^1/2
これと見比べてください。
Re: 大学のC言語の演習問題がわからないので質問します。
そうでした。i!=jですね。
Dは平方根ですよね
これでどうでしょうか↓
Dは平方根ですよね
これでどうでしょうか↓
#include<stdio.h>
#include<math.h>
main(){
#define NUMPOINTS 5
int i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D,Minimum distance=99999999999
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d%d",&x[i],&y[i])
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D)
if(D<Minimum distance){
Minimum distance=D
}
Re: 大学のC言語の演習問題がわからないので質問します。
なかなかいい感じに仕上がってきましたね。
ですが、変数名にスペースを入れることはできないのでそれを修正してください。
そうすれば動くのではないかと思います。
完成したら色々補足入れますね。
【追記】
と、思ったら、 の、
・for文が閉じていません。
・scanfに;がありません。
【さらに追記】
組み合わせ(i,j)の保存もしっかりとね!
【さらにさらに追記】
変数定義時に;がないところがあります。
【さらにさらにさらに追記】
scanf("%d%d",&x,&y) の"%d%d"は"%d,%d"に直してください。理由は上記です。
ですが、変数名にスペースを入れることはできないのでそれを修正してください。
そうすれば動くのではないかと思います。
完成したら色々補足入れますね。
【追記】
と、思ったら、 の、
・for文が閉じていません。
・scanfに;がありません。
【さらに追記】
組み合わせ(i,j)の保存もしっかりとね!
【さらにさらに追記】
変数定義時に;がないところがあります。
【さらにさらにさらに追記】
scanf("%d%d",&x,&y) の"%d%d"は"%d,%d"に直してください。理由は上記です。
Re: 大学のC言語の演習問題がわからないので質問します。
ミスが多くて申し訳ないです。
組み合わせ(i,j)の保存とはどういうことでしょうか?
組み合わせ(i,j)の保存とはどういうことでしょうか?
#include<stdio.h>
#include<math.h>
main(){
#define NUMPOINTS 5
int i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D,Minimumdistance=99999999999;
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d,%d",&x[i],&y[i]);
}
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D);
if(D<Minimumdistance){
Minimumdistance=D;
}
}
}
}
}
Re: 大学のC言語の演習問題がわからないので質問します。
課題でstudent A さんが書きました:組み合わせ(i,j)の保存とはどういうことでしょうか?
>2 点間で最も近い距離とその2 点の座標の組
を出力するよう求められています。
「最も近い距離」はMinimumdistanceを使って出力すればいいとして、では「2 点の座標の組」はどうしましょう?
というのがポイントです。
ここで、最短距離が更新された時にそのiとjの値をなにかの変数に保存しておけば、そこから、2点両方の座標が参照できます。
そうすれば「2 点の座標の組」の出力も可能ですよね。
Re: 大学のC言語の演習問題がわからないので質問します。
なるほど最短距離になったときのi,jの値を保存しておくということですね。
こんな感じでしょうか↓
こんな感じでしょうか↓
#include<stdio.h>
#include<math.h>
main(){
#define NUMPOINTS 5
int i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D,Minimumdistance=99999999999;
int save1[2],save2[2];
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d,%d",&x[i],&y[i]);
}
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D);
if(D<Minimumdistance){
Minimumdistance=D;
save1[0]=x[i];
save1[1]=y[i];
save2[0]=x[j];
save2[1]=y[j];
}
}
}
}
printf((%d,%d)-(%d,%d)\n",save1[0],save1[1],save2[0],save2[1]);
}
Re: 大学のC言語の演習問題がわからないので質問します。
結果出力時にその最短距離も出力するようにすればいいと思います。
正常に動きましたか?
【追記】
main()のところをint main()に修正してください。
それに伴いmain関数の最後にreturn 0;を入れることをお忘れなくです。
正常に動きましたか?
【追記】
main()のところをint main()に修正してください。
それに伴いmain関数の最後にreturn 0;を入れることをお忘れなくです。
最後に編集したユーザー Priest on 2013年2月19日(火) 22:38 [ 編集 1 回目 ]
Re: 大学のC言語の演習問題がわからないので質問します。
例えば、1番目と4番目を比較したら、
4番目と1番目を比較する必要はないですね。
5×5の正方形すべてを比較対象にするよりも、
私が先に投稿したように5×5行列の上半分(あるいは下半分)だけを
比較対象にする方が、実行時間の点で少しでも有利に働くと思います。
4番目と1番目を比較する必要はないですね。
5×5の正方形すべてを比較対象にするよりも、
私が先に投稿したように5×5行列の上半分(あるいは下半分)だけを
比較対象にする方が、実行時間の点で少しでも有利に働くと思います。
Re: 大学のC言語の演習問題がわからないので質問します。
<<初級者さん
なるほど比較の数が半分で済むということですね。そちらのやりかたでもやってみます
<<priestさん
15行目にエラーが出ます
なるほど比較の数が半分で済むということですね。そちらのやりかたでもやってみます
<<priestさん
15行目にエラーが出ます
#include<stdio.h>
#include<math.h>
int main(){
#define NUMPOINTS 5
int j,i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D;
double Minimumdistance=99999999999;
int save1[2],save2[2];
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d,%d",&x[i],&y[i]);
}
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D);
if(D<Minimumdistance){
Minimumdistance=D;
save1[0]=x[i];
save1[1]=y[i];
save2[0]=x[j];
save2[1]=y[j];
}
}
}
}
printf(“Minimumdistance=%f(%d,%d)-(%d,%d)\n",Minimumdistance ,save1[0],save1[1],save2[0],save2[1]);
return 0
}
Re: 大学のC言語の演習問題がわからないので質問します。
エラーが出た時にはそのエラーコードを貼り付けてください。
とりあえず、32行目のprintfの"が全角です。
return文に;がないです。
初級者さんの手法だと今のif(i!=j)の比較がいらなくなるのもでかいですね。
ただこっちのほうが直感的かなぁと思ったのでこうしました。
とりあえず、32行目のprintfの"が全角です。
return文に;がないです。
初級者さんの手法だと今のif(i!=j)の比較がいらなくなるのもでかいですね。
ただこっちのほうが直感的かなぁと思ったのでこうしました。
Re: 大学のC言語の演習問題がわからないので質問します。
申し訳ないです。エラーメッセージはり忘れました
エラーは15行目にexpected ' ; ' before ' } ' token と出ます。
またコンパイルのときにーlmをつける必要はありますか?
エラーは15行目にexpected ' ; ' before ' } ' token と出ます。
またコンパイルのときにーlmをつける必要はありますか?
#include<stdio.h>
#include<math.h>
int main(){
#define NUMPOINTS 5
int j,i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D;
double Minimumdistance=99999999999;
int save1[2],save2[2];
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d,%d",&x[i],&y[i]);
}
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D);
if(D<Minimumdistance){
Minimumdistance=D;
save1[0]=x[i];
save1[1]=y[i];
save2[0]=x[j];
save2[1]=y[j];
}
}
}
}
printf("Minimumdistance=%f(%d,%d)-(%d,%d)\n",Minimumdistance ,save1[0],save1[1],save2[0],save2[1]);
return 0;
}
Re: 大学のC言語の演習問題がわからないので質問します。
-lmはつける必要はありません。
というか、こっちでコンパイルしてみたらできましたよ?
実行結果は以下のようになりました。
どこか全角になっていたりしませんか?
というか、こっちでコンパイルしてみたらできましたよ?
実行結果は以下のようになりました。
No.0: x,y=?3,4
No.1: x,y=?5,6
No.2: x,y=?3,2
No.3: x,y=?1,1
No.4: x,y=?5,7
sqrt(8.000000)=2.828427
sqrt(4.000000)=2.000000
sqrt(13.000000)=3.605551
sqrt(13.000000)=3.605551
sqrt(8.000000)=2.828427
sqrt(20.000000)=4.472136
sqrt(41.000000)=6.403124
sqrt(1.000000)=1.000000
sqrt(4.000000)=2.000000
sqrt(20.000000)=4.472136
sqrt(5.000000)=2.236068
sqrt(29.000000)=5.385165
sqrt(13.000000)=3.605551
sqrt(41.000000)=6.403124
sqrt(5.000000)=2.236068
sqrt(52.000000)=7.211103
sqrt(13.000000)=3.605551
sqrt(1.000000)=1.000000
sqrt(29.000000)=5.385165
sqrt(52.000000)=7.211103
Minimumdistance=1.000000(5,6)-(5,7)
Re: 大学のC言語の演習問題がわからないので質問します。
全角になっていました。
しかし今度はIn function 'main': mondai.c:undefined reference to 'sqrt' collect2: ldはステータス 1で終了しましたとでます
しかし今度はIn function 'main': mondai.c:undefined reference to 'sqrt' collect2: ldはステータス 1で終了しましたとでます
Re: 大学のC言語の演習問題がわからないので質問します。
#include<math.h>
はソースコードに入っていますか?
はソースコードに入っていますか?
Re: 大学のC言語の演習問題がわからないので質問します。
申し訳ないです。
先ほどlmいらないといいましたが、必要かもです。
先ほどlmいらないといいましたが、必要かもです。
Re: 大学のC言語の演習問題がわからないので質問します。
おめでとうございます!
補足入れますね。
まず、#defineは関数外に出しておいた方がいいと思います。
調べたところ、#defineは関数の中にあっても、その#defineの下全てに反映されるようです。
ともあれ、何かをインクルードした後に#defineはまとめられた方がみやすいでしょう。
次にこれです。 実は何とかの何乗をやるのに役立つ関数があります。
それはpow(a,b);でa^bとなります。なので、 と地味にスマートにかけますよ。
で、さらにhypodhypotという関数を使うと、↑の計算を勝手にやってくれます。 ここまで短くなりました。
あと、こういった場で質問する時は、インデントをつけてくださいね。
インデントは{}で囲まれた部分を半角スペース4つ分ずらすことです。
みたいな感じになります。
こうするとどこまでがif分の中に入っているのかとかが分かりやすくなります。
課題を提出する際もこうしておくといいでしょう。
以上です!お疲れさまでした!
補足入れますね。
まず、#defineは関数外に出しておいた方がいいと思います。
調べたところ、#defineは関数の中にあっても、その#defineの下全てに反映されるようです。
ともあれ、何かをインクルードした後に#defineはまとめられた方がみやすいでしょう。
次にこれです。 実は何とかの何乗をやるのに役立つ関数があります。
それはpow(a,b);でa^bとなります。なので、 と地味にスマートにかけますよ。
で、さらにhypodhypotという関数を使うと、↑の計算を勝手にやってくれます。 ここまで短くなりました。
あと、こういった場で質問する時は、インデントをつけてくださいね。
インデントは{}で囲まれた部分を半角スペース4つ分ずらすことです。
#include<stdio.h>
#include<math.h>
#define NUMPOINTS 5
int main(){
int j,i;
int x[NUMPOINTS];
int y[NUMPOINTS];
double value,D;
double Minimumdistance=99999999999;
int save1[2],save2[2];
for(i=0;i<NUMPOINTS;i++){
printf("No.%d: x,y=?",i);
scanf("%d,%d",&x[i],&y[i]);
}
for(i=0;i<NUMPOINTS;i++){
for(j=0;j<NUMPOINTS;j++){
if(i!=j){
value=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
D=sqrt(value);
printf("sqrt(%f)=%f/n",value,D);
if(D<Minimumdistance){
Minimumdistance=D;
save1[0]=x[i];
save1[1]=y[i];
save2[0]=x[j];
save2[1]=y[j];
}
}
}
printf("Minimumdistance=%f(%d,%d)-(%d,%d)\n",Minimumdistance ,save1[0],save1[1],save2[0],save2[1]);
return 0;
}
こうするとどこまでがif分の中に入っているのかとかが分かりやすくなります。
課題を提出する際もこうしておくといいでしょう。
以上です!お疲れさまでした!
最後に編集したユーザー Priest on 2013年2月20日(水) 00:14 [ 編集 3 回目 ]
Re: 大学のC言語の演習問題がわからないので質問します。
何度もすいません
できたと思いましたがMinimumdistanceのあとの座標の数字がおかしいことに気づきました
できたと思いましたがMinimumdistanceのあとの座標の数字がおかしいことに気づきました
Re: 大学のC言語の演習問題がわからないので質問します。
おっと、そのおかしいと思った結果を貼り付けてみてください。
Re: 大学のC言語の演習問題がわからないので質問します。
やったね!おつかれさまでした!
Re: 大学のC言語の演習問題がわからないので質問します。
すっごく今更感ですが、距離の比較自体は平方根をとる前の段階で(つまり距離の2乗の段階で)十分ですよ。
x^2>y^2かつx,y>0 ⇒ x > yですから。
そうやって求めた距離の2乗のうち一番小さいものを選んで、最後に平方根をとって表示すれば十分です
x^2>y^2かつx,y>0 ⇒ x > yですから。
そうやって求めた距離の2乗のうち一番小さいものを選んで、最後に平方根をとって表示すれば十分です