Gre*_*ers 454
#include <algorithm>
std::reverse(str.begin(), str.end());
Run Code Online (Sandbox Code Playgroud)
这是C++中最简单的方法.
小智 162
阅读Kernighan和Ritchie
#include <string.h>
void reverse(char s[])
{
int length = strlen(s) ;
int c, i, j;
for (i = 0, j = length - 1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
Run Code Online (Sandbox Code Playgroud)
And*_*ius 122
邪恶的C:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
(这是XOR交换的事情.请注意,你必须避免与self交换,因为a ^ a == 0.)
// 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;
}
Run Code Online (Sandbox Code Playgroud)
例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*way 40
非邪恶的C,假设字符串是以空终止的char
数组的常见情况:
#include <stddef.h>
#include <string.h>
/* PRE: str must be either NULL or a pointer to a
* (possibly empty) null-terminated string. */
void strrev(char *str) {
char temp, *end_ptr;
/* If str is NULL or empty, do nothing */
if( str == NULL || !(*str) )
return;
end_ptr = str + strlen(str) - 1;
/* Swap the chars */
while( end_ptr > str ) {
temp = *str;
*str = *end_ptr;
*end_ptr = temp;
str++;
end_ptr--;
}
}
Run Code Online (Sandbox Code Playgroud)
Nem*_*vic 35
您使用std::reverse
C++标准库中的算法.
kar*_*lip 25
已经有一段时间了,我不记得哪本书教会了我这个算法,但我认为它非常巧妙且易于理解:
char input[] = "moc.wolfrevokcats";
int length = strlen(input);
int last_pos = length-1;
for(int i = 0; i < length/2; i++)
{
char tmp = input[i];
input[i] = input[last_pos - i];
input[last_pos - i] = tmp;
}
printf("%s\n", input);
Run Code Online (Sandbox Code Playgroud)
小智 23
使用STL中的std :: reverse方法:
std::reverse(str.begin(), str.end());
Run Code Online (Sandbox Code Playgroud)
你必须包括"算法"库,#include<algorithm>
.
Ecl*_*pse 20
请注意,std :: reverse的优点在于它适用于char *
字符串和std::wstring
s以及std::string
s
void strrev(char *str)
{
if (str == NULL)
return;
std::reverse(str, str + strlen(str));
}
Run Code Online (Sandbox Code Playgroud)
Jua*_*ano 11
如果您正在寻找反转NULL终止缓冲区,那么此处发布的大多数解决方案都可以.但是,正如Tim Farley已经指出的那样,这些算法只有在假设字符串在语义上是一个字节数组(即单字节字符串)时才有效,我认为这是一个错误的假设.
例如,字符串"año"(西班牙语年份).
Unicode代码点是0x61,0xf1,0x6f.
考虑一些最常用的编码:
Latin1/iso-8859-1(单字节编码,1个字符是1个字节,反之亦然):
原版的:
0x61,0xf1,0x6f,0x00
相反:
0x6f,0xf1,0x61,0x00
结果还可以
UTF-8:
原版的:
0x61,0xc3,0xb1,0x6f,0x00
相反:
0x6f,0xb1,0xc3,0x61,0x00
结果是乱码和非法的UTF-8序列
UTF-16 Big Endian:
原版的:
0x00,0x61,0x00,0xf1,0x00,0x6f,0x00,0x00
第一个字节将被视为NUL终止符.不会发生逆转.
UTF-16 Little Endian:
原版的:
0x61,0x00,0xf1,0x00,0x6f,0x00,0x00,0x00
第二个字节将被视为NUL终止符.结果将是0x61,0x00,一个包含'a'字符的字符串.
Tim*_*ley 10
为了完整性,应该指出在各种平台上存在字符串的表示,其中每个字符的字节数根据字符而变化.老派程序员将此称为DBCS(双字节字符集).现代程序员更常见的是UTF-8(以及UTF-16等).还有其他类似的编码.
在任何这些可变宽度编码方案中,这里发布的简单算法(邪恶,非邪恶或其他)根本无法正常工作!实际上,它们甚至可能导致字符串在该编码方案中变得难以辨认或甚至是非法字符串.有关一些很好的例子,请参阅Juan Pablo Califano的答案.
只要您的平台的标准C++库(特别是字符串迭代器)的实现正确考虑到这一点,std :: reverse()在这种情况下仍然可能仍然有效.
小智 6
#include <cstdio>
#include <cstdlib>
#include <string>
void strrev(char *str)
{
if( str == NULL )
return;
char *end_ptr = &str[strlen(str) - 1];
char temp;
while( end_ptr > str )
{
temp = *str;
*str++ = *end_ptr;
*end_ptr-- = temp;
}
}
int main(int argc, char *argv[])
{
char buffer[32];
strcpy(buffer, "testing");
strrev(buffer);
printf("%s\n", buffer);
strcpy(buffer, "a");
strrev(buffer);
printf("%s\n", buffer);
strcpy(buffer, "abc");
strrev(buffer);
printf("%s\n", buffer);
strcpy(buffer, "");
strrev(buffer);
printf("%s\n", buffer);
strrev(NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码产生此输出:
gnitset
a
cba
Run Code Online (Sandbox Code Playgroud)
另一种C ++方式(尽管我可能会自己使用std :: reverse():)来提高表现力和速度)
str = std::string(str.rbegin(), str.rend());
Run Code Online (Sandbox Code Playgroud)
C方式(或多或少:)),请注意交换的XOR技巧,编译器有时无法对其进行优化。
char* reverse(char* s)
{
char* beg = s, *end = s, tmp;
while (*end) end++;
while (end-- > beg)
{
tmp = *beg;
*beg++ = *end;
*end = tmp;
}
return s;
} // fixed: check history for details, as those are interesting ones
Run Code Online (Sandbox Code Playgroud)