How do you reverse a string in place in C or C++?(如何在 C 或 C++ 中反转字符串?)
问题描述
如何在 C 或 C++ 中反转字符串而不需要单独的缓冲区来保存反转的字符串?
How do you reverse a string in C or C++ without requiring a separate buffer to hold the reversed string?
推荐答案
标准算法是使用指向开始/结束的指针,然后向内走,直到它们在中间相遇或交叉.随时交换.
The standard algorithm is to use pointers to the start / end, and walk them inward until they meet or cross in the middle. Swap as you go.
反转 ASCII 字符串,即一个以 0 结尾的数组,其中每个字符都适合 1 个 char
.(或其他非多字节字符集).
Reverse ASCII string, i.e. a 0-terminated array where every character fits in 1 char
. (Or other non-multibyte character sets).
void strrev(char *head)
{
if (!head) return;
char *tail = head;
while(*tail) ++tail; // find the 0 terminator, like head+strlen
--tail; // tail points to the last real char
// head still points to the first
for( ; head < tail; ++head, --tail) {
// walk pointers inwards until they meet or cross in the middle
char h = *head, t = *tail;
*head = t; // swapping as we go
*tail = h;
}
}
// test program that reverses its args
#include <stdio.h>
int main(int argc, char **argv)
{
do {
printf("%s ", argv[argc-1]);
strrev(argv[argc-1]);
printf("%s
", argv[argc-1]);
} while(--argc);
return 0;
}
相同的算法适用于已知长度的整数数组,只需使用 tail = start + length - 1
而不是结束查找循环.
The same algorithm works for integer arrays with known length, just use tail = start + length - 1
instead of the end-finding loop.
(编者注:这个答案最初也为这个简单的版本使用了 XOR-swap.为了这个热门问题的未来读者的利益而修复.XOR-swap 高度不推荐;难以阅读并使您的代码编译效率降低.您可以看到在 Godbolt 编译器浏览器上 当 xor-swap 为 x86 编译时,asm 循环体有多复杂-64 与 gcc -O3.)
(Editor's note: this answer originally used XOR-swap for this simple version, too. Fixed for the benefit of future readers of this popular question. XOR-swap is highly not recommended; hard to read and making your code compile less efficiently. You can see on the Godbolt compiler explorer how much more complicated the asm loop body is when xor-swap is compiled for x86-64 with gcc -O3.)
(这是异或交换的事情.注意你必须避免与self交换,因为如果*p
和*q
是同一个位置,您将使用 a^a==0 将其归零.异或交换取决于有两个不同的位置,将它们分别用作临时存储.)
(This is XOR-swap thing. Take care to note that you must avoid swapping with self, because if *p
and *q
are the same location you'll zero it with a^a==0. XOR-swap depends on having two distinct locations, using them each as temporary storage.)
编者注:您可以使用 tmp 变量将 SWP 替换为安全的内联函数.
Editor's note: you can replace SWP with a safe inline function using a tmp variable.
#include <bits/types.h>
#include <stdio.h>
#define SWP(x,y) (x^=y, y^=x, x^=y)
void strrev(char *p)
{
char *q = p;
while(q && *q) ++q; /* find eos */
for(--q; p < q; ++p, --q) SWP(*p, *q);
}
void strrev_utf8(char *p)
{
char *q = p;
strrev(p); /* call base case */
/* Ok, now fix bass-ackwards UTF chars. */
while(q && *q) ++q; /* find eos */
while(p < --q)
switch( (*q & 0xF0) >> 4 ) {
case 0xF: /* U+010000-U+10FFFF: four bytes. */
SWP(*(q-0), *(q-3));
SWP(*(q-1), *(q-2));
q -= 3;
break;
case 0xE: /* U+000800-U+00FFFF: three bytes. */
SWP(*(q-0), *(q-2));
q -= 2;
break;
case 0xC: /* fall-through */
case 0xD: /* U+000080-U+0007FF: two bytes. */
SWP(*(q-0), *(q-1));
q--;
break;
}
}
int main(int argc, char **argv)
{
do {
printf("%s ", argv[argc-1]);
strrev_utf8(argv[argc-1]);
printf("%s
", argv[argc-1]);
} while(--argc);
return 0;
}
- 为什么,是的,如果输入是 borked,这会很高兴地在这个地方交换.
- 在 UNICODE 中破坏时的有用链接:http://www.macchiato.com/unicode/chart/
- 此外,UTF-8 over 0x10000 未经测试(因为我似乎没有任何字体,也没有耐心使用 hexeditor)
例子:
$ ./strrev Räksmörgås ░▒▓○◔◑◕●
░▒▓○◔◑◕● ●◕◑◔○▓▒░
Räksmörgås sågrömskäR
./strrev verrts/.
这篇关于如何在 C 或 C++ 中反转字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在 C 或 C++ 中反转字符串?
基础教程推荐
- 设计字符串本地化的最佳方法 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++,'if' 表达式中的变量声明 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01