字符串反转和句子反转(字符串逆序和句子逆序)
昨天一个哥们面试,面试官给他出一道题:将字符串反转,如qwert,反转为trewq;将一个句子反转,如Do one thing,反转为thing one Do。
首先,这个题目可以可以分为两个题目来做。1、反转字符串。2、反转句子。
1、反转字符串:
我这里用了两种方法:
(1)定义一个反转函数,里面定义一个begin和end指针指向头和尾,将头和尾进行交换,交换后进行begin++,end--。其代码如下:
void myReserve(char *str) { int len =strlen(str); char *begin=str; char *end=begin+len-1; while(str!=NULL&&begin<end) { char temp; temp=*begin; *begin=*end; *end=temp; begin++; end--; } }
(2)定义一个反转函数,里面new一个strlen+1的堆空间,使用类似二分法,将strlen的长度除以2,定义临时变量进行首尾交换。
char* MyReserveTwo(const char* str) { size_t length = strlen(str); char* temp = new char[length+1]; memset(temp, 0x00, sizeof(temp)); memcpy(temp, str, length+1); for(size_t i=0; i<length/2; ++i) { char c = temp[i]; temp[i] = temp[length-i-1]; temp[length-i-1] = c; } return temp; }
上面返回一个new的空间,纯属于个人使用下这种方式而已,其实自己在项目完全没有必要,但如果使用new,记得delete哦。全部代码如下:
#include <stdio.h> #include <string.h> void myReserve(char *str) { int len =strlen(str); char *begin=str; char *end=begin+len-1; while(str!=NULL&&begin<end) { char temp; temp=*begin; *begin=*end; *end=temp; begin++; end--; } } char* MyReserveTwo(const char* str) { size_t length = strlen(str); char* temp = new char[length+1]; memset(temp, 0x00, sizeof(temp)); memcpy(temp, str, length+1); for(size_t i=0; i<length/2; ++i) { char c = temp[i]; temp[i] = temp[length-i-1]; temp[length-i-1] = c; } return temp; } int main(int argc, char** argv) { char str[] = "asdfghjk"; myReserve(str); char* q = MyReserveTwo(str); printf("%s \n", str); printf("%s \n", q); delete[] q; return 0; }
输出如下:
2、反转句子
我那个哥们昨晚跟我讨论了下,关于反正字符串,比较简单,但是反转句子,做起来总是给自己感觉写的太复杂了。我还是说下思路:
首先将所有的字符反正,然后再反转每个单词。我开始也是用调用上的myReserve函数将整个句子反转,然后用strchr查找空格,定义指针p=strchr的返回值,再将p所指向的单个单词进行反转,最后用strcat将所有反转的单词拼接起来。最后也实现了,但是写的太复杂了,最后在网上看到一个还不错的例子,实现思想和我的一致,但是代码比我写的简洁多了,所以就不展示我的代码了,下面附网上一位仁兄相对我而言比较简洁的写法(比自己写的优秀的代码就应该学习学习哈.......):
#include <stdio.h> #include <string.h> char s[50001]=""; void reverse(int begin,int end) { while(begin<end) { char temp=s[begin]; s[begin]=s[end]; s[end]=temp; ++begin; --end; } printf("%s \n", s); } int main() { //memset(s, 0x00, sizeof(s)); while(gets(s)) { //Do one thing at a time, and do well. int len=strlen(s),begin=0; reverse(0,len-1);//反转所有字符 for(int i=0;i<len;i++) { if(s[i]!=' ') { if(i>0 && s[i-1]==' ') begin=i;//将begin设置的index设置到空格处 else if(i<len-1 && s[i+1]==' ' || i==len-1)//反转空格之前的单词 reverse(begin,i); } } printf("%s\n",s); } return 0; }
上面代码的注释是我自己加上的去的,还对其稍微进行了下优化,如变量初始化等。
下面数输出:
自己输入:Do one thing at a time,and do well,最后输出:well do well,and a at thing one Do
总结下:上面分别实现了反转字符串和反转句子。反转字符串用了两种方法实现的,其思想类似二分法,进行前后字符交换;反转句子是先实现整个句子反转,再实现单个单词的反转。上面的代码看上也许你觉得很简单,但是我们只要把简单的事情做好了,自己的技术自然而然就不简单了,就像我一哥们说的:哪里有那么多一战成名,唯有百炼成钢。