質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

5292閲覧

距離が最小となる2点を計算するプログラムがわからない

langhtorn

総合スコア105

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/05 09:40

編集2020/06/05 12:05

###実現したいこと
・点の個数をはじめに入力し、次に点の座標を入力する→vectorに保存する
・**std::vector<Point>**に入力されている点の集合の中から、距離が最小となる2点を計算する関数を作る
これらを使って距離が最小となる2点を計算するプログラムを作る
###問題点

void closet_pair関数の部分がわからない その関数の呼び出しの部分でエラーがでる。関数の呼び出し方がわからない。

###コード

C++

1//最近点対 2#include<iostream> 3#include<vector> 4#include<cmath> 5 6struct Point 7{ 8 double x; 9 double y; 10 11 void input() 12 { 13 std::cin>>x>>y; 14 } 15 16 void output() 17 { 18 std::cout<<"("<<x<<","<<y<<")\n"; 19 } 20}; 21 22//二点a,bの間の距離を計算する関数 23double distance(Point a,Point b) 24{ 25 double dis; 26 dis=std::sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 27 return dis; 28} 29 30//vectorに保存された配列を出力する関数 31void outout_points(std::vector<Point>& points) 32{ 33 int n=points.size(); 34 int i; 35 for(i=0;i<n;i++){ 36 points[i].output(); 37 } 38} 39 40//vectorに保存されている点の集合から、距離が最小となる2点を計算する関数 41void closet_pair(std::vector<Point>& points, int& idx1, int& idx2,double& dist) //idx1,idx2は最小となる二点の添え字,distは二点間の距離 42{ 43 int i=0; 44 int n=points.size(); 45 int d[100]; //それぞれ2点間の距離を保存する配列 46 int min=0; 47 for(i=0;i<n;i++){ 48 d[i]=distance(points[i],points[i+1]); //二点間の距離の関数呼び出し 49 idx1=i; 50 idx2=i+1; 51 } 52 min=d[0]; //配列dの中から最小値を見つけ出す 53 for(i=0;i<n;i++){ 54 if(min<d[i]){ 55 min=d[i]; 56 } 57 } 58 min=dist; 59 idx1=i; 60 idx2=i+1; 61} 62 63int main() 64{ 65 int n,i; 66 double dist=0; 67 68 std::cout<<"点の個数を入力してください\n"; 69 std::cin>>n; 70 71 std::vector<Point> pts; 72 std::cout<<"n点の座標を入力してください\n"; 73 for(i=0;i<n;i++){ 74 Point p; 75 p.input(); 76 pts.push_back(p); 77 } 78 79 //距離が最小となる二点を計算する関数の呼び出し 80 for(i=0;i<n;i++){ 81 closet_pair(pts,i,i+1,dist); 82 std::cout<<"距離が最小となるのは"<<pts; 83 std::cout<<"その時の二点の添え字は"<<i<<i+1; 84 } 85 return 0; 86}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/06/05 10:14

> std::vector<Point>関数の部分がわからない > その関数の呼び出しの部分でエラーがでる "std::vector<Point>関数の部分"てどこですか?
langhtorn

2020/06/05 10:23

失礼しました。間違っていました
episteme

2020/06/05 12:16

> void closet_pair関数の部分がわからない > その関数の呼び出しの部分でエラーがでる。関数の呼び出し方がわからない。 なんで"関数の呼び出し方がわからない"んですか? その関数の仕様はあなたが決めるんでしょ? わかる仕様にすればいぃやん。
guest

回答2

0

ベストアンサー

※ 質問のキモを無視して勝手に解いた。

C++

1#include <iostream> 2#include <vector> 3#include <utility> 4#include <cmath> 5 6typedef std::pair<double,double> Point; 7 8std::ostream& operator<<(std::ostream& stream, const Point& p) { 9 return stream << '(' << p.first << ',' << p.second << ')'; 10} 11 12std::istream& operator>>(std::istream& stream, Point& p) { 13 return stream >> p.first >> p.second; 14} 15 16inline double distance(const Point& a, const Point& b) { 17 return std::sqrt((a.first - b.first) * (a.first - b.first) + 18 (a.second - b.second) * (a.second - b.second)); 19} 20 21typedef std::pair<Point,Point> PointPair; 22 23inline double distance(const PointPair& pp) { 24 return distance(pp.first, pp.second); 25 26} 27 28std::ostream& operator<<(std::ostream& stream, const PointPair& pp) { 29 return stream << pp.first << " - " << pp.second; 30} 31 32#include <sstream> 33#include <algorithm> 34 35int main() { 36 std::vector<Point> pts; 37 38 // 点群をptsに作る 39 { 40 std::istringstream stream( 41 "0.1 1.2 " 42 "2.3 3.4 " 43 "4.5 5.6 " 44 "6.7 7.8 " 45 "8.9 9.0 "); 46 47 Point pt; 48 while ( stream >> pt ) { 49 pts.push_back(pt); 50 } 51 } 52 53 // 全ての2点の対をptpairsに作る 54 std::vector<PointPair> ptpairs; 55 for ( int i = 0; i < pts.size(); ++i ) { 56 for ( int j = i+1; j < pts.size(); ++j ) { 57 ptpairs.emplace_back(pts[i],pts[j]); 58 } 59 } 60 61 // 2点間距離の昇順でソート 62 std::sort(ptpairs.begin(), ptpairs.end(), 63 [](const PointPair& a, const PointPair& b) { 64 return distance(a) < distance(b); 65 }); 66 67/* 68 // 2点間距離の短いものから順にプリント 69 for ( const auto& pp : ptpairs ) { 70 std::cout << pp << " : " << distance(pp) << std::endl; 71 } 72*/ 73 // 最も近い2点とその距離をプリント 74 std::cout << "closest pair is : " << ptpairs[0] 75 << " : " << distance(ptpairs[0]) << std::endl; 76} 77 78/* 実行結果: 79closest pair is : (6.7,7.8) - (8.9,9) : 2.50599 80*/

投稿2020/06/05 12:52

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

langhtorn

2020/06/06 05:32

ありがとうございます。参考にさせていただきます。
episteme

2020/06/06 12:14

[別件] > void closet_pair(std::vector<Point>& points, int& idx1, int& idx2,double& dist) 距離が最小の点対は複数あり得るので、この関数インタフェースは好きになれない。
guest

0

  1. std::vectorは直接はstd::coutなどに書き出せません。range based forとかで回してください。
  2. lvalue referenceはravlueを束縛できません。今回の例ならconst lvalue referenceにしてください。

投稿2020/06/05 09:58

yumetodo

総合スコア5852

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/06/05 10:47

closet_pair()はidx1,idx2の参照先を変更しているのでconstにできなそうな…?
yumetodo

2020/06/05 15:46

あー、というかそもそもなんでidx1, idx2は参照である必要があるんですかね・・・。普通にintでいいじゃん
langhtorn

2020/06/06 05:33

勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問