我想创建一个函数,它将一个字符串和一个整数作为参数,并返回一个包含重复给定次数的字符串参数的字符串。
例如:
std::string MakeDuplicate( const std::string& str, int x )
{
...
}
致电MakeDuplicate( "abc", 3 );
将返回"abcabcabc"
。
我知道我可以通过循环x次来做到这一点,但我确信必须有更好的方法。
答案 0 :(得分:19)
我没有看到循环问题,只要确保先进行预留:
std::string MakeDuplicate( const std::string& str, int x )
{
std::string newstr;
newstr.reserve(str.length()*x); // prevents multiple reallocations
// loop...
return newstr;
}
答案 1 :(得分:7)
在某些时候它必须是一个循环。你可能能够隐藏一些奇特的语言习惯,但最终你将不得不循环。
答案 2 :(得分:4)
对于小'x'简单循环是你的朋友。对于大的'x和相对较短的'str',我们可以通过重用已经连接的字符串来思考“更智能”的解决方案。
std::string MakeDuplicate( const std::string& str, unsigned int x ) {
std::string newstr;
if (x>0) {
unsigned int y = 2;
newstr.reserve(str.length()*x);
newstr.append(str);
while (y<x) {
newstr.append(newstr);
y*=2;
}
newstr.append(newstr.c_str(), (x-y/2)*str.length());
}
return newstr;
}
或类似的东西:o)(我认为它可以用更好的方式编写,但有想法)。
编辑:我对自己感兴趣并做了一些测试,比较笔记本上的三个解决方案和visual studio(重用版本,带预分配的简单循环,简单复制和没有预分配的循环-1)。结果如预期的那样:对于小x(<10)预分配版本通常最快,没有预分配稍微慢一点,因为'重复'版本的更大x加速非常重要(log n vs n复杂度)。很好,我只是想不出任何可以使用它的真正问题:o)答案 3 :(得分:2)
有一个循环的替代品,它叫recursion,递归tail-recursion是最好的变种,因为理论上你可以直到时间结束 - 就像一个循环:D
ps,尾递归通常是循环的语法糖 - 但是在过程语言(C ++)的情况下,编译器通常处于丢失状态,因此尾递归不会被优化,并且可能会耗尽内存(但是如果你写了一个内存耗尽而不是你有更大问题的递归):D
更多downvotes please !!
递归显然不是计算机科学中用于与循环相同工作的构造