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

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

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

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

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

时间: 2024-10-08 00:49:17

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

使用StringBuffer反转字符串

//获取用户输入的单词 String word=request.getParameter("word"); //将该单词先转StringBuffer 对象,然后再进行字符串反转 StringBuffer sb=new StringBuffer(word); //反转字符串对象sb,使用StringBuffer 的reverse()方法 String changWord=sb.reverse().toString(); 原文地址:http://blog.51cto.com/1197822

【LeetCode-面试算法经典-Java实现】【152-Reverse Words in a String(反转字符串中的单词)】

[152-Reverse Words in a String(反转字符串中的单词)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given an input string, reverse the string word by word. For example, Given s = "the sky is blue", return "blue is sky the". 题目大意 给定一个字符串,将其反转,其的字词不转 解题思路

Leetcode#557. Reverse Words in a String III(反转字符串中的单词 III)

题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" 输出: "s'teL ekat edoCteeL tsetnoc" 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格. 思路 分割字符串,再逆序,拼接到字符串 代码实现 package String; /** * 557. Reverse Words in a St

[算法] C# Revert 单词反转字符串[低时间复杂度]

无聊期间想起了一道字符串反转的问题. 大致要求输入"I am a good boy",输出"boy good a am I". 要求不能用已经封装好的方法实现.于是乎,我上网查了一下,基本都是用了封装后类库.于是我自己写了一个小算法,低时间复杂度高空间复杂度的算法. private string Revert(string str) { if (str.Length == 0) { return string.Empty; } string newStr = nul

(C#) 反转字符串,反转一个句子中单词。

这个是非常基本的一道面试题,但是要考虑周全. 首先反转一个字符串: 基本思路是变成Char数组,然后调用C#里面的方法,或者设定两个index,从头,尾向中间遍历,并交换. 方法一: Array.Reverse(char *). 注意在开始的时候要判断字符串为null或空. public static string ReverseString(string input) { if (String.IsNullOrEmpty(input)) { return input; } char[] cha

557. 反转字符串中的单词 III

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" 输出: "s'teL ekat edoCteeL tsetnoc"  注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格. 思路:先将给定的字符串(s)中的单词拆分出来(str),然后单个处理每个单词,拼接成一个新的字符串(ans),返回ans. 总结: 1 static co

Leetcode 557.反转字符串中的单词III

反转字符串中的单词III 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" 输出: "s'teL ekat edoCteeL tsetnoc"  注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格. 实现思路: 刚看题目心想直接用String.split会不会更容易些,不过这样就失去了这个算法的意义了.还是采用最原始的方法,先

反转字符串中的单词 III

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest"输出: "s'teL ekat edoCteeL tsetnoc" 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格. code1:使用自定义reverse函数 class Solution { public: string reverseWords(string s) { i

Leetcode 344:Reverse String 反转字符串(python、java)

Leetcode 344:Reverse String 反转字符串 公众号:爱写bug Write a function that reverses a string. The input string is given as an array of characters char[]. Do not allocate extra space for another array, you must do this by modifying the input array in-place wit