一道笔试题,纸上写的,誊到电脑上并调试通过并改善。
没经验,菜鸟摸索的野蛮算法,不知道有没有更简洁更抽象的算法。
打算用现成字符串操作函数的请绕行搜索。
原题是不用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"); }
结果:
[email protected]:/usr/local/C-language/Interview# gcc reverse_string_without_buffer.c [email protected]:/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()函数中的手动换行):
^[[[email protected]:/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 [email protected]:/usr/local/C-language/Interview#
修改后有换行符:
^[[[email protected]:/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
整体方法比较野蛮,但逻辑上还说的过去吧。没用什么技巧,时间关系不深究,有懂的高手欢迎指教。
会不定时回来修改完善代码。
============================================================================================================================================================================================================================================================================================================================================================================================================
关于“字符串常量”不可更改的验证:
//try to modify a "constant string" #include<stdio.h> main(){ char *str = "hello World"; printf("%s\n",str); *str = ‘W‘; printf("%s\n",str); }
[email protected]:/usr/local/C-language# ./a.out hello World Segmentation fault (core dumped)
果然改不了,崩溃了。。。。
PS:之所以要再验证一下,是因为这两天看到CU论坛有小朋友放出话来和人叫板说字符串常量能改,并举例:
char *str = "hello";
str = "world";
认为这样算是更改了字符串常量,只能无语。。。
按单词(word)反转字符串(string)输出(output)——不用额外缓存(without a buffer)