【问题标题】:Efficient way to get a reversed copy of std::string获取 std::string 反向副本的有效方法
【发布时间】:2021-12-02 05:45:27
【问题描述】:

处理算法任务时,我经常需要得到一份反向的std::string。此外,不应修改源字符串。就我而言,有两种方法可以做到:

  1. 使用std::reverse
// std::string sourceString has been initialized before.
std::string reversedString = sourceString;
std::reverse(reversedString.begin(), reversedString.end());
  1. 使用反向迭代器。这是我在网上找到的:
// std::string sourceString has been initialized before.
std::string reversedString{sourceString.rbegin(), sourceString.rend()};

我的问题是,根据效率和最佳实践,我应该更喜欢哪种方法。 我不关心 C 风格的解决方案,我只对 STL 方式的方法感兴趣。

【问题讨论】:

  • 效率可以是很多东西,所以你需要指定它。你想让算法快吗?还是您希望它使用尽可能少的内存?是只需要输出反向字符串还是需要存储?
  • 要反转字符串中的字符,您将必须读取所有字符并将它们写入新位置(可能在奇数长度的中间字符的特殊情况下细绳)。您可以通过 N/2 交换(这是 std::reverse 所做的)或 N 个副本(这是创建新字符串所做的)来做到这一点。
  • 显示的两种方法都只处理个人chars。两者都没有正确处理多字节字符,即在 MBCS/UTF-8 字符串中使用 2+ chars 的非 ASCII 字符。在这种情况下,您必须迭代sourceString 转发,计算并提取完整的char 序列,然后按原样插入reversedString 的前面,从而保护每个序列的完整性,仅更改序列相对于其他序列的顺序。
  • 为什么您需要一种有效的反转字符串的方法?

标签: c++ algorithm stl c++17


【解决方案1】:

我的问题是根据效率我应该更喜欢哪种方法

根据效率应该首选的一种是已被测量为更有效的一种。两者具有相同的渐近复杂度。

但是,除非碰巧成为瓶颈,否则我不会费心去衡量差异。我更喜欢 2,但它是主观的。

【讨论】:

  • 感谢您的回答!那么,从最佳实践来看,这两种方式没有区别?
  • @powercat 它们的实现略有不同,因此可能更快或更慢,但这取决于您的编译器、设置和 CPU。甚至可能一个在速度快的计算机上速度更快,而另一个在速度较慢的计算机上速度更快。
  • @powercat:从最佳实践的角度来看...反转字符串中的字符所花费的时间不太可能对您的程序性能造成问题。
  • @powercat as-if rule 表示只要可观察的行为不改变,编译器就可以做任何想做的事情。这意味着编译器有权将 1 换成 2、2 换成 1,或者换成你从未想过的 3。
  • 在 Nicol 的建议下加倍努力。只有在分析表明代码中的热路径存在性能问题之后,才应该担心微优化。
【解决方案2】:

我可以说最初用正确的数据构建数据结构通常更快,但关于性能的一般陈述通常是错误的。如果您担心性能,您应该衡量性能和基准。

如果您对编写基准代码的性能不够关注,那么您应该采用最适合您的样式。


另外,你忘记了 C++20 风格:

auto reversed = sourceString | std::views::reverse;
std::string reversedString{begin(reversed), end(reversed)};

这最终与迭代器范围样式没有什么不同,因为字符串仍然需要一个迭代器对。

【讨论】:

    【解决方案3】:

    正如其他人所说,您应该首先决定什么对您的代码库、风格或速度更有意义。如果是样式,只需使用平均运行时间为 O(n) 的std::reverse。如果速度是一个瓶颈并且你一直运行这个反向字符串方法,我会考虑创建一个双向链表。然后反转 LL 可以在 O(1) 运行时发生。

    【讨论】:

      猜你喜欢
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多