字符串的左旋转操

题目:
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef 左旋转2 位得到字符串cdefab。

请实现字符串左旋转的函数,要求时间对长度为n 的字符串操作的复杂度为O(n),辅助内存为O(1)。

 

思路一:

分析:如果不考虑时间和空间复杂度的限制,最简单的方法莫过于把这道题看成是把字符串分成前后两部分,通过旋转操作把这两个部分交换位置。于是我们可以新开辟一块长度为n+1 的辅助空间,把原字符串后半部分拷贝到新空间的前半部分,再把原字符串的前半部分拷贝到新空间的后半部分。不难看出,这种思路的时间复杂度是O(n),需要的辅助空间也是O(n),显然和题目要求的不符合,因此我们要用另想其他的解法。


把字符串看成有两段组成的,记为XY。左旋转相当于要把字符串XY 变成YX。我们先在字符串上定义一种翻转的操作,就是翻转字符串中字符的先后顺序,把X 翻转后记为XT。显然有(XT)T=X。我们首先对X 和Y 两段分别进行翻转操作,这样就能得到XTYT。接着再对XTYT 进行翻转操作,得到(XTYT)T=(YT)T(XT)T=YX。正好是我们期待的结果。
分析到这里我们再回到原来的题目。我们要做的仅仅是把字符串分成两段,第一段为前面n个字符,其余的字符分到第二段。再定义一个翻转字符串的函数,按照前面的步骤翻转三次就行了。时间复杂度和空间复杂度都合乎要求。

 

代码如下:

  1. /*----------------------------- 
  2. Copyright by yuucyf. 2011.08.15 
  3. ------------------------------*/  
  4. #include "stdafx.h"  
  5. #include <assert.h>  
  6. #include <iostream>  
  7. using namespace std;  
  8.   
  9. void ReverseString(char* pStart, char* pEnd)  
  10. {  
  11.     assert(pStart);  
  12.     assert(pEnd);  
  13.   
  14.     char cTemp;  
  15.     while (pStart <= pEnd)  
  16.     {  
  17.         cTemp = *pStart;  
  18.         *pStart = *pEnd;  
  19.         *pEnd = cTemp;  
  20.   
  21.         pStart++;  
  22.         pEnd--;  
  23.     }  
  24. }  
  25.   
  26.   
  27. char *LeftRotateString(char *pStr, int n)  
  28. {  
  29.     if (NULL != pStr)  
  30.     {  
  31.         int i32Len = static_cast<int>(strlen(pStr));  
  32.         if (i32Len > 0 && i32Len > n)  
  33.         {  
  34.             char *pFirStart = pStr;  
  35.             char *pFirEnd = pStr + n - 1;  
  36.             char *pSecStart = pStr + n;  
  37.             char *pSecEnd = pStr + i32Len - 1;  
  38.   
  39.             ReverseString(pFirStart, pFirEnd);  
  40.             ReverseString(pSecStart, pSecEnd);  
  41.             ReverseString(pFirStart, pSecEnd);  
  42.         }  
  43.     }  
  44.   
  45.     return pStr;  
  46. }  
  47.   
  48.   
  49.   
  50. int _tmain(int argc, _TCHAR* argv[])  
  51. {  
  52.     char aszSrcStr[] = {"abcdef"};  
  53.     cout << "输入的字符串为:"<< aszSrcStr << " 输出的字符串为:";  
  54.     LeftRotateString(aszSrcStr, 2);  
  55.     cout << aszSrcStr << endl;  
  56.     return 0;  
  57. }  
switch while for 1.switch 语句的语法结构。2.理解 switch语中case和default 的作用3.正确使用 break 语句控制程序流程。 1.理解 switch 语句的基本概念和作用。 2.掌握 switch 语句的语法结构。 3.使用 switch 语句解决简单的选择问题。 1.while 循环和 do...while 循环的语法结构和执行流程1.理解 while 循环和 do...while 循环的基 本概念。2.掌握使用 while循环和 do...while循环 2.理解 while循环和 do...while 循环的区别。 “for 循环”的语法结构和执行过程。2.理解“for循环”中循环变量的变化和控制循环的条件。 1.理解“for 循环”的基本概念。2.掌握使用“for循环”解决简单的重复问题。 1.数组的概念和声明方法。 初识数组(1) 2.数组元素的访问。 3.理解数组在内存中的存储方式。 1.数组元素的访问。 初识数组(2))2.理解数组在内存中的存储方式。 3.尝试使用数组解决实际问题. 1.循环嵌套的基本结构和执行流程。 循环嵌套 2.运用循环嵌套输出图形和进行简单计算。 3.理解循环嵌套中内外循环的关系和作用。 数组应用 字符串 .一维数组的定义和初始化。2.对一维数组的元素进行访问和操作。3.理解数组的下标和元素之间的关系 字符串的声明和初始化。2字符串的输入和输出。3.理解字符串在内存中的存储方式。 二维数组的定义和初始化。 二维数组 2二维数组的访问和遍历。 3.理解二维数组的存储结构。 1.理解数组的概念。 2.学会声明和初始化数组。 3.掌握访问数组元素的方法。 1.理解数组的概念。 2.学会声明和初始化数组。 3.掌握访问数组元素的方法。 1.理解循环嵌套的概念。2.掌握使用for循环嵌套实现特定图形输出 和简单计算的方法。1.掌握一维数组的定义和使用方法。2.学会对一维数组进行赋值、遍历和输出操作。 1.理解字符串的概念。2.掌握声明和初始化字符串的方法。3.学会使用字符串进行简单的输出和输入 理解二维数组的概念。2掌握二维数组的定义和初始化方法。3.学会使用二维数组存储和访问数据。 根据此大纲 出一道竞赛题,可根据网络上C++竞赛题出
最新发布
08-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值