【问题标题】:How to get a valid iterator after string replacement字符串替换后如何获取有效的迭代器
【发布时间】:2019-04-18 07:39:47
【问题描述】:

我想在 Windows 下使用迭代器在 C++ 中进行一些字符串替换。 这是代码:

#include <stdio.h>
#include <iostream>
#include <string>
#include <iterator>

size_t iterator_to_size_t(std::string &string, std::string::iterator it)
{
    size_t pos;
    pos = std::distance(string.begin(), it);
    return pos;
}


int main()
{
    std::string text = "TTTTbcdefghijklmnopqrstuvwxyz";
    std::string findtext = "TTTT";
    std::string replacementtext = "123456";

    for (std::string::iterator it = text.begin(); it!=text.end(); ++it)
    {
        size_t z = iterator_to_int(text, it);
        if (text.compare(z, findtext.length(), findtext) == 0)
        {
            text.replace(z, findtext.length(), replacementtext);
        }
    }
    return 0;
}

string::replace 方法显然使迭代器无效。我收到一条错误消息说。我试图将 string::replace 的返回值分配给迭代器,以获取新的有效迭代器,但返回值似乎不兼容。

如何在此处获得有效的迭代器,还是必须使用索引而不是迭代器?

【问题讨论】:

  • 这并没有解决问题,而是养成使用有意义的值初始化对象的习惯,而不是默认初始化它们并立即分配新值。即把size_t pos; pos = ...;改成size_t pos = ...;

标签: c++ string replace iterator invalidation


【解决方案1】:

替换后可以重新计算迭代器,例如

if (text.compare(z, findtext.length(), findtext) == 0)
{
    text.replace(z, findtext.length(), replacementtext);
    it = text.begin() + z + replacementtext.size();
}

此外,有一个使用迭代器的循环,从这些迭代器计算位置索引并使用位置索引来获取迭代器确实很麻烦。我建议您考虑以下事项。

#include <regex>

const std::regex re{"TTTT"};
text = std::regex_replace(text, re, replacementtext);

【讨论】:

  • 非常感谢。我发布的这段代码 sn-p 是一个函数的一部分,它获取当前系统时间并根据给定的格式字符串格式化它(还包括阻止我使用 strftime 等的毫秒)。我用正则表达式做到了这一点,但它们似乎大大减慢了解析速度。这就是我转向“标准”字符串替换的原因。
  • 您是否对&lt;regex&gt; 与手动替换相比减慢了多少功能进行了基准测试?众所周知,标准的正则表达式实现可能不是最快的,但在切换到更复杂/容易出错的东西之前,您可能应该对代码进行分析/基准测试?
  • 我还没有尝试过非正则表达式,但我用 powershell 中的 measure-command 命令对其进行了测试,我的版本运行了 40 毫秒,而 powershell 中的内置 get-date commandlet 只运行了 9 毫秒.所以我想这是由于正则表达式,但我可能错了,因为我选择了慢速算法
  • 一般来说,在谈论性能时,以“所以我想这是由于...”开头的句子是错误的。永远不要假设;基准和检查;)
  • 你是绝对正确的,所以我在没有任何正则表达式的情况下测试了一个完全不同的算法(遍历格式字符串并进行替换),结果表明它并不比使用正则表达式的解决方案快,所以我的假设显然是错误的,并且性能有不同的原因,无论如何,感谢您的提示
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
相关资源
最近更新 更多