vectorの配列番号をメモったまま(部分的に)並び変える
昇順・降順ともに一旦ベクトルの値をindex-valueでペア化して、それをソート(ここではpartial_sort)するような関数(ここではlessPair, greaterPair)を用意すればOK。
ここではベクターの上位二番目の位までを降順並び替え。
#include <vector> #include <algorithm> #include <iostream> //index-valueのペア typedef std::pair<int,int> ipair; bool lessPair(const ipair& l, const ipair& r){return l.second < r.second;} bool greaterPair(const ipair& l, const ipair& r){return l.second > r.second;} int main() { using namespace std; //適当データ vector<int> x; x.push_back(11); x.push_back(7); x.push_back(3); x.push_back(4); x.push_back(8); //インデックスと共にペアに突っ込む std::vector<ipair> y; for(unsigned int i = 0; i < x.size(); i++){ y.push_back(ipair(i, x[i])); } //部分ソート、値の上位2位までは並び替え partial_sort(y.begin(), y.begin()+2, y.end(), greaterPair); //インデックス・値の出力 for(vector<ipair>::iterator it = y.begin(); it != y.end(); ++it){ cout << it->first << " " << it->second << endl; } return 0; }}
実行結果(一列目:元の配列のインデックス、二列目:降順に並びかえられた値)
0 11 4 8 2 3 3 4 1 7
アライメントの調整を楽にする
構造体をVBA(Excel)からC++に投げつける際には、データのメモリへの詰め込まれ方、アライメント(VC++デフォルト8バイト・VBA4バイト)に注意せんといかんわけです。
これを成し遂げるために今までは【プロジェクトのプロパティ】→【C/C++】→【コード生成】→【構造体メンバのアライメント】を「4バイト(/Zp4)」にしていたのですが、pragma packでいけるってのがわかったのでメモん。
下のコードではX1・X2構造体がpragma packではさまれているか否かのみが異なる。
これでX1はデフォルトの8バイト毎、X2は指定した4バイト毎にアライメントされる。
#include <iostream> using namespace std; struct X1 { int x; double y; }; #pragma pack(push,4) struct X2 { int x; double y; }; #pragma pack(pop) int main() { std::cout << sizeof(X1) << std::endl; std::cout << sizeof(X2) << std::endl; return 0; }
実行結果を見てみると、X1は8バイトなので、int(4バイト)が埋められた後、4バイトの空白があり、その後doubleの8バイトが入るような形になっている(合計12バイト=4+4+8)一方、
X2は4バイトなので、int(4バイト)が埋められた後、空白なしにdoubleの8バイトが入るような形になっている(合計12バイト=4+8)。
16 12