Есть ли способ реализовать аналог Python 'separator'.join() в С++?
Все, что я нашел, это boost::algorithm::string::join
. Тем не менее, кажется, что overkill использует Boost только для соединения. Так, может быть, есть некоторые проверенные временем рецепты?
UPDATE:
К сожалению, заголовок вопроса был плохим.
Я ищу метод для объединения строк с разделителем, а не только для конкатенации один за другим.
Ответы
Ответ 1
Так как вы ищете рецепт, используйте его и используйте Boost. После того, как вы преодолеете всю родословность, это не слишком сложно:
- Выделите место для хранения результата.
- Добавить первый элемент последовательности в результат.
- Пока есть дополнительные элементы, добавьте разделитель и следующий элемент в результат.
- Верните результат.
Здесь версия, которая работает на двух итераторах (в отличие от версии Boost, которая работает в диапазоне.
template <typename Iter>
std::string join(Iter begin, Iter end, std::string const& separator)
{
std::ostringstream result;
if (begin != end)
result << *begin++;
while (begin != end)
result << separator << *begin++;
return result.str();
}
Ответ 2
Если вы действительно хотите ''.join()
, вы можете использовать std::copy
с std::ostream_iterator
до std::stringstream
.
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
std::vector<int> values(); // initialize these
std::stringstream buffer;
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(buffer));
Это введет все значения в buffer
. Вы также можете указать пользовательский разделитель для std::ostream_iterator
, но это будет добавлено в конце (это существенная разница с join
). Если вам не нужен разделитель, это сделает именно то, что вы хотите.
Ответ 3
Строки С++ реализованы эффективно.
std::string s = s1 + s2 + s3;
Это может быть быстрее:
std::string str;
str.reserve(total_size_to_concat);
for (std::size_t i = 0; i < s.length(); i++)
{
str.append(s[i], s[i].length());
}
Но это в основном то, что ваш компилятор делает с operator+
и минимум оптимизации, за исключением того, что он угадывает размер резерва.
Не стесняйтесь. Посмотрите реализацию строк.:)
Ответ 4
Если вы используете Qt в своем проекте, вы можете напрямую использовать функцию join
QString (QString Reference), и она работает как ожидалось из python. Некоторые примеры:
QStringList strList;
qDebug() << strList.join(" and ");
Результат: ""
strList << "id = 1";
qDebug() << strList.join(" and ");
Результат: "id = 1"
strList << "name = me";
qDebug() << strList.join(" and ");
Результат: "id = 1 and name = me"
Ответ 5
Вот еще одна версия, которую я считаю более удобной в использовании:
std::string join(std::initializer_list<std::string> initList, const std::string& separator = "\\")
{
std::string s;
for(const auto& i : initList)
{
if(s.empty())
{
s = i;
}
else
{
s += separator + i;
}
}
return s;
}
Затем вы можете называть это следующим образом:
join({"C:", "Program Files", "..."});