如何在C或C ++中反转字符串而不需要单独的缓冲区来保存反转的字符串?
标准算法是使用指向起点/终点的指针,并将它们向内移动,直到它们在中间相遇或交叉。随手交换。
反向ASCII字符串,即以0结尾的数组,其中每个字符都适合1 char
。(或其他非多字节字符集)。
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\n", argv[argc-1]);
} while(--argc);
return 0;
}
相同的算法适用于已知长度的整数数组,只是使用tail = start + length - 1
而不是末端查找循环。
(编者注:此答案最初也用于此简单版本的XOR-swap。已修复,以供将来阅读此热门问题的读者使用。强烈建议不要使用XOR-swap;它很难阅读,使您的代码编译效率降低。您可以在Godbolt编译器资源管理器上看到,使用gcc -O3为x86-64编译xor-swap时,asm循环体要复杂得多。)
(这是XOR交换的东西。请注意,您必须避免与self交换,因为如果*p
和*q
处于同一位置,则将a ^ a == 0对其进行清零。XOR交换取决于有两个不同的位置,将它们各自用作临时存储。)
编者注:可以使用tmp变量用安全的内联函数替换SWP。
#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\n", argv[argc-1]);
} while(--argc);
return 0;
}
例子:
$ ./strrev Räksmörgås ░▒▓○◔◑◕●
░▒▓○◔◑◕● ●◕◑◔○▓▒░
Räksmörgås sågrömskäR
./strrev verrts/.
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句