• ベストアンサー

コンテナ要素の削除について

今vectorの勉強をしているのですが、要素を削除できなくて困っています。 下記のch1とch2において、 vector<int> ch1; vector<int> ch2; ch1.push_back(10); ch1.push_back(11); ch1.push_back(12); ch1.push_back(13); ch1.push_back(14); ch1.push_back(15); ch2.push_back(13); ch2.push_back(14); ch2.push_back(15); ch1とch2が一致する要素は削除して、一致しない値を得たいのですがどうしたらいいのでしょうか? 結果としては、 ch1に、10・11・12のみが残る感じです。 よろしくお願い致します。 int ch1_size = ch1.size(); int ch2_size = ch2.size(); vector<int>:: iterator itr1; itr1=ch2.begin(); for(int a=0;a<ch1_size;a++){ for(int b=0;b<ch2_size;b++){ if(ch1[a]==ch2[b]){ itr1+b; ch1.erase(itr1); } } }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

既にpleaseteacherさんも回答されていますが、STLちっくにこんな感じもあります。 #include <iostream> #include <algorithm> #include <vector> using namespace std; template<typename T, typename U> class ChoFuKu { public: ChoFuKu( const U& _container ) : m_container(_container) {} bool operator()( const T& _value ) const { return find(m_container.begin(), m_container.end(), _value) != m_container.end(); } private: U m_container; }; int main() { vector<int> ch1; vector<int> ch2; ch1.push_back(10); ch1.push_back(11); ch1.push_back(12); ch1.push_back(13); ch1.push_back(14); ch1.push_back(15); ch2.push_back(13); ch2.push_back(14); ch2.push_back(15); vector<int>::iterator e = remove_if(ch1.begin(), ch1.end(), ChoFuKu<int, vector<int> >(ch2)); ch1.erase(e, ch1.end()); for( vector<int>::iterator it = ch1.begin(); it != ch1.end(); ++it ) cout << *it << endl; }

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

std::set_differenceまたはstd::set_symmetric_differenceを使えば一発でできそうな気がします。

全文を見る
すると、全ての回答が全文表示されます。
noname#16581
noname#16581
回答No.1

こんな感じでどうでしょう? #include<stdio.h> #include<vector> int main() { std::vector<int> list1; std::vector<int> list2; for(int i=0;i<3;i++) { list1.push_back(i); list2.push_back(i); } list2.push_back(3); list2.push_back(4); for(std::vector<int>::iterator i=list1.begin();i!=list1.end();i++) { for(std::vector<int>::iterator j=list2.begin();j!=list2.end();j++) { if(*i==*j) { list1.erase(i,i+1);i--; list2.erase(j,j+1);j--; } } } for(int i=0;i<list1.size();i++) { printf("%d ",list1.at(i)); } printf("\n"); for(int i=0;i<list2.size();i++) { printf("%d ",list2.at(i)); } getchar(); return 0; }

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c++のvector::erase

    vector::eraseについて質問させてください。 vector::eraseでググるとforループ内でのeraseの仕方は 書いていあるのですが、単純に1要素だけeraseする 例が見当たらなかったので教えてください。 1要素を削除する場合、 以下のような書き方でよろしいのでしょうか? いちおう正しく動作しているようです。 ただ、疑問なのは途中の要素[2]を削除しているので、 後半の要素が詰め直されているのか、 そのあたりが自信がなくて不安です。 vector<string> v; v.push_back("0a"); v.push_back("1a"); v.push_back("2a"); v.push_back("3a"); v.push_back("4a"); v.erase( v.begin() + 2 );//v[2]を削除 //結果表示 for(unsigned int i=0; i<v.size(); i++){ cout<<v[i]<<"\n"; } cout<<endl;

  • STLのvectorの削除

    たびたび申し訳ありませんが、ご教示願います。 vector配列をeraseを使用して削除しているのですが、 どうしてもうまくいかず躓いています。 仮にvectorのサイズが3で1番目の要素を削除したいのですが、 どうしても、サイズに関わらず最後の要素が削除されてしまいます。 下記のコードのように簡略化しましたが、結果は変わりませんでした。 vector<class>obj; vector<class>::iterator it; ・・・ it=obj.begin(); it=obj.erase(it); 結果は最後の要素(サイズが3であれば3番目の要素)が削除されます。 erase時点でのitは削除したい要素をさしているのは確認済みです。 eraseの戻り値も削除したい要素を指してしまっています・・・・ なぜ最後の要素が削除されてしまうのでしょうか。 全く分かりません。よろしくお願いします。

  • STLのvectorの削除

    STLのvectorの削除を行う場合に vector<myclass> v; ・・・ v.erase(it); ・・・ というように削除するiteratorを渡しますが、 任意のインデックスのvectorを削除した場合は、 どのようにそのiteratorを取得するのでしょうか。 例えばv[5]を削除したのですが、 vector<myclass>::iterator it=v.begin(); for(int i=0;i<5;i++) it++; v.erase(it); というbegin()やend()からのインクリメント・デクリメントで取得するしかないのでしょうか? ご教示願います。

  • STL mapからの要素の削除

    mapより特定の値を持つ要素を削除したいのですが、上手くいきません。 下のようなコードで実現しようとしたのですが、eraseを呼んだ次のループでもう一度eraseを呼んで実行時エラーとなってしまうようです。 erase後のイテレータが指す値が悪いのではないかとは思うのですが、実際に何が悪いのかご存知の方がいらっしゃればアドバイスをお願いいたします。 string s[20]; char c='a'; map<string,bool> m; //mapへの要素の挿入 for(int j=0;j<20;j++){ s[j]=string(&c); c++; if(j%10==0) m[s[j]]=true; else m[s[j]]=false; } map<string,bool>::iterator i; //削除処理 for(i=m.begin();i!=m.end();i++){ if(i->second){ m.erase(i); } }

  • プログラミング

    以下のC++で書かれた以下のプログラムのコンパイルができません。理由を教えてください。 #include <iostream> #include <vector> #include <algorithm> istream& read(istream&, std::vector<double>&); double median(std::vector<double>); int main(){ std::vector<double> a; read(std::cin, a); std::vector<double>::iterator itr; while(itr != a.end()){ std::cout << *itr; } std::cout << median(a) << std::endl; } istream& read(istream& is, std::vector<double>& v){ double b; if(is){ while(in >> b) v.push_back(b); } return is; } double median(std::vector<double> a){ int i; if(a.size() == 0) { return -1; } i = a.size() / 2; if(a.size()%2 == 1) return (a[i]); else return ((a[i] + a[i-1])/2); }

  • STLベクトルコンテナ

    vectorの1次元目の要素と1次元目のサイズを常に持ち回す方法しか思いつきません。 int dim1size = 2; int dim1ite = 0; vector<vector<char *> > vec; vec.resize(dim1size); vec.at(dim1ite).reserve(2); どこかの関数で vec.at(dim1ite).push_back("浅倉"); vec.at(dim1ite).push_back("東京"); dim1ite++; どこかの関数で vec.at(dim1ite).push_back("稲垣"); vec.at(dim1ite).push_back("大阪"); dim1ite++; どこかの関数で vec.at(dim1ite).push_back("内山"); vec.at(dim1ite).push_back("名古屋"); dim1ite++; このようなソースです。 dim1sizeとdim1iteを持ち回さなくてもvecだけで1次元目のサイズを気にすることなくpush_backを実行するよい方法はありませんか? 上記ソースではpush_back("内山");の前にresizeが必要です。これを自動でやってほしいのです。

  • vector間における効率的な値の比較

    2つのベクターに入ったdoubleの網羅的な比較を行う関数をC++で書こうとしています。 (VC++ 2008) doubleのベクター vctr_1 , vctr_2 があるとします。 vctr_1 には (100.0, 200.5 , 300.1 , 400.0 ) vctr_2 には(50.0 , 70.2, 100.1, 220.0 , 300.0 ) というdouble の値が入っていて vctr_1の値のうち、vctr_2に近い値(誤差0.2以内)が見つかるものを.新しいベクターとして返すという処理を考えています。 この場合 100 : 100.1 と300.1: 300.0 が 誤差 0.2 未満で近い値といえ、100 と300.1が格納されたベクターを返す、という処理です。 私の考えた方法はベクターaの各要素に対してベクターbの各要素をループで比較する、というものでした。 以下コード ---------------------------- //比較を行う関数。ベクター1、2 要素の比較をし誤差内の数値をベクター1からとりだし、別のベクターとして返す。 vector<double> compare_doubles_with_tol(vector<double> v1,vector<double> v2 , double tol ){ //似た値を格納するベクター vector<double> v_match; //ベクター1に関してループ vector<double>::iterator it1 = v1.begin(); while( it1 != v1.end() ){ //ベクター2に関してループ vector<double>::iterator it2 = v2.begin(); while( it2 != v2.end() ){ //誤差内の値を見つける if( fabs(*it1 - *it2) < tol ){ v_match.push_back(*it1); } ++it2; } ++it1; } return v_match; } int main() { //ベクター1 std::vector<double> vctr_1; vctr_1.push_back(100.0); vctr_1.push_back(200.5); vctr_1.push_back(300.1); vctr_1.push_back(400.0); //ベクター2 std::vector<double> vctr_2; vctr_2.push_back(50.0); vctr_2.push_back(70.2); vctr_2.push_back(100.1); vctr_2.push_back(220.0); vctr_2.push_back(300.0); //誤差0.2内で似た値があるものを新たなベクターとして得る。 vector<double> matched = compare_doubles_with_tol(vctr_1,vctr_2,0.2); for (int i = 0 ; i < matched.size() ; ++i){ cout << matched[i]<<endl; } return 0; } ------------------------- このコードで望んだ結果は得られますがループの繰り返しを行っていて処理が遅くなってしまいます。実際の仕事ではベクターの要素数が100前後のものを非常に数多く処理しなければならず、このままでは処理時間が膨大なものになってしまいそうです。 このような場合どのような処理、コードを作成すれば処理速度の向上が望めるでしょうか。

  • VC++のデバッガでvectorの要素をウォッチしたい

    VC++のデバッガでSTLのvectorの要素をウォッチするやり方があったのですが 方法を忘れてしまいました^^; 例えば vector<int> v; v.push_back(1); v.push_back(2); などのようにしておいて、 デバッグ中にウォッチウィンドウ上で v[1]の要素の内容を表示する方法があったのですが・・・ 確か、v[1]の頭に何か修飾したような記憶がありますが 定かではありません。 どなたかご存知の方、教えてください。 宜しく御願いします。

  • n × n の二次元配列の各要素に vector を突っ込みたいと思っ

    n × n の二次元配列の各要素に vector を突っ込みたいと思っています。 ちょうど三次元グラフで n × n の地表に可変な高さの草が生えてるようなのを想像していただければやりたいことが分かっていただけるかと。 で、このようにしてまずは確保しました。 int i, n = 2; vector<int> ***vecMatrix; vecMatrix = new vector<int>**[ n ]; for (i = 0 ; i < n ; i++) vecMatrix[ i ] = new vector<int>*[ n ]; ここまでは問題ないのですが、次に vecMatrix[ i ][ j ] に対して要素を格納しようとして、 vecMatrix[ 0 ][ 0 ]->push_back( 1 ); とすると segmentation fault で落ちます。 ううーん、なぜでしょう。

  • C++ vectorのbeginについて

    VC++2010にて下記コードのビルドは通るのですが、 vVecotrInt, vVectorIntPtrの要素数0のとき、iptr代入時に Debug assertaion Failed! vector iterator not dereferencableとなります。 そもそもbegin()はイテレータなので、ポインタに代入しようとしていることが間違いかと思うのですが。 質問1.int* iptr = ~ ではなく、std:vector<int>::iteratorとすれば、     要素数が0でもエラーがおきません。この違いは何でしょうか? 質問2.そもそもイテレータをポインタに代入して何か得することがあるんでしょうか?     ただイテレータとポインタは同じようなものだと思って、コーディングしてるだけなんでしょうか・・・ コード: // vVectorIntの要素を間接参照して(参照先はint)、そのアドレスをポインタに格納 std::vector<int> vVectorInt; int* iptr = &*vVectorInt.begin(); // ここでvector iterator not dereferencable // vVectorIntPtrの要素を間接参照して(参照先はint*)、ポインタに格納 std::vector<int*> vVectorIntPtr; int* iptr = *vVectorIntPtr.begin(); // ここでvector iterator not dereferencable // vVecotrIntPtr2の要素数0のときでも、イテレータを使えば問題ない std::vector<int*> vVectorIntPtr2; std::vector<int*>::iterator itr = vVectorIntPtr2.begin();