2013-07-11 4 views
1

Я пишу функцию, которая принимает три параметра:Замена всех вхождений подстроки с другой подстроки в длинной череде

  • target: Target Строка
  • oldVal: Старый подстрока
  • newVal: Новая подстройка (для замены oldVal)

Задача этой функции - найти все возникновение oldVal в target и замените их на newVal.

Это функция у меня есть на данный момент:

std::string replace_old_with_new(std::string target, std::string oldVal, std::string newVal) { 

    std::cout << "target : " << target << ", oldVal: " << oldVal << ", newVal: " << newVal << "\n"; 
    std::string::iterator begin = target.begin(); 
    std::string::iterator oldValBegin = oldVal.begin(); 

    while (begin != target.end()) { 
     if (*begin == *oldValBegin) { 
      target = target.replace(begin, begin + oldVal.size(), oldVal); 
      begin = target.begin(); 
     } else { 
      ++begin; 
     } 
    } 

    return target; 
} 

Следующий вызов функции выше:

replace_old_with_new("Hello! hi hi!", "hi", "bye"); 

должна возвращать строку -

"Hello! bye bye!" 

Но когда я запускаю код, ничего не происходит. Кажется, я застрял в бесконечном цикле. Курсор продолжает мигать на терминале. Что-то не так с моей функцией. Я думаю, что может беспокоить звонок replace в блоке if. Это правильный способ использования диапазона итераторов в вызове функции replace? Я могу сделать это с erase и insert. Но я хочу использовать здесь replace.

+0

Возможный дубликат http://stackoverflow.com/questions/4643512/replace-substring-with-another-substring-c – alexbuisson

+0

Существует некоторая сложная бухгалтерская отчетность, необходимая для отслеживания того, где вы находитесь, когда выполняете замену. Если текст замены короче, чем заменяемый текст, вы можете сделать это довольно легко, но если заменяющий текст длиннее, чем заменяемый текст, вы должны перемещать хвост строки достаточно далеко, чтобы оставить место для нового текста; если вы делаете это многократно, вы в конечном итоге делаете много копий, что делает его очень медленным. –

+0

Версия решения Pete Becker находится в моем посте: -> http://stackoverflow.com/questions/20406744/ – Adolfo

ответ

3

Строки гораздо умнее, чем вы им даете. Они знают, как искать, поэтому вам не нужно это делать самостоятельно.

int pos = 0; 
int match_pos; 
std::string result; 
while ((match_pos = target.find(oldVal, pos)) != std::string::npos) { 
    result += target.substr(pos, match_pos - pos); 
    result += newVal; 
    pos = match_pos + target.size(); 
} 
result += target.substr(pos, std::string::npos); 

Извините, это эскиз; не тестировался, но вы поняли эту идею.

+0

Спасибо @Pete. Не дошел до функции 'find'. Значит, не знал об этом. Попробуй свой solutin. –

+0

@ Наваз - спасибо. Я исправил это в ** первом ** месте, где я это сделал. :-( –

+0

Я думаю, что эта строка «pos = match_pos + target.size();» должна быть «pos = match_pos + newVal.size();» – Ragnar

Смежные вопросы