【字符串】翻转单词顺序,左旋转字符串

面试题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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值