2012-01-29 18 views
12

文字列のベクトルを実行し、長さ3以下の文字列を削除する関数を作成しました。これは、STLアルゴリズムライブラリを使用する際の教訓です。remove_if()を実行した後の消去()

私は関数が機能するだけでなく、長さ3以下の文字列を削除するだけでなく、最後に文字列 "vector"を追加するという点で問題があります。

出力は

This test vector 

でなければなりませんし、代わりにそれは私がそれを修正するにはどうすればよい

This test vector vector" 

のですか?

あなたは、消去の2つのパラメータ形式を使用する必要があります
/* 
* using remove_if and custom call back function, write RemoveShortWords 
* that accepts a vector<string> and removes all strings of length 3 or 
* less from it. *shoot for 2 lines of code in functions. 
*/ 

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <vector> 
#include <iterator> 
using namespace std; 

bool StringLengthTest(string test) //test condition for remove_if algo. 
{ 
    return test.length() <= 3; 
} 

void RemoveShortWords(vector<string> &myVector) 
{ 
    //erase anything in vector with length <= 3 
    myVector.erase(remove_if(myVector.begin(), 
          myVector.end(), 
          StringLengthTest)); 
} 

int main() 
{ 
    //add some strings to vector 
    vector<string> myVector; 
    myVector.push_back("This"); 
    myVector.push_back("is"); 
    myVector.push_back("a"); 
    myVector.push_back("test"); 
    myVector.push_back("vector"); 

    //print out contents of myVector (debugging) 
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," ")); 
    cout << endl; //flush the stream 

    RemoveShortWords(myVector); //remove words with length <= 3 

    //print out myVector (debugging) 
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," ")); 
    cout << endl; 

    system("pause"); 
    return 0; 
} 

答えて

23

それはあなたが文を区切る場合は、これを理解するのが最も簡単です:

auto iter(remove_if(myVector.begin(), myVector.end(), StringLengthTest)); 
myVector.erase(iter); 

これらの2行は同じことを行いますあなたの一行として。そして、 "バグ"が何であるかは今明らかであるはずです。 remove_ifが最初に動作します。これはベクトル全体を反復処理し、すべての「選択された」エントリを「最後まで」移動します(より良い選択:非選択のエントリを前面に移動させます)。それはエントリーの上で左の「最後」の位置にイテレータを返す実行した後、何かのように:

この
テスト
ベクトル
テスト< - ここイテレータポイント
ベクトル

次に、1つのイテレータで消去を実行します。つまり、指し示されている1つの要素を消去して、 "test"要素を消去します。 - 残っているのはあなたが見ているものです。最後にremove_ifによって返されたベクトルから消去単にそれを修正する

():

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest), myVector.end()); //erase anything in vector with length <= 3 
+0

素晴らしい詳細。何が起こっているのかを明確にしてくれてありがとう! – MCP

+2

これは、 'myVector'が空であれば、これはさらに大きくなります。それで 'iter'は' myVector.end() 'と等しくなり、' erase(iter) 'を使って消去するとUBにつながります。 – Ruslan

10

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest), 
       myVector.end()); 
+0

偉大な答え。ありがとう! – MCP

関連する問題