Чтобы обратить строку «на месте», не используя временной строки, используйте шаблон функции reverse из заголовочного файла :
std::reverse(s.begin(), s.end());
reverse работает очень просто: она изменяет диапазон, переданный ей, так, что его порядок меняется на обратный оригинальному. Время, необходимое для этого, линейно зависит от длины диапазона.
В случае, если требуется
std::string s = "Los Angeles";
std::string rs;
rs.assign(s.rbegin(), s.rend());
rbegin и rend возвращают реверсивные итераторы. Реверсивные итераторы ведут себя так, как будто они просматривают последовательность в обратном порядке. rbegin возвращает итератор, который указывает на последний элемент, a rend возвращает итератор, указывающий на позицию перед первым элементом. Это в точности обратно тому, что делают begin и end.
Но rbegin и rend для обратной строки можно использовать все методы или алгоритмы, работающие с диапазонами итераторов. А если требуется выполнить поиск в строке, то можно использовать rfind, которая делает то же, что и find, но начинает с конца строки и движется к ее началу. Для больших строк или большого количества строк обращение может оказаться очень дорогостоящим, так что при возможности избегайте его.
4.6. Разделение строки
Требуется разделить строку с разделителями на несколько строк. Например, может потребоваться разделить строку "Name|Address|Phone" на три отдельных строки — "Name", "Address" и "Phone", удалив при этом разделитель.
Для перехода от одного вхождения разделителя к следующему используйте метод find класса basic_string, а для копирования каждой подстроки используйте substr. Для хранения результатов используйте любую стандартную последовательность. Пример 4.10 использует vector.
#include
#include
#include
#include
using namespace std;
void split(const string& s, char c, vector
string::size_type i = 0;
string::size_type j = s.find(c);
while (j != string::npos) {
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
v.push_back(s.substr(i, s.length()));
}
}
int main() {
vector
string s = "Account Name|Address 1|Address 2 |City";
split(s, '|', v);
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << '\n';
}
}
Превращение приведенного выше примера в шаблон функции, принимающий любой тип символов, тривиально — просто параметризуйте тип символов и замените случаи использования string на basic_string.
template
void split(const basic_string
vector
basic_string
basic_string
while (j != basic_string
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == basic_string
v.push back(s.substr(i, s.length()));
}
}
Логика при этом не меняется.