面试题58-1:翻转单词顺序
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
先对整个字符串翻转,再对字符串中的每个单词做翻转。
#include<bits/stdc++.h>
using namespace std;
//翻转从pBegin到pEnd的字符串
void Reverse(char *pBegin, char *pEnd) {
if(pBegin == nullptr || pEnd == nullptr)//输入合法性检查
return;
while(pBegin < pEnd) {
//交换对称位置的字符
char temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
//对称地向中间移动
pBegin ++, pEnd --;
}
}
//旋转字符串,返回首地址(其实首地址没变,一直在操作指针指向的内容)
char* ReverseSentence(char *pData) {
if(pData == nullptr)
return nullptr;
char *pBegin = pData;//开始之处
char *pEnd = pData;//寻找最后一个字符(结束符前一个字符)
while(*pEnd != '\0')
pEnd ++;
pEnd--;
//翻转整个句子
Reverse(pBegin, pEnd);
//翻转句子中的每个单词
pBegin = pEnd = pData;//两个指针都从头开始
while(*pBegin != '\0') {//pBegin走到结尾就表示所有单词都翻转完了
if(*pBegin == ' ') {//pBegin也走到了空格
//这时end肯定也在这个空格,一起向后走
pBegin ++;
pEnd ++;
} else if(*pEnd == ' ' || *pEnd == '\0') {//pBegin不在空格,但end在空格或者结束符
Reverse(pBegin, --pEnd);//翻转这个字符串
pBegin = ++pEnd;//pBegin和pEnd都踩在这个空格上
} else//pBegin不在空格上说明这是一个单词,pEnd不在空白上说明单词还没找完整
pEnd ++;//pEnd继续向后走,直到遇到空白(空格或结束符)
}
return pData;
}
int main() {
char input[] = "I am a student.";
printf("%s\n",ReverseSentence(input));//student. a am I
return 0;
}
面试题58-2:左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"。
如果当成字符串的拆解拼接来做会比较麻烦,可以先将两部分分别翻转,再翻转整个字符串,因为做了两次翻转所以可以保证这两部分内的有序性,而整个翻转又调换了它们的位置。
#include<bits/stdc++.h>
using namespace std;
//翻转从pBegin到pEnd的字符串
void Reverse(char *pBegin, char *pEnd) {
if(pBegin == nullptr || pEnd == nullptr)//输入合法性检查
return;
while(pBegin < pEnd) {
//交换对称位置的字符
char temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
//对称地向中间移动
pBegin ++, pEnd --;
}
}
//左旋字符串,左旋位置是n
char* LeftRotateString(char* pStr, int n) {
if(pStr != nullptr) {//字符串不能传空指针
int nLength = static_cast<int>(strlen(pStr));//长度
if(nLength > 0 && n > 0 && n < nLength) {//n和nLength的合法性
//左边的子串
char* pFirstStart = pStr;
char* pFirstEnd = pStr + n - 1;
//右边的子串
char* pSecondStart = pStr + n;
char* pSecondEnd = pStr + nLength - 1;
//翻转字符串的前面n个字符
Reverse(pFirstStart, pFirstEnd);
//翻转字符串的后面部分
Reverse(pSecondStart, pSecondEnd);
//翻转整个字符串
Reverse(pFirstStart, pSecondEnd);
}
}
return pStr;
}
int main() {
char input[] = "abcdefg";
printf("%s\n",LeftRotateString(input,2));//cdefgab
return 0;
}