据我所知,C++只允许将两个字符串相加,即:
s = s1 + s2
但是如何将多个字符串拼接在一起呢?例如:
s = s1 + s2 + s3 + s4 + ... + sn
据我所知,C++只允许将两个字符串相加,即:
s = s1 + s2
但是如何将多个字符串拼接在一起呢?例如:
s = s1 + s2 + s3 + s4 + ... + sn
string s1 = "string1";
string s2 = "string2";
string s3 = "string3";
string s = s1 + s2 + s3;
或者
string s = string("s1") + string("s2") + string("s3") ...
operator+(std::basic_string<t>, std::basic_string<t>)
会产生指数级的时间复杂度。与之相比,使用std::basic_string<t>::append
成员函数只需要线性时间。 - Billy ONealstring("s1") + "s2" + "s3"
也可以工作。原因是普通的字符串常量如“s1”属于类型const char *
,您不能将这些指针简单地相加。另一方面,string
对象知道如何添加const char *
以形成新的string
。(另外:在这里没有使用指数时间,所以不用太担心) - sthstring a;
//either
a.append(s1).append(s2).append(s3);
//or
a.append("I'm a string!").append("I am another string!");
append
会更快,但通常仍然是二次时间,因为它需要不时重新分配内存。在大多数情况下,这两种方法都不会慢到能够被察觉到。 - sth(0*N + N) + (1*N + N) + (2*N + N) + ... + ((K-1)*N + N)
,这相当于(1+2+...+(K-1)) * N + K*N
=(K*(K-1)/2) * N + K*N
=((K^2 + K) / 2) * N
=O(K^2 * N)
。因此,它在部分数量K
方面是二次的,在每个部分中的字符数量N
方面是线性的。 - sthappend()
:我好像错过了你提到的reserve()
。如果与reserve()
一起使用,它确实是线性的。 - sthappend
函数也会以线性摊销时间运行,这比平方级别的时间要快得多。 - fredoverflows = s1 + s2 + s3 + .. + sn;
尽管可能会创建很多临时变量(一个好的优化编译器应该会有所帮助),但这段代码仍然可以工作,因为它将有效地被解释为:
string tmp1 = s1 + s2;
string tmp2 = tmp1 + s3;
string tmp3 = tmp2 + s4;
...
s = tmpn + sn;
s = s1;
s += s2;
s += s3;
...
s += sn;
std::ostringstream
是专为此而构建的,可以看这里的示例(点击此处)。使用起来很简单:
std::ostringstream out;
out << "a" << "b" << "c" << .... << "z";
std::string str( out.str());
请使用模板添加字符串、char*和char,以形成字符串。
strlen:-
#include <iostream>
#include <cstring>
// it_pair to wrap a pair of iterators for a for(:) loop
template<typename IT>
class it_pair
{
IT b;
IT e;
public:
auto begin() const
{
return b;
}
auto end() const
{
return e;
}
};
// string length
template<typename S> auto strlen(const S& s) -> decltype(s.size())
{
return s.size();
}
auto strlen(char c) -> size_t
{
return 1u;
}
auto strlen(const std::initializer_list<char>& il) -> size_t
{
return il.size();
}
template<typename IT>
auto strlen(const it_pair<IT>& p)
{
auto len = size_t{};
for(const auto& s:p)
len += strlen(s);
return len;
}
template<typename S, typename ...SS> auto strlen(S s, SS&... ss) -> size_t
{
return strlen(s) + strlen(ss...);
}
// terminate recursion
template<typename TA, typename TB>
void append(TA& a, TB& b)
{
a.append(b);
}
// special case for a character
template<>
void append<std::string, const char>(std::string& a, const char& b)
{
a.append(1, b);
}
// special case for a collection of strings
template<typename TA, typename TB>
void append(TA& a, const it_pair<TB>& p)
{
for(const auto& x: p)
a.append(x);
}
// recursion append
template<typename TA, typename TB, typename ...TT>
void append(TA& a, TB& b, TT&... tt)
{
append(a, b);
append(a, tt...);
}
template<typename ...TT>
std::string string_add(const TT& ... tt)
{
std::string s;
s.reserve(strlen(tt...));
append(s, tt...);
return s;
}
template<typename IT>
auto make_it_pair(IT b, IT e)
{
return it_pair<IT>{b, e};
}
template<typename T>
auto make_it_pair(const T& t)
{
using namespace std;
return make_it_pair(cbegin(t), cend(t));
}
int main()
{
const char * s[] = {"vw", "xyz"};
std::vector<std::string> v{"l", "mn", "opqr"};
std::string a("a");
std::string b("bc");
std::string c("def");
std::cout << string_add(a, b+c, "ghij", make_it_pair(v), 'k', make_it_pair(s));
}
auto s = std::string(s1).append(s2).append(s3).append(sn);
如果你喜欢事情有良好的格式
auto s = std::string(s1).append(s2)
.append(s3)
.append(sn)
"asd" "123"
变成了"asd123"
。但是,运行时字符串的添加需要使用字符串类。 - GManNickG"blah1" + "blah2"
是不对的。它将会把指针值相加而非连接字符串。 - Billy ONeal