2013-04-14 12 views
5
void replace(vector<string> my_vector_2, string old, string replacement){ 

    vector<string>::iterator it; 
    for (it = my_vector_2.begin(); it != my_vector_2.end(); ++it){ 

     if (*it==old){ 
      my_vector_2.erase(it); 
      my_vector_2.insert(it,replacement); 

     } 
    } 

} 

したがって、この関数は、ベクトル内の古い文字列のすべての文字列を置換文字列で置き換えることができます。しかし、この関数を呼び出すときには、ベクトルをまったく変更しません。私は、消去と挿入機能を正しく使用しているかどうかはわかりません。何か案は?削除と挿入を使用してベクトル内の要素を置換する

+3

あなたは_reference_としてベクトルを渡すべきではないでしょうか。 –

+0

ああ、私は今、とても馬鹿だと感じています....ありがとう! –

+5

消去して挿入する必要はありません。 '* it = replacement;'を代入するだけです。これにより、イテレータの無効化に関する問題はなくなり、要素を削除するための一連の変更が削除され、その要素があった場所に挿入するための穴が開かれます。 –

答えて

7

まず、値ではなく参照によってベクトルを渡す必要があります。

void replace(vector<string>& my_vector_2, string old, string replacement){ 

第2の消去とinvalidatesにそれを挿入し、あなたはあなたが値としてごstd::vectorを渡している消去

it = my_vector_2.erase(it); 
it = my_vector_2.insert(it,replacement); 
+0

このUBではありませんか? '消去 'の呼び出し後に' it'をUBと言い、 'insert'へのあなたの呼び出しで' it'と言います。私は 'std :: distance'で回避策を使わなければならないと思います。 –

+0

@Enn - 'it'に' erase() 'の* result *が割り当てられていることに気付かなかったのですか? 'it'は有効なイテレータを保持しているので、無効化されたイテレータは使用できません。次の 'insert()'行についても同様です。 –

+0

明らかに私はしなかった... –

2

によって返された新しいイテレータでそれを更新する必要があります。 std::vectorあなたが関数に渡すを変更するために、

void replace(vector<string>& my_vector_2, string old, string replacement){ } 

参照としてそれを宣言する&は、あなたが参照してstd::vectorを渡すので、あなたが渡されたオブジェクトにアクセスできることを意味します。

要素を消去しないで置き換えてください。

3

既製algorithmは、あなたの問題のためにあります:

#include <algorithm> 
#include <string> 
#include <vector> 

std::vector<std::string> v; // populate 

std::replace(v.begin(), v.end(), "old", "new"); 
+0

これは、 'replace'の' T'を 'char [4]'と推論する価値があるかもしれません。 'string'と' const char * 'を組み合わせた演算は効率的なはずですので、この場合は問題はないと思いますが、長さの異なる文字列リテラルを渡したい場合は変換が必要です。 –

関連する問題