初めて質問させて頂きます。
至らない点がありましたらご指摘お願いいたします。
行いたいことは 2次元配列の『列』でのソートです。
Excelのように列にてソートを行いたく思います。
まずファイルから vector<string> にて分割を行い、
index を作成し、ソートを行ってみました。
-- ソース --
int main() {
typedef vector<string> row_type;
vector<row_type> data;
ifstream file("c:\\data.csv");
if ( !file.is_open() ) { return 1; }
string line;
while ( std::getline(file, line) ) {
row_type row;
string::size_type begin = 0;
string::size_type end = 0;
const string delim = ",\t";
while ( (begin = line.find_first_not_of(delim, end))
!= string::npos ) {
end = line.find_first_of(delim, begin);
row.push_back(line.substr(begin, end-begin));
}
data.push_back(row);
}
cout << "元のデータ" << endl;
string::size_type i,j;
for ( i = 0; i < data.size(); i++ ) {
for ( j = 0; j < data[i].size(); j++ ) {
std::cout << '[' << data[i][j] << "] ";
}
std::cout << std::endl;
}
// index 作成
int index[65535]; // vector<string>.size() にしたい。
int counter = 0;
for (counter = 0; counter < data.size(); ++counter){
index[counter] = counter;
}
/* ----- ここからが問題 ----- */
// ソートの実行
string str;
string::size_type tempval = 0;
for (i = 0; i < data.size(); i++){
str = data[index[i]][2];
int x = i;
for (j = 0 ; j < data.size() ; j++){
if (strcmp(data[index[j]][2].c_str(),
str.c_str()) > 0){
str = data[index[j]][2];
x = j;
}
}
// インデックスの交換
tempval = index[i];
index[i] = index[x];
index[x] = tempval;
}
// 出力
cout << "変換後のデータ" << endl;
for (i = 0; i < data.size(); i++){
cout << index[i] << "" ;
for (j = 0; j < data[i].size(); j++){
cout << '[' << data[index[i]][j] << "]";
}
cout << endl;
}
return 0;
}
-- data.csv --
"1","2000/01/01","test"
"2","2000/01/02","test2"
"3","2000/01/03","test3"
"4","2000/01/04","test"
"5","2000/01/05","test2"
"6","2000/01/06","test3"
"7","2000/01/07","test4"
-- 変換後 --
1["2"]["2000/01/02"]["test2"]
2["3"]["2000/01/03"]["test3"]
3["4"]["2000/01/04"]["test"]
4["5"]["2000/01/05"]["test2"]
5["6"]["2000/01/06"]["test3"]
0["1"]["2000/01/01"]["test"]
6["7"]["2000/01/07"]["test4"]
上記を実行するとデータがばらばらでまったくソートがされて
おりません。
非常にわかりにくい質問で申し訳ありません。
また非常にみなさんに失礼な質問かもしれません。
申し訳ありませんがヒントだけでも結構です。
アドバイス頂けますでしょうか。
環境は Windows2000, VC6.0にて作成を行っております。
よろしくお願いいたします。
> 行いたいことは 2次元配列の『列』でのソートです。
> Excelのように列にてソートを行いたく思います。
> まずファイルから vector<string> にて分割を行い、
> index を作成し、ソートを行ってみました。
vector<string>ではなく,
struct {
std::string index;
std::string date;
std::string str;
} row_type;
を使った方がわかりやすいのでは?
まぁ,std::vector<std::string>を相手にしても同じようなことができますが。
とりあえず,構造体を利用するとして,まずは比較用の型を用意。
struct row_type_compare : binary_function<row_type, row_type, bool>
{
bool operator() (const row_type & lhs, const row_type & rhs) const
{
return lhs.str < rhs.str; // std::stringは直接比較可能
}
};
で,
> // ソートの実行
> string str;
> string::size_type tempval = 0;
>
> for (i = 0; i < data.size(); i++){
> str = data[index[i]][2];
> int x = i;
>
> for (j = 0 ; j < data.size() ; j++){
> if (strcmp(data[index[j]][2].c_str(),
> str.c_str()) > 0){
> str = data[index[j]][2];
> x = j;
> }
> }
>
> // インデックスの交換
> tempval = index[i];
> index[i] = index[x];
> index[x] = tempval;
> }
は
std::sort(data.begin(), data.end(), row_type_compare());
で一発。
インデックスが必要なら,それなりにデータ構造を変える必要がありますが……。
YuOさん早速のご返答ありがとうございます。
>vector<string>ではなく,
>struct {
> std::string index;
> std::string date;
> std::string str;
>} row_type;
>を使った方がわかりやすいのでは?
言葉が足りませんでした。申し訳ありません。
構造体にしないのは、data.csvは上記の3つのデータのみではなく、
可変長なデータでした。
よってstd::vector<std::string>にて動的配列を使用しています。
やることは変わらないと思いますが……。
比較用のファンクタクラス作って,std::sortに渡すだけ……。
http://www005.upp.so-net.ne.jp/episteme/html/stlprog/index.html
のところの,
http://www005.upp.so-net.ne.jp/episteme/html/stlprog/_05.html#algo_sort
とか
http://www005.upp.so-net.ne.jp/episteme/html/stlprog/_04.html#making_fun
を参照してみてください。
YuOさんありがとうございます。
まだファンクタクラス等への理解がありませんので、
YuOさんの適切なご指示を理解できません。
早速、『Effective STL』をAmazon にて購入しました。
勉強せねばと思います。
結果、私には回答が導きだせませんでした。
しかしYuOさんほどの著名なかたが、私ごときの質問に回答いただき、
とても幸せに思います。ありがとうございました。
以下書き方が良くないですね・・。
> 結果、私には回答が導きだせませんでした。
"私に回答を導きだすのには時間が必要です。" に変更させてください。