如何在c++; 我知道C++只允许把2个字符串加在一起,即: s=s1+s2

如何在c++; 我知道C++只允许把2个字符串加在一起,即: s=s1+s2,c++,string,add,concat,C++,String,Add,Concat,但是我怎样才能把许多字符串加在一起呢?比如: s = s1 + s2 + s3 + s4 + ... + sn 首先,你可以把+sn做得很好。尽管假设您在C++03上使用std::basic_stringstring,这将花费指数四分位数(参见注释)时间 您可以使用std::basic_string::append和std::basic_string::reserve在O(n)时间内连接字符串 编辑:例如 string a; //either a.append(s1).append(s2).a

但是我怎样才能把许多字符串加在一起呢?比如:

s = s1 + s2 + s3 + s4 + ... + sn

首先,你可以把+sn做得很好。尽管假设您在C++03上使用
std::basic_string
string,这将花费指数四分位数(参见注释)时间

您可以使用
std::basic_string::append
std::basic_string::reserve
在O(n)时间内连接字符串

编辑:例如

string a;
//either
a.append(s1).append(s2).append(s3);
//or
a.append("I'm a string!").append("I am another string!");

如果您试图附加std::string类的string对象,这应该可以工作

string s1 = "string1";
string s2 = "string2";
string s3 = "string3";

string s = s1 + s2 + s3;

string s = string("s1") + string("s2") + string("s3") ...
尽管它可以创建很多临时文件(一个好的优化编译器应该会有帮助),但它仍然可以工作,因为它可以有效地解释为:

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());
std::ostringstream out;

out使用模板添加字符串,char*和char’s组成字符串

斯特伦:-

#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...);
    }
#包括
#包括
//它需要为for(:)循环包装一对迭代器
模板
把它分成两类
{
它是b;
它是e;
公众:
自动开始()常量
{
返回b;
}
自动结束()常量
{
返回e;
}
};
//字符串长度
模板自动strlen(常数S&S)->decltype(S.size())
{
返回s.size();
}
自动字符串(字符c)->大小
{
返回1u;
}
自动字符串(常量标准::初始值设定项\u列表和il)->大小\u t
{
返回il.size();
}
模板
自动strlen(const it\u pair&p)
{
自动长度=大小{};
用于(const auto&s:p)
len+=strlen(s);
回程透镜;
}
模板自动序列号(S、SS和…SS)->大小
{
返回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));
    }
//终止递归
模板
无效附加(TA&a、TB&b)
{
a、 附加(b);
}
//字符的特殊情况
模板
void追加(std::string&a、const char&b)
{
a、 附加(1,b);
}
//字符串集合的特殊情况
模板
无效附加(TA&a、const it\u pair&p)
{
用于(常量自动和x:p)
a、 附加(x);
}
//递归附加
模板
无效附加(TA&a、TB&b、TT和…TT)
{
附加(a,b);
附加(a,tt…);
}
模板
std::string_add(常量TT&…TT)
{
std::字符串s;
s、 保留地(斯特伦(tt…);
附加(s,tt…);
返回s;
}
模板
自动生成it对(it b、it e)
{
返回它_对{b,e};
}
模板
自动生成it对(常数T&T)
{
使用名称空间std;
返回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));
    }
intmain()
{
常量字符*s[]={“vw”,“xyz”};
向量v{“l”,“mn”,“opqr”};
std::字符串a(“a”);
std::字符串b(“bc”);
std::字符串c(“def”);

std::cout如果你想做到这一点

  • ,即不产生二次时间
  • 不覆盖原始变量
  • 不创建临时变量
这样就可以了

auto s = std::string(s1).append(s2).append(s3).append(sn);  
如果你喜欢格式很好的东西

auto s = std::string(s1).append(s2)
                        .append(s3)
                        .append(sn)

为什么你认为这不起作用?你在使用字符串类吗?是的,我注意到它只在使用string类时起作用。但是我想在C++中这样做,定义ST“BLAH3”s= S1+“BLAH1”+“BLAH2”。 + St@tsubasa:当然,您不能。如果您在编译时知道两个文本,只需将它们相邻放置即可允许它们在预处理器中串联。即,
“asd”“123”
变成
“asd123”
。但是运行时添加字符串需要使用字符串类。@比利:它本身不会添加指针值。它会尝试编译,但编译失败。+1-使用
运算符+(std::basic\u string,std::basic\u string)时请记住
在C++03中会产生指数时间。相比之下,使用
std::basic_string::append
成员函数只需要线性时间。我认为string s=string(“s1”)+string(“s2”)+string(“s3”)…是我正在寻找的东西。我想知道为什么它会起作用?因为使用string(x)时就是这样的,为x上的标准字符串类调用构造函数。创建一个临时字符串对象,然后该对象可以与其运算符+(这种类型的工作方式类似于cast)@tsubasa:如果您只需确保第一项是
string
,那么
string(“s1”)+“s2”+“s3”就足够了
也可以工作。原因是像
“s1”
这样的普通字符串常量属于
const char*
类型,您不能只将这些指针添加在一起。
string
对象另一方面知道如何添加
const char*
以形成新的
字符串。(还有:这里没有什么会使用指数时间,所以不要太担心)@BillyONeal:你确定这是指数时间吗?看O(N^2)对我来说,这不需要指数时间,只需要二次型。
append
会更快,但总的来说是二次型的,因为它需要一次又一次地重新分配形式。不过,在大多数情况下,这两种方法都不会慢到引人注目的程度。@BillyONeal:为什么会是指数型的?你提到的总和等于
(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
,它是线性的。关于
append()
:我似乎错过了您提到的
reserve()
。与
reserve()一起使用
它确实是线性的。@sth即使没有保留足够的空间,
append
也需要线性摊销时间,这比quadratic@BillyONeal你可以说它是指数的
auto s = std::string(s1).append(s2)
                        .append(s3)
                        .append(sn)