這是一個使分配和分配數量最小化的代碼。它基於對類似問題的以下回答: https://stackoverflow.com/a/32322122/3903076
替換字符串長度爲0或1的情況分開處理。否則,弦必須增長。
如果沒有足夠的容量,那麼無論如何都需要一個外部緩衝區,所以我們只是進行復制替換和交換。
有趣的情況是,當字符串已經有足夠的容量,所以我們實際上可以做一個不平凡的原地替換。我們用反向複製替換來做到這一點,當我們不需要替換其他東西時停止。
這可以在函數的最後一行可以看出。
void replaceChar(std::string& input, const std::string& replacementString, char charToReplace)
{
if (replacementString.empty()) {
input.erase(std::remove(input.begin(), input.end(), charToReplace), input.end());
return;
}
if (replacementString.size() == 1) {
std::replace(input.begin(), input.end(), charToReplace, replacementString.front());
return;
}
const auto first_instance = std::find(input.begin(), input.end(), charToReplace);
auto count = std::count(first_instance, input.end(), charToReplace);
const auto extra_size = count * (replacementString.size() - 1);
const auto new_size = input.size() + extra_size;
if (input.capacity() < new_size) {
std::string aux;
aux.reserve(new_size);
replace_with_range_copy(input.cbegin(), input.cend(), std::back_inserter(aux), charToReplace, replacementString.cbegin(), replacementString.cend());
input.swap(aux);
return;
}
input.resize(new_size);
const auto rlast = std::make_reverse_iterator(first_instance);
const auto rfirst = input.rbegin();
const auto old_rfirst = rfirst + extra_size;
replace_with_range_copy(old_rfirst, rlast, rfirst, charToReplace, replacementString.crbegin(), replacementString.crend());
}
這裏是replace_with_range_copy
算法的實現:
template <typename InputIt1, typename OutputIt, typename T, typename InputIt2>
OutputIt replace_with_range_copy(InputIt1 first, InputIt1 last, OutputIt d_first, const T& old_value, InputIt2 new_first, InputIt2 new_last)
{
InputIt1 next;
while (true) {
if (first == last) return d_first;
next = std::find(first, last, old_value);
d_first = std::copy(first, next, d_first);
if (next == last) return d_first;
d_first = std::copy(new_first, new_last, d_first);
first = std::next(next);
}
}
你預計多餘的字符會去哪裏? – AShelly 2012-04-05 14:37:12
雅這就是我問的是,因爲我已經看到在java中的代碼實現計算字符串的新長度,並開始將字符從結尾到開始。這就是爲什麼我想知道的是java的是否允許在運行時字符串長度的這種類型的變化...... – Madu 2012-04-05 14:44:20
有插入一個字符串開頭的特定位置,消除在只有位置的字符的方式,但這樣會增加尺寸的內部緩衝區。 – hmjd 2012-04-05 14:44:37