char s[10][10]をstd::sortでソート

解決


ja  2009-06-18 18:07:24  No: 70365

2次元配列 char tab[10][10] をstd::sortでソートしたいのですが、
std::sortへの引数の渡し方がわかりません。
どのように書いたらよいでしょうか?

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

bool cmp_strcmp(const char* a, const char* b) {
  return strcmp(a, b) < 0;
}

int main() {
  char tab[10][10];
  int n = 0;
  strcpy(&tab[n++][0], "ab");
  strcpy(&tab[n++][0], "hello");
  strcpy(&tab[n++][0], "abd");

  // sortでソートしたい
  // sort(??, ??, cmp_strcmp) // ??の部分がわかりません

  // 出力
  for (int i = 0; i < n; i++)
    puts(tab[i]);
}

期待する実行結果:
ab
abd
hello


επιστημη  URL  2009-06-18 18:54:03  No: 70366

うわ、めんどくせー...
↓コレなら楽勝なんですけどねー

#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

bool cmp_strcmp(char *a, char *b) {
  return strcmp(a, b) < 0;
}

int main() {
  char* tab[10];
  int n = 0;
  tab[n++] = strdup("ab");
  tab[n++] = strdup("hello");
  tab[n++] = strdup("abd");

  sort(tab, tab+n, &cmp_strcmp);
  
  // 出力
  for (int i = 0; i < n; i++) {
    puts(tab[i]);
    free(tab[i]);
  }
}


tetrapod  2009-06-18 20:18:12  No: 70367

std::sort は、ソート対象が代入可能でないと使えない。
一方で単純配列は代入可能でない (int a[10], b[10]; に対して a=b; はできない)
なのでそもそも std::sort で配列自体をソートするってのが不向き。

うーむ誤解を生みかねないので補足しておくほうがよさそうかな:
string の配列や ポインタの配列ならソート可能(ソート対象は string やポインタ)
配列の配列は std::sort 不能(ソート対象が 配列 なので)


επιστημη  URL  2009-06-18 20:24:02  No: 70368

フォローありがとです > tetrapodさん。

int main() {
  char tab[10][10];
  int n = 0;
  strcpy(&tab[n++][0], "ab");
  strcpy(&tab[n++][0], "hello");
  strcpy(&tab[n++][0], "abd");

  sort(&tab[0], &tab[n], ptr_fun(&cmp_strcmp));
  ...

このコードをVC++9でコンパイルすると:
...\Microsoft Visual Studio 9.0\VC\INCLUDE\algorithm(3133) 
: error C2106: '=' : 左のオペランドが、左辺値になっていません。
...\Microsoft Visual Studio 9.0\VC\INCLUDE\algorithm(3140) 
: error C2106: '=' : 左のオペランドが、左辺値になっていません。

なんてエラーが報告されます。
ソート対象となる要素 char[] に =(代入操作) が適用できないからですね。


ja  2009-06-19 19:43:15  No: 70369

ありがとうございました。別のデータ構造に変換してからソートするようにします。


επιστημη  URL  2009-06-19 20:35:08  No: 70370

> 別のデータ構造

ご参考: char tab[10][10] 改め vector<string> に。

#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
  vector<string> tab;
  tab.push_back("ab");
  tab.push_back("hello");
  tab.push_back("abd");

  sort(tab.begin(), tab.end());
  
  // 出力
  for (int i = 0; i < tab.size(); ++i)
    puts(tab[i].c_str());
}

ほら簡単♪


tetrapod  2009-06-19 21:39:03  No: 70371

既に char[10][10]; でデータを持っていて、そこを修正するつもりはなくて、
でもソートのためだけに vector<string> に変換し、またもとの char[10][10] に戻すくらいなら
素直に qsort してしまえ。

char tab[5][10]; に3つ有効な要素が入っているとしたら
qsort(tab, 3, sizeof(char[10]), tabcompfunc);
でソートできる(データの変換不要)
比較関数 tabcompfunc をどう実装するかはお任せ(宿題)としておこう。


επιστημη  URL  2009-06-19 22:50:58  No: 70372

> ソートのためだけに vector<string> に変換し、
> またもとの char[10][10] に戻すくらいなら
> 素直に qsort してしまえ。

激しく"ごもっとも"


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加