创建包含另一个字符串的多个副本的字符串的最佳方法

时间:2010-01-11 15:01:36

标签: c++ string

我想创建一个函数,它将一个字符串和一个整数作为参数,并返回一个包含重复给定次数的字符串参数的字符串。

例如:

std::string MakeDuplicate( const std::string& str, int x )
{
    ...
}

致电MakeDuplicate( "abc", 3 );将返回"abcabcabc"

我知道我可以通过循环x次来做到这一点,但我确信必须有更好的方法。

4 个答案:

答案 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 !!

递归显然不是计算机科学中用于与循环相同工作的构造