WinXP(SP2) VC++ 6.0です。
STLはさわりはじめたばかりです。
struct student {
int student_no;
int point;
bool operator<(const student& r) const {
return point < r.point;
}
};
typedef std::set<student> student_set_t;
student_set_t student_set;
として、student_noに一意の生徒番号、pointに得点を次々とinsertしていき得点順に
ソートしておきます。
ここまではできました。
その後、{1,2,3,4,5}など任意の数の生徒番号が入ったvectorを渡すと、student_set内
でソートされた順にvector要素がソートされて返ってくるような処理を書きたいのです
が、どう手をつけていいのかからわかりません。
よくありそうな処理なので、STLを使えばうまくかけるのかなあと思っている程度なの
で、ほかにもっとよい方法などあれば教えていただきたいです。
/*
* 説明は省略
*/
#include <iostream>
#include <vector>
#include <algorithm>
struct student {
int no;
int point;
};
bool no_less(const student& x, const student& y)
{ return x.no < y.no; }
bool point_less(const student& x, const student& y)
{ return x.point < y.point; }
struct no_eq {
int no;
no_eq(int n) : no(n) {}
bool operator()(const student& x) const {
return x.no == no;
}
};
int get_no(const student& x)
{ return x.no; }
int main() {
student master[8] = {
{7, 345},
{8, 678},
{1, 123},
{2, 456},
{5, 567},
{6, 812},
{3, 781},
{4, 234},
};
std::vector<student> record(master, master+8);
int no[5] = { 4, 5, 3, 1, 2};
std::vector<int> target(no, no+5);
// ----- ここから
std::vector<student> work;
for ( std::vector<int>::iterator i = target.begin(); i != target.end();
++i ) {
std::vector<student>::iterator item = std::find_if(record.begin(),
record.end(), no_eq(*i));
if ( item != record.end() ) {
work.push_back(*item);
}
}
std::sort(work.begin(), work.end(), &point_less);
std::transform(work.begin(), work.end(), target.begin(), &get_no);
// ----- ここまで
for ( std::vector<int>::iterator i = target.begin(); i != target.end();
++i ) {
std::cout << *i << ' ';
}
std::cout << std::endl;
}
…違うな。題意に沿うのはこっち。
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
struct keyed_less {
std::map<int,int>& ref;
keyed_less(std::map<int,int>& r) : ref(r) {}
bool operator()(int x, int y) const {
return ref[x] < ref[y];
}
};
int main() {
int master[] = {
7, 345,
8, 678,
1, 123,
2, 456,
5, 567,
6, 812,
3, 781,
4, 234,
};
std::map<int,int> record;
for ( int i = 0; i < 8; ++i ) {
record[master[i*2]] = master[i*2+1];
}
int no[5] = { 4, 5, 3, 1, 2};
std::vector<int> target(no, no+5);
std::sort(target.begin(), target.end(), keyed_less(record));
for ( int i = 0; i < target.size(); ++i ) {
std::cout << target.at(i) << '/'
<< record[target.at(i)] << std::endl;
}
std::cout << std::endl;
}
1つめのはいまいち理解できていませんが、2つめのは分かりやすく、目からうろこがお
ちる思いでした。
必ずしも、ソートしたものを持っておく必要はないわけですね。
それにしてもこんなに簡潔に書けるなんて、STLって奥が深そうです..
どうもありがとうございました。