58 翻转字符串
题目一:翻转单词顺序列
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
测试序列:
1)功能测试(句子中有多个单词、只有一个单词)
2)特殊输入测试(空字符串、字符串中只有空格、)
解题思路:
通过两次翻转字符串(不占用额外的空间)
1)反转句子中所有字符 如"hello world!" 反转后是"!dlrow olleh"
2)再反转每个单词中的字符的顺序 翻转后"world! hello"
class Solution { public: string ReverseSentence(string str) { //string res; int size = str.size(); if(size==0) return str; int pFront = 0; int pBack = size-1; ReverseStr(pFront, pBack, str); //反转每个单词 pBack = 0; while(pFront < size){ if(str[pFront] ==' '){ pBack = ++pFront; //移到下一个单词的首字母 }else if(str[pBack] ==' ' || pBack ==size){ //找到单词结尾后的空格(或字符串结尾) ReverseStr(pFront, --pBack, str); //更新pFront与pBack pFront = ++pBack; }else{ pBack++; //寻找单词结尾 } } return str; } void ReverseStr(int pf, int pb,string &str){ //if(pf==nullptr ||pb==nullptr) //交换的两个指针必须有字符(非空格) //return; while(pf<pb){ char temp = str[pf]; str[pf] = str[pb]; str[pb] = temp; pf++; pb--; } return; } };
代码编写不当:不要对string使用string指针!!!直接用下标即可!!!
string *p = &a;
p++; //不知道是什么,总之不是下一个字符!!!
1 class Solution { 2 public: 3 string ReverseSentence(string str) { 4 //string res; 5 int size = str.size(); 6 if(size==0) 7 return str; 8 9 string *pFront = &str; 10 string *pBack = &str; 11 while(*pBack != "\0"){ 12 pBack++; 13 } 14 pBack--; 15 //翻转整个字符串 16 ReverseStr(pFront, pBack); 17 18 //反转每个单词 19 while(*pFront != "\0"){ 20 if(*pFront ==" "){ 21 pBack = ++pFront; //移到下一个单词的首字母 22 }else if(*pBack ==" " || *pBack =="\0"){ 23 //找到单词结尾后的空格(或字符串结尾) 24 ReverseStr(pFront, --pBack); 25 //更新pFront与pBack 26 pFront = ++pBack; 27 }else{ 28 pBack++; //寻找单词结尾 29 } 30 } 31 32 return str; 33 34 35 } 36 37 void ReverseStr(string *pf, string *pb){ 38 if(pf==nullptr ||pb==nullptr) //交换的两个指针必须有字符(非空格) 39 return; 40 while(pf<pb){ 41 //swap 42 //*pf = *pf + *pb; //此处是字符串,不能相减 43 //*pb = *pf - *pb; 44 //*pf = *pf - *pb; 45 //swap(*pf,*pb); 46 string temp = *pf; 47 *pf = *pb; 48 *pb = temp; 49 pf++; 50 pb--; 51 } 52 return; 53 } 54 };
题目二:左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
测试序列:
1)功能测试(把长度为n的字符串左旋转0个、1个、2个、n-1个、n个、n+1个字符)
2)特殊输入测试(字符串为空串----如果是char*输入,也要考虑字符串指针为空指针,和指针指向空字符串)
解题思路:
参照题目一的思路:
对字符串"abcdefgh"左翻转3位,结果是"defghabc"
1)将字符串分成两个部分,分别是要左移的三位,与剩下的几位。即"abc" "defgh"
对两部分分别翻转:"cbahgfed"
2)然后对得到的字符串翻转
"defghabc"
class Solution { public: string LeftRotateString(string str, int n) { int sz = str.size(); if(n<=0 || sz<=1) return str; n = n%sz; //处理n大于sz时 ReverseStr(0, n-1, str); ReverseStr(n, sz-1, str); ReverseStr(0, sz-1, str); return str; } void ReverseStr(int pf, int pb, string& str){ while(pf<pb){ char temp = str[pf]; str[pf] = str[pb]; str[pb] = temp; pf++; pb--; } return; } };