STL #include vector のまとめ。
元々の定義はこんな感じ.
vector(); vector( const vector& c ); explicit vector( size_type num, const T& val = T() ); vector( input_iterator start, input_iterator end );
vectortest(sz); //sz:要素数 vector test(sz, 0) //五個の要素を0で初期化 //新規に独立してできた変数. vector test2(test); //OK!! コピーコンストラクタとして. vector b(&test[0], &test[sz]); //OK!! vector b(test.begin(), test.end()); //いうまでもなく、これもOK
いったん初期化してしまえば、push_back()等は使えない.使えました.普通に.
なので、配列の大きさがよくわからないときや、条件によって、配列の大きさが変わる時などは動的に作らせると良い.
vectora;
vectorは最後の要素に、参照、挿入、削除するのを得意とする。
最初の要素には、insert, eraseで線形時間かかるので、やめた方が無難。
最初の要素を参照するのは、frontでできる。これは、定数時間。
これも、OK!!
int main() { vectorit(5); //意味はないけど、 // vector it(0); //も可能。 it.push_back(7); for(vector ::iterator i = it.begin(); i != it.end(); i++) { cout << *i << endl; //size = 6; 動的に配列が増えている. } }
//ただ、ポインタがかわっているだけ。 vectorarr(N+1, 0); for(int i = 0; i <= N; i++) { arr[i] = i; } int skip = 2; while(arr.size() > 2) { int sz = arr.size(); vector ok; ok.push_back(0); for(int i = 1; i < sz; i++) { if(i % skip != 1) { ok.push_back(arr[i]); } } arr = ok; skip++; }
多次元配列の作り方。
const int sz = 10; vectorform[sz]; //10個のvector を作成 vector< vector > form(sz); //10個のvector を作成(動的) vector< vector > form(sz, vector (N, 0)) //10*Nの0に初期化されたvector を作成 //メリットは、2番目は複雑な分、縦方向も横方向もvectorのメソッドを使えることか。 //基本的には、1番目のやり方で事足りるような気がする。
v1.swap(v2)
//使いどころ ある条件で二つの出力を変えたい時. while(male.size() != i) { if(ans.empty()) ans.push_back("HOST"); if(i == male.size()/2) { ans.push_back("HOSTESS"); flag = true; } if(flag) { ans.push_back(male[i]); ans.push_back(female[i]); } else { ans.push_back(female[i]); ans.push_back(male[i]); } i++; //すっきりした書き方. female.swap(male) //または、 swap(female, male);
indexも保存してソートしたいとき、
普通のやり方では無理っぽいので、構造体かクラスを使って保存しておくのが一番簡単.
class Node { int index; int value; int sum; } //classだと初期化できちゃうからまあ、使いやすいと思う. //比較関数の作成 class LessSum { bool operator() (const Node& a, const Node& b) const { ... }
排除処理。
配列を条件に従って、順番に消していきたい。
eraseを使うと、消した分が全体的に一つ左にシフトするので・・・
1 2 3 4 5 6 //<----4を削除 1 2 3 5 6 // //forを使った時厄介になる for(int i = 0; i < 6; i++) { if(arr[i] == 4) { arr.erase(i); } //これが適用された直後にforを抜けて、i = 4で処理すると、 //配列の5がきちんと処理されなくなる。 }
一応、イテレータを使って、条件に充てはまるときだけ、
イテレーターを次に移動させるとかもいいけど、いろいろめんどくさいし、分かりにくいコードになるので、
コピーコントラスタを使えば、簡単。
const int N = 7; vectorarr(N); while(1) { vector tmp; //段階的に条件にそぐわない配列の要素を削除。 for(..) { if(arr[i] != 4) { tmp.push_back(arr[i]); } } arr = tmp; //コピーコンストラクタ使用 ポインタが変わっているだけということに注意。 //...break; 適当なところでbreak; } //このとき、tmpの要素数のほうが小さくなるので、arr[N-1]とかに //アクセスできるかもしれないと思うかもしれないが、実際にはそんなことはなく、 //arr.size() = tmp.size() となり、何の問題もなく動作する。
vector
イテレータをうまく処理できないらしいので、余り使い勝手が良くない。 findも使えないし、trueの数を数えるのに、countも使えない。 ならば、bool flag[N]とやっちゃおう。