【问题标题】:fastest way to read the last line of a string?读取字符串最后一行的最快方法?
【发布时间】:2019-05-11 18:38:42
【问题描述】:

我想知道读取std::string 对象中最后一行的最快方法。
从技术上讲,最后一次出现 \n 之后的字符串以最快的方式出现吗?

【问题讨论】:

  • std::basic_string::find_last_of 后跟std::basic_string::substr 的表现如何?
  • 快速编写、快速调试、快速执行或其他快速方式?
  • @user4581301 当然可以快速执行。但如果已经有一个 C++ 函数,我不会介意,因为它会更安全 && 更少代码。
  • 同意。这是最好的起点。

标签: c++ string stdstring


【解决方案1】:

我想到了一种在存储它读取的内容的同时反向(向后)读取字符串的方法

std::string get_last_line(const std::string &str)
{
    size_t l = str.length();
    std::string last_line_reversed, last_line;
    for (--l; l > 0; --l)
    {
        char c = str.at(l);
        if (c == '\n')
            break;
        last_line_reversed += c;
    }
    l = last_line_reversed.length();
    size_t i = 0, y = l;
    for (; i < l; ++i)
        last_line += last_line_reversed[--y];
    return last_line;
}

直到遇到'\n' 字符,然后将存储的字符串反转并返回。如果目标字符串很大并且有很多新行,这个函数会非常高效。

【讨论】:

  • at 很棒。这是一款出色的调试工具,但是当您追求速度时,额外的有效性测试at 会降低您的速度。
  • 推荐一个注解来警告用户如果给定一个空字符串,这个函数将会出现异常。当l 为零时for (--l; l &gt; 0; --l) 会以糟糕的方式结束。
  • @user4581301 谢谢,我只是匆匆写了它,没有任何if检查,只将想法传递给SO。
【解决方案2】:

这可以像这样使用 string::find_last_ofstring::substr 来完成

std::string get_last_line(const std::string &str)
{
  auto position = str.find_last_of('\n');
  if (position == std::string::npos)
    return str;
  else
    return str.substr(position + 1);
}

见:example

【讨论】:

    【解决方案3】:

    我可能会使用std::string::rfindstd::string::substr 结合保证std::string::npos 环绕以简洁:

    inline std::string last_line_of(std::string const& s)
    {
        return s.substr(s.rfind('\n') + 1);
    }
    

    如果s.rfind('\n') 没有找到任何东西,它会返回std::string::nposC++ 标准是 std::string::npos + 1 == 0。返回s.substr(0) 总是安全的。

    如果s.rfind('\n') 确实找到了某些东西,那么您需要从下一个字符开始的子字符串。根据标准,再次返回s.substr(s.size()) 是安全的。

    注意:C++17 中,此方法将受益于保证返回值优化,因此它应该非常高效。

    【讨论】:

    • 这个答案比我的好,不知道npos位
    • @kmdreko 有些人会争辩说你的更清晰(确实如此 - 我赞成),所以它是一个六个中的六个。
    • 我做了一些测试,结果证明rfind 在处理单个字符时比find_last_of 快。
    • 有趣,我认为他们对单个字符的情况有相同的实现......
    猜你喜欢
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2012-08-06
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多