2013-04-14 20 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); 

     } 
    } 

} 

Chciałbym, aby ta funkcja zastąpiła wszystkie wystąpienia ciągu znaków starego w wektorze zastępowaniem ciągu znaków. Ale wywołując tę ​​funkcję, po prostu nie zmienia w ogóle wektora. Nie jestem pewien, czy używam poprawnie funkcji usuwania i wstawiania. Jakieś pomysły?Zastępowanie elementów w wektorze za pomocą wymazywania i wstawiania

+3

nie należy przekazać wektor jako _reference_? –

+0

Ah man, czuję się teraz tak głupi ... Dzięki! –

+5

Nie trzeba wymazywać ani wstawiać. Po prostu przypisz: '* it = replacement;'. Eliminuje to wszelkie problemy związane z unieważnieniem iteratora i usuwa szereg mieszania w celu usunięcia elementu, a następnie otwiera otwór do wstawienia w miejscu, w którym znajdował się ten element. –

Odpowiedz

7

Na początku musisz przekazać wektor przez odniesienie, a nie według wartości.

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

drugie erase i wstawić invalidates go, trzeba zaktualizować go nowym iterator zwrócony przez erase

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

Czy to nie jest UB? Wspomnienie "to" po wywołaniu "wymazywania" to UB, a ty wspominasz 'it' w twoim wywołaniu' wstawiania'. Myślę, że musisz użyć obejścia z 'std :: distance'. –

+0

@Enn - czy nie zauważyłeś, że "to" jest przypisane z * wynikiem * z 'erase()'? Nie można użyć unieważnionego iteratora, ponieważ 'it' posiada teraz poprawny iterator; to samo dotyczy następującej linii 'insert()'. –

+0

Najwyraźniej ja nie ... –

2

są przechodzącą swojej std::vector jako wartość. Aby zmienić std::vector przekazać do funkcji, zadeklarować ją jako punkt odniesienia

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

& oznacza, że ​​zdasz std::vector przez odniesienie i dzięki czemu można uzyskać dostęp do obiektu, który minął.

I nie kasuj elementu, po prostu go wymień.

3
Nie

AN gotowe algorithm dla swojego problemu:

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

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

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

Warto lub nie warto zauważyć, że dedukuje to 'T' w' replace' jako 'char [4]'. Operacje, które mieszają 'string' i' const char * 'powinny być wydajne, więc nie sądzę, aby miało to znaczenie w tym przypadku, ale jeśli chcesz przekazać ciągi literowe o różnych długościach, potrzebujesz konwersji. –

Powiązane problemy