按单词(word)反转字符串(string)输出(output)——不用额外缓存(without a buffer)

来源:互联网 发布:大连淘宝网店装修 编辑:程序博客网 时间:2024/05/29 17:30

一道笔试题,纸上写的,誊到电脑上并调试通过并改善。

没经验,菜鸟摸索的野蛮算法,不知道有没有更简洁更抽象的算法。

打算用现成字符串操作函数的请绕行搜索。


原题是不用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 punsigned 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+cntchar *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.outthe original string is:hello world   hehe piapia ljljand 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 punsigned int cnt = 0;while(*(p + cnt) != ' ' && *(p + cnt) != '\0'){cnt++;}if(*(p + cnt) == ' '){//consider multi spacerecurence(p + cnt + 1);//+1 to avoid deadloop}//output p to p+cntchar *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.outthe original string is:hello world   hehe piapia ljljand the result string is:ljlj piapia hehe   world hello root@v:/usr/local/C-language/Interview# 


修改后有换行符:

^[[Aroot@v:/usr/local/C-language/Interview# ./a.outthe original string is:hello world   hehe piapia ljljand the result string is:ljlj piapia hehe   world hello 


v0.3

关于空格的准确输出:其实很简单,从哪遭遇空格陷入,就从哪输出空格(当然是回来以后~),把之前手动打印空格这种低级手法删掉




CSDN的排版真让人想骂人

这下就可以了,输出(为了测试效果,可以把换行符屏蔽掉~字符串前端两个空格,后端三个空格,反转输出以后空格完全对称):

^[[Aroot@v:/usr/local/C-language/Interview# ./a.outthe 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.outhello WorldSegmentation fault (core dumped)
果然改不了,崩溃了。。。。

PS:之所以要再验证一下,是因为这两天看到CU论坛有小朋友放出话来和人叫板说字符串常量能改,并举例:

char *str = "hello";

str = "world";

认为这样算是更改了字符串常量,只能无语。。。






0 0
原创粉丝点击