翻转字符串(剑指offer42)

       问题:

       1.输入一个英文单词的顺序,翻转单词的顺序.例如输入的单词是"student",则输出"tneduts"。

       2.输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。

       3.字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的末尾。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"。右旋字符串与之类似,不再累述。


1.翻转一个英文单词(从两端开始交换每一个字符,直到中间位置)--使用数组

void reverseWord(char* pChar, int length) {
	if (NULL == pChar || 0 >= length) {
		return;
	}

	int left = 0, right = length - 1;
	while (left < right) {
		std::swap(pChar[left], pChar[right]);
		++left;
		--right;
	}

	return;
}

2.翻转一个英文单词(从两端开始交换每一个字符,直到中间位置)--使用指针

void reverseWordByPoint(char* pChar, int length) {
	if (NULL == pChar || 0 >= length) {
		return;
	}

	char* p_nStart = pChar;
	char* p_nEnd = pChar + length - 1;
	while (p_nStart < p_nEnd) {
		char ch = *p_nStart;
		*p_nStart = *p_nEnd;
		*p_nEnd = ch;

		++p_nStart;
		--p_nEnd;
	}

	return;
}

3.翻转一个英文句子(先翻转整个句子,然后再分别翻转每一个单词)

void reverseSentence(char* pChar, int length) {
	if (NULL == pChar || 0 >= length) {
		return;
	}

	//首先翻转整个句子
	reverseWordByPoint(pChar, length);
	//然后翻转每一个单词(包括单词后紧跟的标点符号)
	char *pHead = pChar, *pEnd = pChar;
	while (*pHead != '\0') {
		//如果遇到空格不用处理并向前移动
		while (*pEnd == ' ') {
			++pEnd;
			++pHead;
		}

		//统计单词的长度
		int count = 0;
		while (*pEnd != ' ' && *pEnd != '\0') {
			++pEnd;
			++count;
		}

		if (pHead + length != pEnd) {
			//翻转这个单词
			reverseWordByPoint(pHead, count);
			//起始位置变为下一个单词的开始位置
			pHead = pEnd;
		} else {
			//只有一个单词翻转一次即可
			break;
		}

	}

	return;
}

4.左翻转一个字符串(先整个字符串,然后分别翻转最后指定数值的字符串及剩余的前半部分)

void leftReverseString(char* pChar, int length, int number) {
	if (NULL == pChar || 0 >= length || 0 > number || number > length) {
		return;
	}

	//先翻转整个字符串
	reverseWord(pChar, length);
	//然后翻转length-number个字符
	reverseWord(pChar, length - number);
	//最后翻转后number个字符——这就是被左旋过去的那几个字符
	reverseWord(pChar + length - number, number);

	return;
}

5.右翻转一个字符串(跟左翻转类似,只是剩余两次翻转的字符串长度相反)

void rightReverseString(char* pChar, int length, int number) {
	if (NULL == pChar || 0 >= length || 0 > number || number > length) {
		return;
	}

	//先翻转整个字符串
	reverseWord(pChar, length);
	//然后翻转number个字符——这就是被左旋过去的那几个字符
	reverseWord(pChar, number);
	//最后翻转后length-number个字符
	reverseWord(pChar + number, length - number);

	return;
}

测试代码

/*
 *
 *  Created on: 2014-4-9 08:57:59
 *      Author: danDingCongRong
 *
 */

#include <iostream>
#include <string>
#include <cstdio>
#include <stddef.h>
using namespace std;

void copyString(char* pString, char* pResult, int length) {
	if (NULL == pString || NULL == pResult || 0 >= length) {
		cout << "Invalid Parameter." << endl;
		return;
	}

	for (int i = 0; i < length; ++i) {
		pResult[i] = pString[i];
	}

	pResult[length] = '\0';
}

int main() {
	int length = 0;
	cout << "请输入字符串的长度:" << endl;
	while (cin >> length) {
		char* pSource = new char[length + 1];
		//实际操纵的数组
		char* pChar = new char[length + 1];

		getchar();
		gets(pSource);
		*(pSource + length) = '\0';
		//getchar()是程序等着用户按键,用户输入的字符被存放在
		//键盘缓冲区中,直到用户按回车为止(回车字符也放在缓冲区中)。
		//
		//而gets()输入是不会遇到空格就停止的函数。

		cout << "使用数组翻转:" << endl;
		copyArray(pSource, pChar, length);
		reverseWord(pChar, length);
		cout << pChar << endl;

		cout << "使用指针翻转:" << endl;
		copyArray(pSource, pChar, length);
		reverseWordByPoint(pChar, length);
		cout << pChar << endl;

		cout << "翻转句子:" << endl;
		copyArray(pSource, pChar, length);
		reverseSentence(pChar, length);
		cout << pChar << endl;

		int count = 0;
		cout << "输入要翻转的字符长度:" << endl;
		cin >> count;

		cout << "左翻转字符串:" << endl;
		copyArray(pSource, pChar, length);
		leftReverseString(pChar, length, count);
		cout << pChar << endl;

		cout << "右翻转字符串:" << endl;
		copyArray(pSource, pChar, length);
		rightReverseString(pChar, length, count);
		cout << pChar << endl;

		delete pChar;

		cout << "请输入字符串的长度:" << endl;
	}

	return 0;
}


注:部分代码参考自剑指offer


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值