【问题标题】:Is it a good practice to use + for string in c++在 c++ 中使用 + 作为字符串是一种好习惯吗
【发布时间】:2020-08-13 06:16:46
【问题描述】:

在 C++ 中,使用 + 进行字符串连接是一件坏事吗?例如下面,

string str = "";
int n = 10;
for (int i = 0; i < n; i++) {
  str += i + '0';
}

这段代码 sn-p 的时间复杂度是多少?是 O(n) 吗? C++ 中的字符串 + 运算符是否像矢量的 push_back 一样,并且在末尾添加项目时,如果需要,它会自行动态增长,从而使平均时间保持不变?

更新: 还有一个问题:如果我需要将 char 附加到字符串但不知道前面的长度是多少,如果不使用 + 运算符,最好的方法是什么?我知道在 Java 中,我们有 stringbuilder,我们有类似的东西 c++ std 吗?

【问题讨论】:

  • 可能是的,但不能保证:en.cppreference.com/w/cpp/string/basic_string/operator%2B%3D。您是否尝试过对代码进行基准测试?
  • 怀疑是n,也许是log n * n。许多因素都在起作用。但是对于这么小的n,不太可能看到性能差异。
  • 确保第一个参数是std::string 而不是char[]const char[]。例如str += "hello" + i + '0'; 将不起作用。

标签: c++


【解决方案1】:

我喜欢 std::string 的 operator+,因为它简单易懂的代码。

但是,如果连接太多,可能会频繁重新分配内存,并且每次重新分配时,也会发生内存复制。我更喜欢调用reserve(),它会提前分配足够的内存,并连接字符串。

string str;
int n = 10;
str.reserve(n);
for (int i = 0; i < n; i++) {
  str += i + '0';
}

【讨论】:

    【解决方案2】:

    C++ 中的字符串+= 运算符是否像向量的push_back() ...?

    不,std::stringoperator+=() 调用 append() 并返回 this

    假设一个程序:

    #include <iostream>
    
    int main(void) {
        std::string str1 = "Hello";
        std::string str2 = "World";
        str1 += str2;
        std::cout << str1;
    }
    

    注意语法:

    str1 += str2;
    

    这里的operator+=()会调用String类中的重载运算符+=

    basic_string& operator+=(const basic_string& __str)
          { return this->append(__str); }
    

    很明显,我们可以看到这里使用了append() 函数。不是push_back()

    例外: 在 Libstdc++(它是 GCC 的一部分,是用依赖于 Glibc 的 C++ 编写的)中,传递的参数是 char,并在调用 operator+=() 时应用 push_back() 函数。

    【讨论】:

    • 请注意,传递给operator+ 的参数是char,而不是std::string。在libstdc++operator+= 中带有char 参数calls this-&gt;push_back
    • @Evg 我明白了,我不知道libstdc++ 的字符串操作及其重载运算符。已编辑。
    • 这与libstdc++ 无关。在 OP 的代码中,operator+= 参数的类型是intint 可以隐式转换为char,但不能转换为std::string。因此,您带有两个字符串的示例与问题无关,并且operator+= 调用append() 的结论通常是错误的。 operator+= 有几个重载,它们做不同的事情。
    • @Evg i + '0' 结果为数字字符,然后分配字符。
    • str += some_strstr += some_char 调用不同的重载。
    【解决方案3】:
    • 这里是关于字符串的一般解释:https://stackoverflow.com/a/9132610/13292734

    • 由于我在上面添加的链接中的解释,您的情况是 θ(n) 而不是 O(n)。

    • 但是请记住,如果您分配的字符串是字符串的n - k 地址,并且您想添加n - k + 1 字符,有时可能会很棘手。

      例如:当字符串中有 543 个字符并且您想将第 544 个字符添加到 字符串。

      这会造成问题,您将没有足够的内存,它会添加另一个 存储n - k + 1 字符的地址,但它会复制整个字符串并添加 第 544 个字符。最后,它仍然是 O(n),但如果你需要高性能,你必须 照顾它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 2019-03-11
      • 2015-12-14
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多