码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-05-22 10:12:28      阅读:298      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   c   code   ext   

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

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

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


原题是不用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 


整体方法比较野蛮,但逻辑上还说的过去吧。没用什么技巧,时间关系不深究,有懂的高手欢迎指教。

会不定时回来修改完善代码。



============================================================================================================================================================================================================================================================================================================================================================================================================

关于“字符串常量”不可更改的验证:

//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";

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






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

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

标签:style   blog   class   c   code   ext   

原文地址:http://blog.csdn.net/huqinwei987/article/details/26099091

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!