在c ++中,用c-string反转的最快方法是什么?

时间:2013-02-05 02:14:41

标签: c++

在仅使用库的c ++中,反转c字符串的最快方法是什么?特别是,是否有任何方法需要少于O(strlen)时间?

3 个答案:

答案 0 :(得分:5)

不可能有一种方法可以在不到n的时间内反转长度为O(n)的字符串。根据“反转”的定义,每个角色必须至少阅读一次。

答案 1 :(得分:3)

我怀疑它的复杂程度低于O(N)。考虑到如何定义C字符串(NUL终止),你甚至无法找到字符串的最终元素,其复杂度低于O(N),因此很难想象实际上用较低的复杂度做任何事情。

就你如何做而言,通常是将第一个元素与最后一个元素交换,第二个元素与倒数第二个交换,依此类推。

要实现比线性更快的速度,您可能需要首先存储字符串的长度。然后,根本不是实际反转它,而是(例如)设置一个标志以指定从结尾开始。这将允许恒定的复杂性“逆转”。这在C ++中非常容易管理,您可以在其中“保护”存储,并使运算符超载,以便按照您想要的方向进行访问。

答案 2 :(得分:3)

由于你必须至少触摸一次每个角色,所以没有办法比O(n)时间更好。

类似于:

void reverseString (char *s) {
    char t, *d = &(s[strlen (s) - 1]);
    while (d > s) {
        t = *s;
        *s++ = *d;
        *d-- = t;
    }
}

可能与您在标准C ++中获得的效率相当。

现在有很多方法可以改善这种情况,如果您可以将额外信息强加到可以将成本分摊到小于O(n)的程度,具体取决于您的访问模式。

通过这个,我的意思是保持一个反向的字符串和脏标志以及原始字符串。

  • 如果在标志变脏时尝试访问反向字符串,则计算反转,将标志设置为清除并返回计算/存储的反转。成本是O(n)。
  • 如果您在标志清洁时尝试访问反向字符串,只需返回计算/存储的反转。成本是O(1)。
  • 如果您更改了原始字符串,请将该标志设置为脏。成本是O(1)。

如果您比更改原始字符串更频繁地访问反向字符串,则成本会降低到简化的“每次计算反向字符串”方法之下。