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

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

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

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

Q&A

解決済

3回答

2981閲覧

C++ 二次配列のソートの仕方について

Usagi365m

総合スコア16

C++

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

0グッド

0クリップ

投稿2020/07/11 20:51

編集2020/07/12 11:36

入力
2 2
2 3
3 1
出力
3 1
2 3
2 2

一行目の数値が優先され上に表示されます、同じ場合は二行目の数値が優先され上に表示されます。
このような処理をするときはどのようなコードを書けばいいでしょうか?
入力を受け付けるコードを打ち込んでから手が止まってしまいました。

追加文:やったことはsort()qsort()などの標準ライブラリの使用です。
しかし、一行目は入れ替えられるが、一行目をキーにして、二行目を呼び出し、入れ替えるにはどうしたらいいのか、アルゴリズムが思いつきません。

    //参考にしたサイト
https://codezine.jp/article/detail/6020
http://stlalv.la.coocan.jp/sort.html

追加文:基礎を学ぶために、標準ライブラリを使って処理をしたいです。構造体の一次配列でもOkです。

ご回答おねがいします!

C++

1#include <iostream> 2#include <algorithm> 3#include <vector> 4using namespace std; 5int main(void){ 6 int num[100][100]; 7 int n; 8 cin >> n; 9 for(int i = 0;i < n;i++){ 10 cin >> num[i][0] >> num[i][1]; 11 } 12 /* 13 int num[3][2] = {{ 2, 2 } 14 { 2, 3 } 15 { 3, 1 }} 16 */ 17 //sortやqsortを使ってみましたが、うまくいきませんでした 18 //sort(num[0],num[0] + n,greater<int>());これだとうまく行かない 19 //一行目を入れ替えて、同じになった数値をキーにして、二行目を比較して、入れ替える。 20     //といった部分が思いつきません。 21 22 for(int i = 0;i < n;i++){ 23 cout << num[i][0] << " " << num[i][1] << endl; 24 } 25 return 0; 26}

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

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

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

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

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

cateye

2020/07/11 21:04 編集

未完であっても良いので、ソースを追記して下さい。
kazuma-s

2020/07/11 23:39

行を降順(大きいものから小さいものへ)にソートするんですよね。 1列目の数値でソートし、同じ場合は 2列目でソートする。 1次元配列のソートはできますか? ソートには何を使いますか? 選択ソート? バブルソート? 挿入ソート? クイックソート? あるいはライブラリ関数の qsortを使う? 質問を編集して、ソートの条件を追加訂正してください。
bjnes

2020/07/12 10:34 編集

データの持ち方は2次元配列が本当に正しいのですか? 構造体X,yの1次元配列のほうが趣旨にあっていませんか?
Usagi365m

2020/07/12 11:07

次の出題が二次配列のソートが必要のようで、この段階から学習しておきたいと思い質問いたしました。 構造体の一次配列のソートのほうも、時間がありましたらやり方をご教示いただければ幸いです。 まだ初心者で、明快な質問ができず申し訳ありません。ご理解のほど、ご回答をおねがいいたします。
bboydaisuke

2020/07/12 11:49

> 次の出題が二次配列のソートが必要のようで、この段階から学習しておきたいと思い質問いたしました。 予習なんかしなくていいから復習をして、授業をしっかり聞いてわからないことは授業中に質問した方がいいと思う。
Usagi365m

2020/07/13 00:03

アドバイスありがとうございます。今回の問題はweb上の出題(スキルチェック)であり、残念なことにこの問題に対する回答及び、解説がありません。C++は完全独学です。 ソートに関するものはインターネットサーフィンで何かしらのヒントは得たものの、かゆいところに手が届かないものでした。 今回、自分ではわからないところをこの場を借りてを質問した経緯です。 まだ学習から一週間しか立っていないためC++を使い慣れるまではみなさまに多大なご迷惑をおかけすると思いますが、何卒よろしくおねがいします。
bboydaisuke

2020/07/13 00:10

> みなさまに多大なご迷惑をおかけすると思います いやいや、勘弁してよ(笑 実際はここは「コミュニティ」だから「多大な迷惑」を感じたら誰も回答とかくれなくなると思うけどね。
guest

回答3

0

2次元配列で並んでいるということは、各要素の変化は他の要素に影響を与えずに、独立しているということ。

C++はしっかりとクラス定義を覚えて手続きっぽくならないように、
気をつけないといけないです。

目安としては20行以上{}の中に書かないこと。

あとC++20だとコレぐらい楽に書けれます。

C++

1//注意:C++20 2 3#include <iostream> 4#include <vector> 5#include <compare> 6#include <string> 7 8class KeyValue 9{ 10public: 11 int FirstKey; 12 int SecondKey; 13 14 KeyValue(int key1 = 0, int key2 = 0) : FirstKey(key1), SecondKey(key2) 15 { 16 } 17 auto operator<=>(const KeyValue &ather) 18 { 19 auto result = this->FirstKey <=> ather.FirstKey; 20 if (result == std::strong_ordering::equal) 21 { 22 return this->SecondKey <=> ather.SecondKey; 23 } 24 else 25 { 26 return result; 27 } 28 } 29}; 30 31int main() 32{ 33 std::vector keys = {KeyValue(1, 3), KeyValue(1, 2), KeyValue(2, 3), 34 KeyValue(3, 2), KeyValue(1, 1), KeyValue(1, 2), KeyValue(1, 2), 35 KeyValue(3, 1)}; 36 37 std::sort(keys.begin(), keys.end()); 38 39 std::for_each(keys.begin(), keys.end(), [](KeyValue x) { 40 std::cout << "key1:" << x.FirstKey << "key2:" << x.SecondKey << std::endl; 41 }); 42} 43 44

投稿2020/07/13 04:21

bjnes

総合スコア113

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

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

Usagi365m

2020/07/13 10:55

アドバイス非常に参考になりました、回答ありがとうございます!
guest

0

ベストアンサー

C++

1#include <iostream> // cin, cout 2#include <vector> // vector 3#include <algorithm> // sort 4using namespace std; 5 6struct Comp { 7 bool operator()(vector<int> &a, vector<int> &b) { 8 return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; 9 } 10}; 11 12int main() 13{ 14 int n; 15 cin >> n; 16 vector<vector<int>> num(n, vector<int>(2)); 17 18 for (int i = 0;i < n;i++) 19 cin >> num[i][0] >> num[i][1]; 20 21 sort(num.begin(), num.end(), Comp()); 22 23 for (int i = 0; i < n; i++) 24 cout << num[i][0] << " " << num[i][1] << endl; 25}

関数オブジェクト Comp() が分かりにくければ、
比較関数 comp を定義しても構いません。

C++

1#include <iostream> // cin, cout 2#include <vector> // vector 3#include <algorithm> // sort 4using namespace std; 5 6bool comp(vector<int> &a, vector<int> &b) 7{ 8 return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; 9} 10 11int main() 12{ 13 int n; 14 cin >> n; 15 vector<vector<int>> num(n, vector<int>(2)); 16 17 for (int i = 0; i < n;i++) 18 cin >> num[i][0] >> num[i][1]; 19 20 sort(num.begin(), num.end(), comp); 21 22 for (int i = 0; i < n; i++) 23 cout << num[i][0] << " " << num[i][1] << endl; 24}

また、ラムダ式を使うやり方もあります。

C++

1#include <iostream> // cin, cout 2#include <vector> // vector 3#include <algorithm> // sort 4using namespace std; 5 6int main() 7{ 8 int n; 9 cin >> n; 10 vector<vector<int>> num(n, vector<int>(2)); 11 12 for (int i = 0; i < n;i++) 13 cin >> num[i][0] >> num[i][1]; 14 15 sort(num.begin(), num.end(), [](vector<int> &a, vector<int> &b) { 16 return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; 17 }); 18 19 for (int i = 0; i < n; i++) 20 cout << num[i][0] << " " << num[i][1] << endl; 21}

追記
vector ではなく、配列を使って、qsort でソートするなら、

C++

1#include <iostream> 2#include <cstdlib> // qsort 3using namespace std; 4 5int comp(const void *x, const void *y) 6{ 7 int (*a)[2] = (int (*)[2])x, (*b)[2] = (int (*)[2])y; 8 return b[0] == a[0] ? b[1] - a[1] : b[0] - a[0]; 9} 10 11int main(void) 12{ 13 int num[100][2]; 14 int n; 15 cin >> n; 16 17 for (int i = 0; i < n; i++) 18 cin >> num[i][0] >> num[i][1]; 19 20 qsort(num, n, sizeof num[0], comp); 21 22 for (int i = 0; i < n; i++) 23 cout << num[i][0] << " " << num[i][1] << endl; 24}

追記2

return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; を 3項演算子を使わずに書くと、

C++

1 if (b[0] == a[0]) 2 return b[1] < a[1]; 3 else 4 return b[0] < a[0];

となります。比較演算子 < による演算結果は true または false なので何の問題
もないのですが、比較演算の式はどうしても if文の中に書きたいというのなら、

C++

1 if (b[0] == a[0]) 2 if (b[1] < a[1]) 3 return true; 4 else 5 return false; 6 else 7 if (b[0] < a[0]) 8 return true; 9 else 10 return false;

投稿2020/07/12 04:31

編集2020/07/13 10:55
kazuma-s

総合スコア8224

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

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

Usagi365m

2020/07/12 11:45

ご回答ありがとうございます! sort(num.begin(), num.end(), [](vector<int> &a, vector<int> &b) { return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; ここの部分はどのような処理をしているのでしょうか?
kazuma-s

2020/07/13 00:45

関数オブジェクト Comp() と 関数 comp は理解できたけど、[] で始まるラムダ式が理解できなかったということでしょうか?
Usagi365m

2020/07/13 10:41

ご丁寧にありがとうざいます! visualstudioで実際にステップインしながら確認しました、vector<int> &a, vector<int> &bで配列を取得して(今回の場合は最初a[2]{2,2},b[2]{2,3}....begin()で配列の最初、endで配列の終わりの数を指定、全ての要素を比較する全探査?を行い終わるまで処理?) return b[0] == a[0] ? b[1] < a[1] : b[0] < a[0]; 三項演算子じゃなくすと if(b[0] == a[0]){ b[1]<a[1] return true }else{ b[0]<a[0]; return false; } こんな感じになって tureかfalseか返して、同じだった場合二行目をひっくり返している、といった感じでしょうか?
Usagi365m

2020/07/13 10:58

追加分ご丁寧にありがとうございます! 三項演算子はその様になっているのですね、非常に勉強になりました!
guest

0

ソート関数に使う比較関数を、2番めの数値を対象にするように書けばそうできますね

投稿2020/07/11 21:33

y_waiwai

総合スコア88042

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

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

Usagi365m

2020/07/13 10:59

アドバイスありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問