【问题标题】:Difference between concat of strings s=s+"0" and s+="0" in c++c++中字符串s=s+"0"和s+="0"的concat的区别
【发布时间】:2019-01-17 15:56:05
【问题描述】:

我想从这两个中知道哪个在“时间复杂度”方面更好:

for(int i=0;i<n;i++){
s=s+"0";
}

for(int i=0;i<n;i++){
s+="0";
}

我正在解决一个问题,我在使用第一种方法时发现“TLE(Time Limit Exceed)”,但它适用于第二种方法。

【问题讨论】:

  • 您可能应该使用s += std::string( n, '0' ); 而不是循环。
  • 甚至更短的s.append(n, '0');
  • 当有更复杂的算法可用时,TLE 通常是选择错误算法的症状。你确定这是最贵的线路吗?
  • @user463035818 是的,我刚刚更改了这一行并且解决方案被接受了。
  • 如果是这样,那么您遇到了一个例外,您可以真正从在线法官那里学到有用的东西;)

标签: c++ string string-concatenation


【解决方案1】:

第一个创建一个中间字符串(将在+ 操作之后分配给s),而第二个可能不会(取决于字符串的容量)。

在最坏情况下的复杂性在这两种情况下是相同的,在最好的情况下,它只是将第二种情况的新字符串复制到第一种情况的两个字符串的完整副本(+内存分配和空闲)。

你得到TLE(超过时间限制)的事实可能是由于这种最坏的情况一直存在,总是复制巨大的字符串而不是仅仅在现有的字符串中添加一些东西(没有重新分配)。像vector一样,string中应该有一些启发式,以提前获得足够的容量。

正如@Slava所说,这个例子应该写不同,我想实际代码不同。

【讨论】:

  • 感谢您的回答,但请您详细说明一下,这样会更有帮助。
  • 你在哪里需要澄清?
  • 如果 s 的类型是 std::string (我不确定),那么第一个必须构建一个临时字符串并将 s 内容复制到存储 s+" 0" 然后交换到 s 并删除旧的字符串缓冲区,而第二个可以只是 push_back('0') 在现有缓冲区中,所以第二个可以更快,除非超过字符串容量()并且它必须调整大小。
  • @GemTaylor 的解释可能有所帮助;)
【解决方案2】:

我知道这是一个老问题。但是对于任何其他人都可能需要答案,并且由于在解决比赛问题时时差确实很尖锐,我想提醒一下

s = s + "0"; 需要 O(len(s)) 次操作。和

s += "0"; 需要 O(1)。

或者如果你想在字符串的前后追加,最好使用双端数据结构而不是字符串。

【讨论】:

    猜你喜欢
    • 2020-09-07
    • 2019-08-10
    • 2021-11-03
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    相关资源
    最近更新 更多