Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c+中反转c字符串的最快方法是什么+;? 什么是最快的方法来反转C字符串,在C++中只使用库?特别是,是否有需要少于O(strlen)时间的方法?_C++ - Fatal编程技术网

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

在c+中反转c字符串的最快方法是什么+;? 什么是最快的方法来反转C字符串,在C++中只使用库?特别是,是否有需要少于O(strlen)时间的方法?,c++,C++,不可能有方法在少于O(n)时间内反转长度n的字符串。根据“反转”的定义,每个字符都必须至少读取一次。我怀疑它的复杂度不到O(N)是可能的。考虑到C字符串是如何定义的(以NUL结尾),您甚至找不到复杂性小于O(N)的字符串的最后一个元素,因此很难想象实际使用它来做任何事情 至于如何操作,通常是将第一个元素与最后一个元素交换,将第二个元素与第二个元素交换,依此类推 要获得比线性更快的结果,可能需要先存储字符串的长度。然后,您可以(例如)设置一个标志来指定从末尾开始,而不是实际上完全反转它。这将允许不

不可能有方法在少于
O(n)
时间内反转长度
n
的字符串。根据“反转”的定义,每个字符都必须至少读取一次。

我怀疑它的复杂度不到O(N)是可能的。考虑到C字符串是如何定义的(以NUL结尾),您甚至找不到复杂性小于O(N)的字符串的最后一个元素,因此很难想象实际使用它来做任何事情

至于如何操作,通常是将第一个元素与最后一个元素交换,将第二个元素与第二个元素交换,依此类推


要获得比线性更快的结果,可能需要先存储字符串的长度。然后,您可以(例如)设置一个标志来指定从末尾开始,而不是实际上完全反转它。这将允许不断的复杂性“逆转”。在C++中,这是相当容易管理的,在这里你可以“保护”存储,并使操作符过载,从而提供你想要的方向。

< p>没有比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)

如果访问反转字符串的频率高于更改原始字符串的频率,那么成本将低于简化的“每次计算反转字符串”方法。

既然您必须移动(并因此读取)所有字符(可能只有一个字符除外),它怎么可能不是O(strlen)有一个显示C++代码的用于在本地反转C字符串的代码。仅此而已,不要使用字符串文本调用函数。除了编程项目外,是否还需要反转C字符串?@ThomasMatthews:不经常!是:
std::string str=“我的字符串”;自动反转=str.rbegin()是O(1)!!!1你能解释一下你是如何用你的方法得到次线性复杂度的吗?OP的要求是“在适当的位置反转字符串”。即使他不一定需要用倒数来覆盖旧字符串,而只是“提取”倒数,它将是
O(N)
。我所看到的次线性的唯一可能性是,如果你只需要最后的
k
字符,在这种情况下,如果你事先知道长度,你可以去
O(k)
。@us2012:他在描述一个反向迭代器。我想说的是,虽然在
O(1)
中可以获得反向迭代器,一旦你获得了它,你就没有做任何有用的事情。要处理所需的输出(反向字符串),您必须输入/递减它并读取字符。我觉得将此解决方案作为
O(1)字符串反转
进行销售至少是一种创造性营销:)@us2012若要对真正已反转的字符串执行任何有用的操作,您还必须输入/减少它并读取字符。除了一个更快之外,没有什么区别。@Seth为真,但不会改变整体的复杂性。我想说的是,用它做任何有用的事情,复杂性都是线性的。如果你相信
std::reverse
,你可以做
std::reverse(s,s+strlen(s))
@user315052,我没有理由不相信它,但它仍然是一个O(n)操作。这应该是d>s吗?另外,我很好奇单词的反转,而不是单个字母。@Bob,是的,应该是
d>s
s
是字符串的开头,
d
是字符串的结尾。交换,然后递增
s
并递减
d
,直到它们相遇或交叉。在你的问题中没有关于交换单词的内容,而是关于反转字符串,这是一个逐字符的操作。如果你想问一个关于交换单词的问题,我建议你再问一个。但是首先检查一下,我很确定你会发现一些东西。好吧,这不是一个与普通C字符串兼容的好方法,但是你可以创建一个特殊的字符串类,它有一个isReversed标志,并保持指向字符串两端的指针。然后添加字符串操作,这些操作可以检查标志并决定使用哪些字节。