代码之家  ›  专栏  ›  技术社区  ›  Richard

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

  •  5
  • Richard  · 技术社区  · 15 年前

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

    例如:

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

    打电话 MakeDuplicate( "abc", 3 ); 会回来 "abcabcabc" .

    我知道我只需要循环X次就可以做到这一点,但我相信一定有更好的方法。

    4 回复  |  直到 15 年前
        1
  •  19
  •   luke    15 年前

    我不认为循环有问题,只要先确定你做了预订:

    std::string MakeDuplicate( const std::string& str, int x )
    {
        std::string newstr;
        newstr.reserve(str.length()*x); // prevents multiple reallocations
    
        // loop...
    
        return newstr;
    }
    
        2
  •  7
  •   John Weldon user3678248    15 年前

    在某种程度上,它必须是一个循环。你可以用一些花哨的语言习语来隐藏循环,但最终你必须循环。

        3
  •  4
  •   MaR    15 年前

    对于小“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加速确实很重要(对数n与n的复杂性)。很好,我就是想不出什么真正的问题可以用:o)

        4
  •  2
  •   Hassan Syed    15 年前

    有一个循环的替代方法,它被称为 recursion ,和递归的 tail-recursion 从理论上说,你可以一直做到时间结束,就像一个循环:d

    P.S.,尾部递归通常是循环的语法糖——然而,在过程语言(C++)的情况下,编译器通常处于丢失状态,因此尾递归没有优化,并且可能内存不足(但如果你写的内存比你的大问题内存不足):D

    请投更多的反对票!!

    递归显然不是计算机科学中用于循环的构造。