#include "stdafx.h"

#include<iostream>
using namespace std;

void LeftRotateString(char* str,int n);
void StringReverse(char* pStart, char* pEnd);

int main(int argc, char* argv[])
{
char str[]="abcdef";   //将"abcdef"拷贝到str[]中,str指向拷贝字符串的首址
int n=3;
LeftRotateString(str,n);
return 0;
}

/*void LeftRoundOper(char* str,int n)
{

int len=strlen(str);
char strtemp[100];
if(n<0 || n>len)
strtemp[0]='\0';

int i,j=0;
for(i=n; i<len; i++)
{
strtemp[j++]=str[i];
}
for(i=0; i<n; i++)
{
strtemp[j++]=str[i];
}
strtemp[j]='\0';

for(i=0; i<j; i++)
cout<<strtemp[i]<<' ';
cout<<endl;
}*/

/*接下来的一种思路可能要稍微麻烦一点。我们假设把字符串左旋转m位。
于是我们先把第0个字符保存起来,把第m个字符放到第0个的位置,在把第2m个字符放到第m个的位置…依次类推,
一直移动到最后一个可以移动字符,最后在把原来的第0个字符放到刚才移动的位置上。
接着把第1个字符保存起来,把第m+1个元素移动到第1个位置…重复前面处理第0个字符的步骤,
直到处理完前面的m个字符。*/

/*我们还是把字符串看成有两段组成的,记位XY。左旋转相当于要把字符串XY变成YX。
我们先在字符串上定义一种翻转的操作,就是翻转字符串中字符的先后顺序。把X翻转后记为XT。显然有(XT)T=X。

我们首先对X和Y两段分别进行翻转操作,这样就能得到XTYT。接着再对XTYT进行翻转操作,得到(XTYT)T=(YT)T(XT)T=YX。
正好是我们期待的结果。

分析到这里我们再回到原来的题目。
我们要做的仅仅是把字符串分成两段,第一段为前面m个字符,其余的字符分到第二段。
再定义一个翻转字符串的函数,按照前面的步骤翻转三次就行了。时间复杂度和空间复杂度都合乎要求。*/

void LeftRotateString(char* str,int n)
{
if(str!=NULL)
{
int len = strlen(str);
if(len>0 && n>0 && n<len)
{
StringReverse(str,str+n);
StringReverse(str+n,str+len);
StringReverse(str,str+len);
cout<<str<<endl;
}
}
}

void StringReverse(char* pStart, char* pEnd)
{
if(pStart!=NULL && pEnd!=NULL)
{
pEnd--;
while(pStart<pEnd)
{
char temp = *pStart;
*pStart = *pEnd;
*pEnd = temp;

pEnd--;
pStart++;
}
}
}

/*标准答案
#include "string.h"

///////////////////////////////////////////////////////////////////////
// Move the first n chars in a string to its end
///////////////////////////////////////////////////////////////////////
char* LeftRotateString(char* pStr, unsigned int n)
{
if(pStr != NULL)
{
int nLength = static_cast<int>(strlen(pStr));
if(nLength > 0 && n > 0 && n < nLength)
{
char* pFirstStart = pStr;
char* pFirstEnd = pStr + n - 1;
char* pSecondStart = pStr + n;
char* pSecondEnd = pStr + nLength - 1;

// reverse the first part of the string
ReverseString(pFirstStart, pFirstEnd);
// reverse the second part of the strint
ReverseString(pSecondStart, pSecondEnd);
// reverse the whole string
ReverseString(pFirstStart, pSecondEnd);
}
}

return pStr;
}

///////////////////////////////////////////////////////////////////////
// Reverse the string between pStart and pEnd
///////////////////////////////////////////////////////////////////////
void ReverseString(char* pStart, char* pEnd)
{
if(pStart != NULL && pEnd != NULL)
{
while(pStart <= pEnd)
{
char temp = *pStart;
*pStart = *pEnd;
*pEnd = temp;

pStart ++;
pEnd --;
}
}
}
*/

给自己做个备份,记录点点滴滴,看进步如何。。。

在验证各种方法时,遇到运行问题,也就是自己之前经常碰到的:在使用指针时,经常出现内存问题

比如该题中,

int main(int argc, char* argv[])
{
char str[]="abcdef";
int n=3;
LeftRotateString(str,n);
return 0;
}

第一种方法,使用char str[]="abcdef";和char* str="abcdef";均可

但标准答案只能使用char str[]="abcdef";

为什么?原因很简单,可惜我才明白。。

参考:http://bbs.csdn.net/topics/340111697

字符串“hello world”本身就是一个字符串常量指针,存储在静态存储区,而第一个指针p,无非就是一个地址的拷贝,也就是“hello world”地址的拷贝,此时的p指向静态存储区的"hello world"
实际就相当于 const char *p = "hello world"; 
======================================================================================
而对于p[]来说就不一样了,虽然"hello world"本身是常量,不过此时拷贝给p[]的不是地址,而是内容,也就是 “hello world”,也就是p本身拥有一个自己的hello world副本,而p此时代表的是自己副本的内存地址,而非静态区的"hello world"。由于p[]是一个局部变量,它的生存期只有在局部函数中,一旦结束调用,p就会消亡,p的内容就会被覆盖!因此结果是不确定的!

所以,"abcdef"是字符串常量,存储于静态存储区,直到程序结束才释放。

char* str="abcdef"将该静态存储区的地址赋予str,所以*str,str[i]均是取原字符串常量中的字符,切记:只能‘读’,不能‘写’,也就是不能修改值!

char str[]="abcdef"则将"abcdef"拷贝到动态存储区(栈)中,使之成为局部变量,此时的str将指向局部存储区的首址,*str,str[i]均取拷贝字符串的各值。因此能‘读’能‘写’。

进一步分析:自己所写的程序(最简单的),仅涉及到str[i],并开辟另外的存储空间,所以char* str="abcdef"与char str[]="abcdef"均可;

标准答案中涉及反转,也就是涉及到本地交换,所以只能char str[]="abcdef",不能修改原字符串常量。

剑指offer--21题的更多相关文章

  1. 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

    剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Offer 21 这题的解法其实是考察快慢指针和头尾指针. package com.walegarrett.offer; /** * @Aut ...

  2. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  3. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  4. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  5. 牛客网剑指offer刷题总结

    二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...

  6. 剑指offer刷题

    1.面试题43. 1-n整数中1出现的次数 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次 ...

  7. 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

    用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...

  8. 剑指offer编程题66道题 36-66

    36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...

  9. 剑指offer刷题(Tree)

    开篇 二刷剑指offer了,本来用Tyora记的笔记,发现字数到四万了就变得好卡o(╥﹏╥)o,刚好开始写博客,就转过来吧,记下来子自己看.不废话,开刷... JZ26. 树的子结构 输入两棵二叉树A ...

  10. LeetCode剑指Offer刷题总结(一)

    LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...

随机推荐

  1. MongoDB 插入文档

    文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 MongoDB 使用 inse ...

  2. 新浪SAE URLRewrite(伪静态、重定向)详解

    SAE全称Sina App Engine,真是一个好东西,他有很多优秀的特性,简单来说SAE就是一个简单高效的分布式Web服务开发.运行平台.支持现在常用的 PHP+Mysql 环境,在开发中难免会碰 ...

  3. LotusPhp起步:经典的HelloWorld

    写了几篇LotusPhp,一直没有跑个程序,感觉好像步骤有点错,所以先上个经典的Demo,HelloWorld吧 先按推荐目录建好文件夹,如果懒的建,下面有下载的Demo包,解压就可以用,因为简单,也 ...

  4. VB 进制转换大全

    '二进制转十进制 Public Function B2D(vBStr As String) As Long Dim vLen As Integer '串长 Dim vDec As Long '结果 D ...

  5. USB协议分析

    一.USB设备描述结构 1.逻辑组织结构 在USB设备的逻辑组织中,包含设备.配置.接口和端点4个层次.设备通常有一个或多个配置,配置通常有一个或多个接口,接口有零或多个端点. 每个USB设备都可以包 ...

  6. apache 403错

    <Directory />Options FollowSymLinksAllowOverride NoneOrder deny,allowAllow from all</Direct ...

  7. Debug.print的用法

    使用Debug.print可以用来更好的调试VBA程序 通过ALT+F11代开VBA编程窗口) 插入模块,接着在窗口中输入以下代码,按F5执行 Sub Excute() Debug.Print * + ...

  8. android几种定时器机制及区别

    在android中,经常用到的定时器主要有以下几种实现:一.采用Handler与线程的sleep(long )方法二.采用Handler的postDelayed(Runnable, long) 方法三 ...

  9. netlink

    http://blog.csdn.net/zirconsdu/article/details/8569193 http://www.xuebuyuan.com/1725837.html netlink ...

  10. Swift的一些基础内容

    //①判断字符串是否为空的方法 isEmpty var str:String = "www.baidu.com" if str.isEmpty { print("空字符串 ...