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

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

新規登録して質問してみよう
ただいま回答率
85.35%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

C++

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

1回答

1864閲覧

C++で二次元配列のソート

aiouongaku

総合スコア1

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

C++

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/07/20 04:23

編集2020/07/21 06:50

実現したいこと

C++で作成しています。
PCD形式の点群データを配列に格納し,class内のデータ(二次元配列)でソートしたいです。(伝え方が難しい)
垂直角のソートは出来ているのですが,水平角のソート方法がわかりません.
解決策がありましたら教えていただきたいです.

該当のソースコード

C++

1/*Point.h*/ 2 3class Point{ 4public: 5double x,y,z;      //点のx,y,z座標値 6double hori_angle;   //xy平面上でのx軸と点の角度(以下、水平角) 7double vertical_angle; //xy平面と点のなす角度(以下、垂直角) 8Point(); 9};

C++

1/*Point.cpp*/ 2 3#include "Point.h" 4Point::Point(){ 5}

C++

1/*main.cpp*/ 2 3using namespace pcl; 4PointCloud<pcl::PointXYZI>::Ptr input(new pal::PointCloud<pcl::PointXYZI>);//入力点群 5 6int hori = 7;   //水平方向データ数 7int vertical = 4; //垂直方向データ数 8 9Void main(void){ 10 for(int i = 0; i < hori; i++){ 11 for(int j = 0; j < vertical; j++){ 12 /*点群データを配列に格納*/ 13   a_point[j][i].x = input->points[i*4+j].x; 14 a_point[j][i].y = input->points[i*4+j].y; 15 a_point[j][i].z = input->points[i*4+j].z; 16 17 /*垂直角・水平角を求める*/ 18 a_point[j][i].hori_angle = atan2(a_point[j][i].y,a_point[j][i].x); 19 a_point[j][i].vertical_angle = /*計算式*/; 20 //↑↑↑それぞれ[rad]から[deg]に変換,水平角は-180[deg]~180[deg]が,垂直角は-10[deg]~30[deg]が得られる 21 } 22 } 23 /*並べ替える*/ 24 Sort(); 25} 26 27Void Sort(void){ 28 29   /*水平角を-180[deg]から 昇順に並べた後 ,同じ水平角内で垂直角を-10[deg]から昇順に並べたい. 30 理想形は以下のようになる.(このような表し方が正しいのかは多目に見て欲しいです) 31 32    a_point[hori][vertical].hori_angle 33 = [-180,-180,-180,-180,-180,-180,-180], 34 [-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ], 35 [0 ,0 ,0 ,0 ,0 ,0 ,0 ], 36 [180 ,180 ,180 ,180 ,180 ,180 ,180 ]; 37 38 a_point[hori][vertical].vertical_angle 39 = [-10,0,10,15,20,25,30], 40 [-10,0,10,15,20,25,30], 41 [-10,0,10,15,20,25,30], 42 [-10,0,10,15,20,25,30]; 43 44*/ 45}

###入力(ソート前)データ

a_point[ hori ][ vertical ].hori_angle =
[-180,-180,0 ,-30 ,-30 ,0 ,-180],
[-30 ,0 ,0 ,-30 ,-180,180 ,0 ],
[0 ,0 ,-180,180 ,-180,-30 ,180 ],
[-180,-30 ,180 ,180 ,-30 ,180 ,180 ];

a_point[ hori ][ vertical ].vertical_angle =
[-10 ,10 ,-10 ,0 ,15 ,10 ,30 ],
[-10 ,30 ,20 ,25 ,15 ,10 ,0 ],
[15 ,25 ,0 ,25 ,25 ,20 ,30 ],
[20 ,10 ,-10 ,20 ,30 ,0 ,15 ];

###1.水平角ソート後
a_point[ hori ][ vertical ].hori_angle =
[-180,-180,-180,-180,-180,-180,-180],
[-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ],
[0 ,0 ,0 ,0 ,0 ,0 ,0 ],
[180 ,180 ,180 ,180 ,180 ,180 ,180 ];

↓↓↓こんな感じなのかな?と予想↓↓↓
a_point[ hori ][ vertical ].vertical_angle =
[(-10 ,20 ),10 ,0 ,(15 ,25 ),30 ],
[-10 ,10 ,0 ,(25 ,15 ),30 ,20 ],
[15 ,(30 ,25 ),(-10,20 ),10 ,0 ],
[-10 ,(25 ,20 ),(10 ,0 ),(30 ,15 )];

()内は順不同.あくまで予想です.

###2.垂直角ソート後

C++

1/*垂直角ソートプログラム(Sort関数内に存在)*/ 2 3double temp1, temp2, temp3, temp4, temp5; 4 5for(int i = 0; i < hori; i++){ 6 for(int j = 0; j < vertical; j++){ 7 for(int k = j+1; k < vertival; k++){ 8 temp1 = a_point[j][i].x; 9 temp2 = a_point[j][i].y; 10 temp3 = a_point[j][i].z; 11 temp4 = a_point[j][i].hori_angle; 12 temp5 = a_point[j][i].vertical_angle; 13 14 a_point[j][i].x = a_point[k][i].x; 15 a_point[j][i].y = a_point[k][I].y; 16 a_point[j][i].z = a_point[k][I].z; 17 a_point[j][i].hori_angle = a_point[k][i].hori_angle; 18 a_point[j][i].vertical_angle = a_point[k][i].vertical_angle; 19 20 a_point[k][i].x = temp1; 21 a_point[k][i].y = temp2; 22 a_point[k][i].z = temp3; 23 a_point[k][i].hori_angle = temp4; 24 a_point[k][i].vertical_angle = temp5; 25 } 26  } 27} 28

<結果>
a_point[ hori ][ vertical ].hori_angle =
[-180,-180,-180,-180,-180,-180,-180],
[-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ],
[0 ,0 ,0 ,0 ,0 ,0 ,0 ],
[180 ,180 ,180 ,180 ,180 ,180 ,180 ];

a_point[hori][vertical].vertical_angle =
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30];

###現状
垂直角のソートのみ取り入れているので,以下のような結果が得られています.

a_point[ hori ][ vertical ].hori_angle =
[-180,0,-30,-180,0,-30,-180],
[-30,0,180,-180,-180,0,-30,0],
[-180,0,-30,(0,180,-180),0],
[180,180,-30,(180,180),-180,-30]

a_point[hori][vertical].vertical_angle =
[-10,-10,0,10,10,15,30],
[-10,0,10,15,20,25,30],
[0,15,20,25,25,25,30],
[-10,0,10,15,20,20,30];

補足情報

a_point[][]はpoint classのことを表しています.
垂直角のソートは出来ているのですが,水平角のソート方法がわかりません.

更に詳しく編集し直しました.

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

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

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

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

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

episteme

2020/07/20 04:26

つまり 何を/どんな 順で並べるんですか? 比較/交換規則を明らかにしてください。
guest

回答1

0

上記<結果>が得られればいいのなら:

C++

1#include <iostream> 2#include <algorithm> 3 4int main() { 5 int data[5][7] = { 6 { 0, 0, 0, 1, 2, 0, 0 }, 7 { 1, 3, 2, 1, 0, 4, 3 }, 8 { 0, 1, 1, 4, 1, 1, 4 }, 9 { 2, 2, 4, 3, 2, 3, 2 }, 10 { 2, 3, 4, 4, 3, 3, 4 }, 11 }; 12 std::sort((int*)data, (int*)data+5*7); 13 14 // できたかな? 15 for ( int row = 0; row < 5; ++row ) { 16 for ( int col = 0; col < 7; ++col ) { 17 std::cout << data[row][col] << ' '; 18 } 19 std::cout << std::endl; 20 } 21}

[追記] 第二版

C++

1#include <iostream> 2#include <algorithm> 3 4class point { 5public: 6 int angle; 7 point(int a) : angle(a) {}; 8}; 9 10int main() { 11 point data[5][7] = { 12 { 0, 0, 0, 1, 2, 0, 0 }, 13 { 1, 3, 2, 1, 0, 4, 3 }, 14 { 0, 1, 1, 4, 1, 1, 4 }, 15 { 2, 2, 4, 3, 2, 3, 2 }, 16 { 2, 3, 4, 4, 3, 3, 4 }, 17 }; 18 std::sort((point*)data, (point*)data+5*7, 19 [](const point& a, const point& b) { return a.angle < b.angle; }); 20 21 // できたかな? 22 for ( int row = 0; row < 5; ++row ) { 23 for ( int col = 0; col < 7; ++col ) { 24 std::cout << data[row][col].angle << ' '; 25 } 26 std::cout << std::endl; 27 } 28}

[追記] 第三版

C++

1#include <iostream> 2#include <algorithm> 3 4class point { 5public: 6 double hori_angle; //xy平面上でのx軸と点の角度(以下、水平角) 7 double vertical_angle; //xy平面と点のなす角度(以下、垂直角) 8}; 9 10int main() { 11 point data[5][7] = { ... }; 12 std::sort((point*)data, (point*)data+5*7, 13 [](const point& a, const point& b) { 14 return a.hori_angle < b.hori_angle || 15 (!(b.hori_angle < a.hori_angle ) && a.vertical_angle < b.vertical_angle); 16 }); 17 18 // できたかな? 19 for ( int row = 0; row < 5; ++row ) { 20 for ( int col = 0; col < 7; ++col ) { 21 std::cout << data[row][col].hori_ange << ',' << data[row][col].vertical_angle << ' '; 22 } 23 std::cout << std::endl; 24 } 25}

投稿2020/07/20 04:47

編集2020/07/21 08:02
episteme

総合スコア16612

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

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

aiouongaku

2020/07/20 05:06

回答ありがとうございます。 pointクラスに他にもデータが存在しており、その中でもangleの数値が質問での<入力>としてこの値をソートしたいと考えています。記載不足でした。 回答いただいた方法で今やって見ましたが私が思っているようにはいきませんでした。。
episteme

2020/07/20 05:12

追記しました。これがあなたのやりたいことか自信ないけど。
yumetodo

2020/07/20 13:27

そもそもpointクラスの比較演算子はどうオーバーロードされているんだ・・・
aiouongaku

2020/07/21 06:24

質問を更に詳しく追記しました. C++ 初心者なのでこの情報で伝わるか不安ですが,宜しくお願いい致します.
episteme

2020/07/21 06:27

いやだから比較/交換規則を明らかにしろと。例示ではなく。
aiouongaku

2020/07/21 06:59

「水平角を-180[deg]から昇順に並べた後、同じ水平角内で垂直角を-10[deg]から昇順に並べたい。」 これでは不十分ですか? これ以上詳しくどうすればわからないので並び替え方法がわかりません。 どうすればいいのか自分で分かっていればプログラム組むことはできています。。すみません。
episteme

2020/07/21 07:03

よーするに、比較キーがふたつあり、 - key1の大小で要素の大小が決まる。 - key1が等しいならkey2で大小が決まる。 ですか? 二次元配列であるか否かは関係なく、一次元とみなしても構わないってことですか?
aiouongaku

2020/07/21 07:19

key1=水平方向・key2=垂直方向 を指しているのであれば、その考えで大丈夫ですね。 一次元と見なしても大丈夫かも?です。
episteme

2020/07/21 07:33

追記しました。
aiouongaku

2020/07/21 08:01

ありがとうございます。 もう少しでできそうな感じはしているのですが、data[][]の中にはどの数値を格納すれば良いのでしょうか? 私の該当のソースコードに記載の通り、水平方向と垂直方向では同じクラス内ではありますが別の配列(表現が正しくないかも)にデータが格納されているため、何をdata[][]に設定すれば良いのかわかりませんでした。
episteme

2020/07/21 08:32 編集

いやそれは僕が決めることじゃありませんよ。ソートしたい要素群を突っ込んでください。 僕のコードは、data[][]を一次元(のリニアな)配列とみなしてソートしてるだけです。
yumetodo

2020/07/21 09:36

ところで質問文の「垂直角ソート後」に大量の代入文が見えますが、そもそもstd::swap使いましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問