【问题标题】:Most efficient way of finding last char occurrence查找最后一个字符出现的最有效方法
【发布时间】:2012-08-28 20:30:45
【问题描述】:

考虑一下我写的这个函数,它可以快速找到给定字符在字符串中的最后一次出现,并返回它在物理上是字符串的字符数组中的位置:

size_t strlstchar(const char *str, const char ch)
{
    char *chptr = strrchr(str, ch);
    return chptr - str;
}

我只是在这里快速输入了这个(尚未编译或尚未编译),只是因为我对一些事情有疑问。

对我来说,这似乎是查找哪个数组元素包含特定字符的最后一个实例的最简单解决方案,但我不知道它是如何工作的。我只是按照 strrchr 的文档制作的,所以从技术上讲,它是 strrchr 完成所有工作。我只是无法想象这是实现这一目标的最佳方式(就性能而言),并希望有人可以就什么是实现这一目标的最佳方式提供一些意见。

strrchr 是一种有效的方法吗?还是 strrchr 最好留作其他用途?

【问题讨论】:

  • strrchr 可以返回 NULL,从而使您的函数的结果在找不到字符时难以预测。通常“-str”可以看作是一个随机数,然后转换为size_t,你怎么知道你没有找到char?

标签: c performance strrchr


【解决方案1】:

您使用的方法非常好 - 不幸的是,数组操作很昂贵。大多数实现中的 Strrcr 只是从字符串的末尾开始逐步遍历字符串,直到找到匹配的字符。那是O(n) 时间。然后执行减法运算,即O(1)。这还不错。

【讨论】:

  • 很有趣,谢谢你的快速回答,我只是总是对使用字符串函数犹豫不决,我想这是一种习惯,或者不太清楚为什么它会钻进我的大脑,“如果你使用string.h 中定义的函数你做错了”
  • @KeithMiller 错了。这些功能是有目的的。如果有一种神奇的恒定时间方法来解决所有算法问题,libc 实现者会使用它。永远记住 Linus Torvalds 写的那句话:“任何理智的人都知道 K&R 是对的”:)
  • 字符串在 C 中真的很慢,因为它们的特定性质(以 0x00 结尾): strrchr() 从字符串的开头到结尾(通过调用 strlen() 来知道结尾字符串,它遍历整个字符串,然后从末尾取出它直到找到字符,或者通过简单的传递直到字符串末尾)。因此,无论您找到的字符在哪里,都会扫描整个字符串!
  • @H2CO3 写的时候没看到,想补充一下 strrchr() 常用算法的精度 :)
【解决方案2】:

来自文档:

返回指向 C 字符串 str 中最后出现的字符的指针。

所以它完全符合您的要求。它存在的目的就是这个。

strrchr 是一种有效的方法吗?

几乎可以肯定,它写得至少和你自己写的一样好或更好。

还是 strrchr 最好留作其他用途?

没有。它正是为此目的而编写的。

【讨论】:

    【解决方案3】:

    如果你能提供字符串的长度然后向后循环会更快。当你找到第一次出现的字符时立即返回。

    如果您不知道长度,请使用 strrchr。

    【讨论】:

    • 这就是我的想法,但在什么情况下我不知道字符串的长度,除非它包含 NULL 字符或其他东西,那时它甚至会被认为是一个字符串吗?还是只是一大块数据?如果这样会更有效,为什么标准库中不这样呢?看起来很简单?这就是为什么我很困惑,因为有时事情对我来说没有意义:(
    • 通常在 C 中你不知道字符串的长度,所以在 strrchr 中不包含长度更有意义。所以每次使用 strrcr 时都不需要做 strlen 来获取长度。但也有很多函数会在成功时返回长度,例如 scanf。如果您的代码确实需要更高效,您可以向后循环。
    猜你喜欢
    • 1970-01-01
    • 2016-01-08
    • 2018-05-23
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多