• 締切済み

辞書式順序

C++で、2次元(以上の)配列に対して、 辞書式順序でsortできるようにするためには、 bool operatorとsortを使えばよいらしいというのは、 分かったのですが、具体的なコーディングが分かりません。 教えてください。

noname#108554
noname#108554

みんなの回答

  • bilbo
  • ベストアンサー率100% (1/1)
回答No.2

>まず、bilboさんのプログラムは動きませんでした。 >いろいろこちらで手直ししてみましたがやっぱりだめです 依然載せたプログラムは一応テストしたのですが... int版で作ってみました. 今度はちゃんと通った事を確認しています. >よく考えたら、こちらの開発環境を伝えてませんでした 僕の開発環境はUNIXのg++ですので,少し違うかも知れませんね. このプログラムが動かなかった場合は,配列のi行目の最後の列のデータ とi+1行目の最後の列のデータが,隣同士にあるかどうか確かめてください. これはm行n列の配列Aに対して,A[i][n+5]という様なアクセスで, A[i+1][5]をアクセスできるかどうかで確かめられると思います. もしA[i][n-1]とA[i+1][0]が隣同士に無い様な開発環境ですと, A[i]がA[i][0]~A[i][n-1]までの配列へのポインタになってること が考えられます(配列でそんな環境があるかは疑問ですが). そのような場合,この方法でソートするのはイタレータを 定義しなければならないのでややこしい事になります. それから,これは分かっておられるかと思いますが, ソートするデータを静的配列に入れないと,A[i][n-1]と A[i+1][0]が隣り合わないので駄目です. 動的配列に入れるとコンパイルの時点ではねられると思います. #include<algorithm> #include<iostream> #include<functional> int main() { int m[4][6]; for(int i = 0; i < 4; ++i) for(int j = 0; j < 6; ++j) m[i][j] = i+ j; for(int i = 0; i < 4; ++i) { copy(m[i], m[i]+6, ostream_iterator<int>(cout, " ")); cout << endl; } cout << endl; sort(m[0], m[0]+24, less<int>()); for(int i = 0; i < 4; ++i) { copy(m[i], m[i]+6, ostream_iterator<int>(cout, " ")); cout << endl; } return 0; } 出力結果 0 1 2 3 4 5 1 2 3 4 5 6 2 3 4 5 6 7 3 4 5 6 7 8 0 1 1 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 7 7 8

noname#108554
質問者

補足

たびたび申し訳ないです。 コンパイラのエラー情報によると、 copyやostream_iteratorは「定義されていない識別子」だそうです。 UNIX CとWindowsではまったく違うものなのでしょうか?

  • bilbo
  • ベストアンサー率100% (1/1)
回答No.1

2次元配列上のデータをソートするというのは、 どのような基準で並べ替えるということなのでしょうか? (列数)*(行インデックス)+(列インデックス) が大きくなる程、値が大きくなるようにソートしたいということでしょうか? そうであると仮定して話を進めさせてもらいます。 又、bool operator>とsortを使えばいいというのは、 C++の標準テンプレートライブラリの、<algorithm>のsortを使って、 2次元配列をソートしたいということなのでしょうか? そうであると仮定して話を進めさせてもらいます。 まず、operator>についてですが、配列に格納するデータに対して このメンバ関数を定義する必要があります。ソートの基準のためです。 また、必ずしもoperator>を使わなくても、ソートの基準を決めてくれる 関数をsortに渡してやってもいいです。 辞書式順序といっておられるので、格納するデータは文字列でしょうか? stringクラスにはoperator>が定義してあるので、stringクラスを 利用する場合でしたら必要ありません。 ここでは文字型の配列に文字列を入れている事にしましょう。 この場合、strcmpで比較する事になりますね。 例えば、次のようなコードになります。 #include<algorithm> #include<iostream> #include<cstring> bool my_less(const char *str1, const char *str2) { return (strcmp(str1, str2) < 0); } int main() { char *a[4][6]; for(int i = 0; i < 4; ++i) for(int j = 0; j < 6; ++j) { a[i][j] = new char[4]; a[i][j][0] = 'a'+i*j; a[i][j][1] = 'a'+j/(i+1); a[i][j][2] = 'a'+j+i; a[i][j][3] = '\0'; } for(int i = 0; i < 4; ++i) { for(int j = 0; j < 6; ++j) cout << " " << a[i][j]; cout << endl; } cout << endl; sort(a[0], a[0]+24, my_less); for(int i = 0; i < 4; ++i) { for(int j = 0; j < 6; ++j) cout << " " << a[i][j]; cout << endl; } return 0; }

noname#108554
質問者

補足

ご解答ありがとうございます。 まず、bilboさんのプログラムは動きませんでした。 いろいろこちらで手直ししてみましたがやっぱりだめです。 よく考えたら、こちらの開発環境を伝えてませんでした。 申し訳ないです。 MicrosoftVisualC++6.0になります。 あと何か必要なデータはありますか? > (列数)*(行インデックス)+(列インデックス)が大きくなる程、 >値が大きくなるようにソートしたいということでしょうか? そうです。 >C++の標準テンプレートライブラリの、<algorithm>のsortを使って、 >2次元配列をソートしたいということなのでしょうか? これもそうです。 >格納するデータは文字列でしょうか? 数字です。すみません、忘れてました・・・ で、こちらでも調べて lexicographical_compareとかいうのがあるらしいというので、 こんなプログラムを作ったのですが、やっぱり動きません。 八方ふさがりになってきました・・・ #include <iostream> #include <algorithm> #include <vector> #include <functional> using namespace std; class data { int num1,num2; public: void setnum1(int i){num1=i;} int getnum1() const {return num1;} void setnum2(int j){num2=j;} int getnum2() const {return num2;} }; bool operator < (const data& a,const data& b){ return lexicographical_compare(a.begin(),a.end(), b.begin(), b.end()); } int main() { int i,k,l; data dat; vector<data> d; cout << "数字を入力" << endl; for(i=0;i<5;i++){ cin >> k; cin >>l; dat.setnum1(k); dat.setnum2(l); d.push_back(dat); } cout << "出力" << endl; sort(d.begin(),d.end()); for(i=0;i<5;i++){ cout << d[i].getnum1() << " " << d[i].getnum2() << endl; } }

関連するQ&A

  • 辞書式配列

    辞書式配列の方法を教えてください。(^o^;

  • 辞書式順序に対応する順序(オリジナル)

    いつもお世話になっています。 ●順列 異なるn個のものから重複を許さないでr個並べる順列の総数をnPrで表します。 ○例 異なる3つのものa,b,cから重複を許さないで2つ並べる方法 3P2=6通り を具体的に表記すると、 (a,b),(a,c),(b,a),(b,c),(c,a),(c,b) と組を使って表記できます。 同じことですが、単射な写像f:{1,2}→{a,b,c}を用いて、 (f(1),f(2))=(a,b),(a,c),(b,a),(b,c),(c,a),(c,b) と表記できます。 さらに逆写像を用いて、 (f^(-1)(a),f^(-1)(b),f^(-1)(c))=(1,2,φ),(1,φ,2),(2,1,φ),(φ,1,2),(2,φ,1),(φ,2,1) と表記できます。 ただし、φは空集合。 ●組合せ 異なるn個のものから重複を許さないでr個選ぶ組合せの総数をnCrで表します。 ○例 異なる3つのものa,b,cから重複を許さないで2つ選ぶ方法 3C2=3通り を具体的に表記すると、 {a,b},{a,c},{b,c} と集合を使って表記できます。 同じことですが、単射な写像f:{1,2}→{a,b,c}の像集合を用いて、 {f(1),f(2)}={a,b},{a,c},{b,c} と表記できます。 さらに逆写像の個数を用いて、 (♯f^(-1)(a),♯f^(-1)(b),♯f^(-1)(c))=(1,1,0),(1,0,1),(0,1,1) と表記できます。 ●重複順列 異なるn個のものから重複を許してr個並べる順列の総数をn^rで表します。 ○例 異なる2つのものa,bから重複を許して3つ並べる方法 2^3=8通り を具体的に表記すると、 (a,a,a),(a,a,b),(a,b,a),(a,b,b),(b,a,a),(b,a,b),(b,b,a),(b,b,b) と組を使って表記できます。 同じことですが、写像f:{1,2,3}→{a,b}を用いて、 (f(1),f(2),f(3))=(a,a,a),(a,a,b),(a,b,a),(a,b,b),(b,a,a),(b,a,b),(b,b,a),(b,b,b) と表記できます。 さらに逆像を用いて、 (f^(-1)(a),f^(-1)(b))=({1,2,3},φ),({1,2},{3}),({1,3},{2}),({1},{2,3}),({2,3},{1}),({2},{1,3}),({3},{1,2}),(φ,{1,2,3}) と表記できます。 ただし、φは空集合。 ●重複組合せ 異なるn個のものから重複を許してr個とる組合せの総数をnHrで表します。 ○例 異なる2つのものa,bから重複を許して3つとる方法 2H3=4通り を具体的に表記すると、 {a,a,a},{a,a,b},{a,b,b},{b,b,b} と表記できます。 ただし、多重集合の意味。 同じことですが、写像f:{1,2,3}→{a,b}の像集合を用いて、 {f(1),f(2),f(3)}={a,a,a},{a,a,b},{a,b,b},{b,b,b} と表記できます。ただし、多重集合の意味。さらに逆写像の個数を用いて、 (♯f^(-1)(a),♯f^(-1)(b))=(3,0),(2,1),(1,2),(0,3) と表記できます。 それぞれ2通りの表記をしましたが、前者は辞書式順序ですが、後者はいったいどういった順序になっているのでしょうか? 今回、後者の表記を書くときは、前者の表記を参考に書きましたが、後者のみを書くとき、どういう順序に気を付けて書いたらいいのでしょうか?

  • シェルソートの順位性

     このカテゴリーのNo.137(#35189)の続きなのですが、シェルソートについてご存知の方お願いします。  上記の質問にて、ヒープソートは完全二分割木型で、同一の値であってもその順序は保証されない、ということがわかりました。  そこで、配列の内容をソートする処理をシェルソートで組んでみました。  やろうとしているのは、n1、n2 の2つの配列に値を入れ、n1 が同じ値だったら n2 の値を使ってソートする、という処理です。  しかし実際には、n3、n4と無制限に続く2次元配列なので各配列を個別にソートしなければならず、n2 を先にソートしてから n1 をソートする、という処理を入れています。  ところがこれだと、n1 のソート時に同一の値の順序が崩れると、せっかく行った n2 のソートが無駄になってしまいます。  シェルソートの場合、こういうことは起こるのでしょうか。  よろしくお願いします。 

  • C言語での式の評価順序について

    ANSI C規格では 「式の評価順序は処理系により異なる」 とのことですが,次のプログラムがどのような評価順序で処理されたのか,どうしても分かりません. C言語の細かいところまでご存知の方がいらっしゃいましたら教えてください. #include <stdio.h> main(){ int c; c = 0; printf("%d\n", c + 1 == ++c); c = 0; printf("%d\n", c + 0 == ++c); } 私の処理系のccでコンパイルして実行すると 1 1 と出力されます. 上の二つの条件式が両方とも真であると解釈され得るような評価順序が存在するのでしょうか?

  • 多次元配列の並び変えについて

    <?php $food["a"]["1"]= "hoge1"; $food["b"]["2"]= "hoge2"; $food["c"]["3"]= "hoge3"; $food["d"]["4"]= "hoge4"; ?> 上記の配列について、1,2,3,4のキーの順番でソートしたいのですが、うまく出来ません。 一次元配列だと簡単なのですが、二次元配列だとどうやったらよいのでしょうか? array_multisortを使うと、多次元でも並び変えはできると他のサイトで読みましたが、 これは結局値でソートしてますよね? 私は純粋にキーのみでソートしたいのですが、色々調べているのですがどうも複雑なプログラムを 書かないとできないような気がしてきました。

    • 締切済み
    • PHP
  • rubyでは比較演算子もメソッドとして書き換えが可

    rubyでは<や>などの比較演算子もメソッドと分類されるのでオーバーライドが可能と認識しております。具体的にどのようにコーディングしたら良いのでしょうか? 例えば、配列に数値が格納されているとします。 array=[3,5,4,2,1] この配列をソートした場合に比較が何回行われたかをカウントしたいです。 p array.sort >や<が再定義可能なら、比較演算子が呼ばれる度にカウンターアップするなどと言う事はできるような気がするのですが、どうコーディングしてよいか解りません。 rubyのマニュアルも読んだし、それなりに検索でも頑張ったのですが、煮詰まってしまいました。 ご指導のほど、よろしくお願いいたします。

    • ベストアンサー
    • Ruby
  • c言語 配列 や ソート datファイル読み込みについて

    初投稿でC言語初心者なのでよろしくお願いします。 課題でdatファイルから100万個の数字を読み込んで、ソートのタイムを競うのがでました。 ソートのアルゴリズム等は分かるのですが、100万個の数字を読み込むのがわかりません。 datファイルには、縦にずらっと数字が並べられていてどこを区切り文字としてとりだすのとか。 int配列も100万個も格納できないので3次元配列つかうのかなと思ってみたりしてます。 どうやって格納すればソートで使いやすいかご教授お願いいたします。

  • 三次元空間での直線の式

    二次元で直線の式はy=ax+bとなることはわかります。では三次元になるとどうなるのですか?直感としては、z=ax+by+cとなるかな~と考えているのですが、これでは一直線じゃないような気もします。どなたか教えてください。また、できれば4次元以上ではどうなるのかも教えてほしいです。よろしくお願いします。

  • 多次元配列のソートの仕方について

    Arrayクラスにsortというメソットについて質問です。 配列が多次元の場合、そのどれか1次元についてソートしたいのですが使い方がわからなく質問しました。 たとえば、a[n][m]という配列で a[0][0]=4 a[0][1]=3         a[0][0]=4 a[0][1]=3 a[1][0]=5 a[1][1]=5    →    a[1][0]=7 a[1][1]=4 a[2][0]=7 a[2][1]=4         a[2][0]=5 a[2][1]=5 だとします。 この配列をmの値が1のときについて最初の[n]をソートしたいです。 そして、mの値が0の値も[1]でソートしたものと一緒にソートしたいです。

  • Pythonの2次元配列のソート

    Python3の2次元配列のソートについて教えて下さい [[1, 2], [1, 3], [2, 4]]のようなリストのソートで 昇順ソートでインデックス0が同じならインデックス1は降順でソートしたいと思ってます。 結果が以下のようになるようにしたいです 1 3 1 2 2 4 よろしくおねがいします。

専門家に質問してみよう