C ++中的字符串乘法

时间:2016-02-19 13:39:07

标签: c++ string multiplication repeat

这里已经存在一个问题:How to repeat a string a variable number of times in C++?但是因为问题制定得很差,主要是给出了关于字符乘法的答案。有两个正确但昂贵的答案,所以我会在这里提高要求。

Perl提供了x运算符:http://perldoc.perl.org/perlop.html#Multiplicative-Operators,我可以这样做:

$foo = "0, " x $bar;

我知道我可以使用辅助功能执行此操作,例如其他答案中的辅助功能。我想知道我可以在没有自己的辅助功能的情况下这样做吗?我倾向于初始化const string,但如果我不能这样做,我很确定这可以用标准算法和lambda来回答。

2 个答案:

答案 0 :(得分:3)

您可以覆盖乘法运算符

#include <string>
#include <sstream>
#include <iostream>


std::string operator*(const std::string& str, size_t times)
{
    std::stringstream stream;
    for (size_t i = 0; i < times; i++) stream << str;
    return stream.str();
}

int main() {
    std::string s = "Hello World!";
    size_t times = 5;

    std::string repeated = s * times;
    std::cout << repeated << std::endl;

    return 0;
}

......或者使用lambda ......

#include <string>
#include <sstream>
#include <iostream>

int main() {
    std::string s = "Hello World!";
    size_t times = 5;

    std::string repeated = [](const std::string& str, size_t times) {std::stringstream stream; for (size_t i = 0; i < times; i++) stream << str; return stream.str(); } (s, times);
    std::cout << repeated << std::endl;

    return 0;
}

...或者使用带参考捕获的lambda ...

#include <string>
#include <sstream>
#include <iostream>

int main() {
    std::string s = "Hello World!";
    size_t times = 5;

    std::string repeated = [&s, &times]() {std::stringstream stream; for (size_t i = 0; i < times; i++) stream << str; return stream.str(); }();
    std::cout << repeated << std::endl;

    return 0;
}

您可以将std::stringstreamstd::string结合使用,而不是使用std::string::reserve(size_t),因为您已经知道(或可以计算)结果字符串的大小。

std::string repeated; repeated.reserve(str.size() * times);
for (size_t i = 0; i < times; i++) repeated.append(str);
return repeated;

这可能会更快:将http://goo.gl/92hH9Mhttp://goo.gl/zkgK4T

进行比较

答案 1 :(得分:0)

可以使用标准算法和带有generate_n的lambda来完成此操作,但它仍然无法初始化const string它需要在单独的行中完成:

string foo;
const auto bar = 13U;

generate_n(back_inserter(foo), bar * 3U, [](){
    static const char multiplicand[] = "0, ";
    static const auto length = strlen(multiplicand);
    static auto i = 0U;
    return multiplicand[i++ % length];});

我在这里创建了一个实例:http://ideone.com/uIt2Ee但是,所有问题评论可能已经明确表示,在一行中执行此操作的要求导致代码较差。马上,我们可以看到裸常量3表示multiplicand的大小,并且不必要地更改multiplicand的初始化以更新此文字。

应该做出明显的改进:

string foo;
const auto bar = 13U;
const char multiplicand[] = "0, ";
const auto length = strlen(multiplicand);

generate_n(back_inserter(foo), bar * length, [&](){
    static auto i = 0U;
    return multiplicand[i++ % length];
});

下一个改进是在foo增长时消除重新分配,如果barlength很大,这可能会很昂贵。这可以通过构造foo来实现,其中有足够的空间来包含整个生成的字符串:

const auto bar = 13U;
const char multiplicand[] = "0, ";
const auto length = strlen(multiplicand);
string foo(bar * length, '\0');

generate_n(foo.begin(), bar * length, [&](){
    static auto i = 0U;
    return multiplicand[i++ % length];
});

[Live Example]