有没有办法C
用最少的(可能是单行的)源代码行来反转字符串。C++ 通过按照此处#include <algorithm>
的建议使用来支持这一点。我想知道 C 是否也支持任何这样的机制。
问问题
1558 次
7 回答
7
这是一个不使用任何库函数的单行(排序,需要声明变量):-
char s [] = "hello world";
char *p,*q;
for (p=s,q=0;p>q;q?*p^=*q,*q^=*p,*p--^=*q++:!*++p?q=s,*--p:0);
代码如何工作的解释:-
变量:-
- p:字符串结尾指针,初始化为字符串的开头,用于查找结尾
- q:两个目的,指向字符串的开头并用于状态
状态:-
- q == 0: for 循环正在搜索输入字符串的结尾,p 正在递增以找到结尾
- q != 0: for 循环从字符串的前半部分和字符串的后半部分交换字符
终止:-
当指向字符串前半部分的指针超出指向字符串后半部分的指针时,循环终止。在搜索字符串结尾时,指向前半部分 (q) 的指针为 0,因此条件始终为真。
递增:-
for 循环的第三部分取决于状态,可以这样分解:-
if state is searching for end of string (q == 0)
increment end of string pointer (++p)
if end of string pointer is pointing at null terminator (*p == 0)
set start of string pointer and set state to swapping characters (q=s)
decrement end of string pointer (--p)
endif
else
swap characters (the three ^=)
move first and secondhalf pointers (--p, ++q)
endif
中明显不必要的原因*
是*--p
为了确保三元运算符的所有部分都具有相同的类型。
如果您了解所有这些,那么您应该发现代码中的错误。
于 2013-07-17T10:51:23.903 回答
5
“最少行数”的要求没有多大意义(毕竟,你的整个程序可以写在一行中)。如果您愿意进行就地反转,您可以拥有一个相当轻量级的实现:
void strrev(char *s) {
char *p = s + strlen(s);
while ( s + 1 < p ) {
char tmp = *s;
*s++ = *--p;
*p = tmp;
}
}
于 2013-07-17T10:42:07.890 回答
3
#include <string.h>
char *strrev(char *string);
说明 strrev 反转给定字符串中字符的顺序。结束空字符 (\0) 保持不变。
退货
strrev 返回一个指向已更改字符串的指针。没有错误返回值
这仅适用于 Windows
于 2013-07-17T10:30:07.033 回答
2
不,没有用于反转字符串(或其他序列或范围)的标准 C 库例程。
于 2013-07-17T10:38:59.367 回答
1
#include <stdio.h>
int strrev_r(char *str, int pos){
char ch = str[pos];
return (ch == '\0')? 0 : ((str[pos=strrev_r(str, ++pos)]=ch), ++pos);
}
void strrev(char *str){
strrev_r(str, 0);
}
int main(){
char string[] = "string";
strrev(string);
puts(string);
return 0;
}
于 2013-07-17T11:44:36.747 回答
0
你好,这不是一条线,但它工作得很好
#include<stdio.h>
#include<string.h>
char *revstr(char *str)
{
int i;
int size;
int max;
char save;
i = 0;
size = strlen(str);
max = size / 2;
while (i < max)
{
save = str[i];
str[i] = str[size - 1 - i];
str[size - 1 -i] = save;
i = i + 1;
}
return(str);
}
int main()
{
char *str;
str = strdup("hello");
str = revstr(str);
printf("%s\n", str);
}
于 2013-07-17T10:43:47.267 回答
0
如果你坚持一个一个衬里,你会得到一个衬里。
for(int i = -1, len = strlen(s), t = 0; ++i < len / 2; t = s[i], s[i] = s[len - 1 - i], s[len - 1 - i] = t);
于 2013-07-17T10:50:05.500 回答