一道笔试题,纸上写的,誊到电脑上并调试通过并改善。
没经验,菜鸟摸索的野蛮算法,不知道有没有更简洁更抽象的算法。
打算用现成字符串操作函数的请绕行搜索。
原题是不用buffer(缓存)反转字符串打印输出,受OJ的毒害,我就认为只要逆序打印就行了(要是把原字符串改了,我还真不知道怎么办到,尤其听说字符串常量不能被更改,在文章尾部会做验证)。
v0.1:
用了一下递归,思路是用指针遍历字母,每碰到空格就用新指针往下递归调用一次,碰到结束符呢,就结束呗。有两个细节,如果空格之后还是空格呢?所以你需要指针+1,往后走,别卡住;每次递归不能改变初始指针,只能用+cnt做遍历,不然递归调用返回的时候怎么知道打印谁谁谁呢?
可直接运行,可无视注释部分,为调试时设置。
//reverse string without a buffer
#include<stdio.h>
void recurence(char * str){
char *p = str;//don't forget to initial point p
unsigned int cnt = 0;
while(*(p + cnt) != ' ' && *(p + cnt) != '\0'){
// printf("*(p + cnt) == %c \t cnt++\n",*(p + cnt));
cnt++;
// printf("%d\n",cnt);
}
if(*(p + cnt) == ' '){//consider multi space
// printf("next recurence\n");
recurence(p + cnt + 1); //+1 to avoid deadloop
}
//output p to p+cnt
char *out = p;
while(out != (p + cnt)){
printf("%c",*out);
out++;
}
printf(" ");
if(*(p + cnt) == '\0'){//exit must after print
// printf("end\n");
//How to find the final output and add an "end"
return;
}
}
main(){
char * str = "hello world hehe piapia ljlj";
printf("the original string is:\n");
printf("%s\n",str);
printf("and the result string is:\n");
recurence(str);
printf("\n");
}
结果:
root@v:/usr/local/C-language/Interview# gcc reverse_string_without_buffer.c
root@v:/usr/local/C-language/Interview# ./a.out
the original string is:
hello world hehe piapia ljlj
and the result string is:
ljlj piapia hehe world hello
整体功能达到~!
V0.11:
删一下无用的调试注释,看起来简洁点:
//reverse string without a buffer
#include<stdio.h>
void recurence(char * str){
char *p = str;//don't forget to initial point p
unsigned int cnt = 0;
while(*(p + cnt) != ' ' && *(p + cnt) != '\0'){
cnt++;
}
if(*(p + cnt) == ' '){//consider multi space
recurence(p + cnt + 1); //+1 to avoid deadloop
}
//output p to p+cnt
char *out = p;
while(out != (p + cnt)){
printf("%c",*out);
out++;
}
printf(" ");
if(*(p + cnt) == '\0'){//exit must after print
// printf("end\n");
//How to find the final output and add an "end"
return;
}
}
main(){
char * str = "hello world hehe piapia ljlj";
printf("the original string is:\n");
printf("%s\n",str);
printf("and the result string is:\n");
recurence(str);
printf("\n");
}
不完善:空格的位置的严格判定,如果真是OJ,过于严格的要求顺序怎么办,比如第一个单词前有空格,最后一个单词后边有空格,都怎么输出。换行符,希望在函数内打印,而不是在main()中手动打印,这些小细节待完善。不难,有空弄一下~!
v0.2:
小功能添加:在函数内完成反转输出字符串后换行,而不借助于“外力”在main()中使用printf()。
思路:加个count,count最小的那次嵌套在最后打印换行符,当递归结束回来时,if一下,打印一个换行符:
但是递归如何计数?
如果用静态变量吧~可是问题来了,用递归就得最后输出换行符,可是到最后那个静态count已经很大了,这个矛盾怎么解决,也不知道确切单词数量,也没法用一个临时的max来做判断,怎么完成?
如果不用静态变量吧,每次递归还得向下再传递一个count,相当于重构函数了,添加一个参数,但是这是目前能想到的唯一办法。
限制条件:因为要用if语句判断recurcount的值来判断何时输出换行符。不能有recurcount++影响recurcount的值,改用传递参数recurcount+1
整体算是比较蛋疼的设计:
#include<stdio.h>
void recurence(char * str,unsigned int recurcount){
char *p = str;//don't forget to initial point p
unsigned int cnt = 0;
while(*(p + cnt) != ' ' && *(p + cnt) != '\0'){
cnt++;
}
if(*(p + cnt) == ' '){//consider multi space
// recurcount++;
recurence(p + cnt + 1,recurcount+1); //+1 to avoid deadloop
}
char *out = p;
while(out != (p + cnt)){
printf("%c",*out);
out++;
}
printf(" ");
if(recurcount == 0){//when recurence end,change to next line.
printf("\n");
}
if(*(p + cnt) == '\0'){//exit must after print
return;
}
}
main(){
char * str = "hello world hehe piapia ljlj";
printf("the original string is:\n");
printf("%s\n",str);
printf("and the result string is:\n");
recurence(str,0);
// printf("\n");
}
修改前没有换行符(去掉了main()函数中的手动换行):
^[[Aroot@v:/usr/local/C-language/Interview# ./a.out
the original string is:
hello world hehe piapia ljlj
and the result string is:
ljlj piapia hehe world hello root@v:/usr/local/C-language/Interview#
修改后有换行符:
^[[Aroot@v:/usr/local/C-language/Interview# ./a.out
the original string is:
hello world hehe piapia ljlj
and the result string is:
ljlj piapia hehe world hello
v0.3
关于空格的准确输出:其实很简单,从哪遭遇空格陷入,就从哪输出空格(当然是回来以后~),把之前手动打印空格这种低级手法删掉
CSDN的排版真让人想骂人
^[[Aroot@v:/usr/local/C-language/Interview# ./a.out
the original string is:
hello world hehe piapia ljlj
and the result string is:
ljlj piapia hehe world hello root@v:/usr/local/C-language/Interview#
整体方法比较野蛮,但逻辑上还说的过去吧。没用什么技巧,时间关系不深究,有懂的高手欢迎指教。
会不定时回来修改完善代码。
============================================================================================================================================================================================================================================================================================================================================================================================================
关于“字符串常量”不可更改的验证:
//try to modify a "constant string"
#include<stdio.h>
main(){
char *str = "hello World";
printf("%s\n",str);
*str = 'W';
printf("%s\n",str);
}
root@v:/usr/local/C-language# ./a.out
hello World
Segmentation fault (core dumped)
果然改不了,崩溃了。。。。
PS:之所以要再验证一下,是因为这两天看到CU论坛有小朋友放出话来和人叫板说字符串常量能改,并举例:
char *str = "hello";
str = "world";
认为这样算是更改了字符串常量,只能无语。。。