剑指offer--21题
#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题的更多相关文章
- 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Offer 21 这题的解法其实是考察快慢指针和头尾指针. package com.walegarrett.offer; /** * @Aut ...
- 剑指 offer 第一题: 二维数组中的查找
打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- 剑指offer刷题
1.面试题43. 1-n整数中1出现的次数 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次 ...
- 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 剑指offer刷题(Tree)
开篇 二刷剑指offer了,本来用Tyora记的笔记,发现字数到四万了就变得好卡o(╥﹏╥)o,刚好开始写博客,就转过来吧,记下来子自己看.不废话,开刷... JZ26. 树的子结构 输入两棵二叉树A ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
随机推荐
- js数组的内部实现,迭代器,生成器和内包
js内部实现 在js以外的很多语言中,数组将会隐式占用一段连续的内存空间.这种隐式的内部实现,使得高效的内存使用及高速的元素方法称为可能,而 在javascript中,数组实体是一个对象,所以通常的实 ...
- win7里开始菜单属性里的隐私项无法选择解决方法
具体问题如下图,其中的隐私项目呈现灰色无法选择: 解决方法如下: win+R 输入gpedit.msc 回车,[用户配置][管理模板][开始菜单和任务栏],在右侧找到[关闭用户跟踪],双击进入设置界面 ...
- javascript中split字符串分割函数
1. var ss=s.split("fs"); for(var i=0;i<ss.length;i++){ 处理每一个ss[i]; } 2. "2:3:4:5&q ...
- How to setup and process Intercompany accounting [AX2012]
In this post, I will take you through a very simple functionality called the intercompany accountin ...
- 批量kill进程
ps -e | grep java |awk '{print $1}'|xargs kill -9
- 线性结构CT 02-线性结构1 一元多项式的乘法与加法运算
设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. ...
- iOS开发常用的宏
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)#define SCREEN_HEIGHT ([UIScreen mainS ...
- python杂记-3(购买商品)
#!/usr/bin/env python# -*- coding: utf-8 -*-#如下是一个购物程序:#先输入工资,显示商品列表,购买,quit退出,最后格式化输出所买的商品.count = ...
- 4.css度量单位
在 CSS 长度设置中,我们经常需要使用到度量单位,即以什么样的单位设计我们的字 体或边框长度.而在 CSS 中长度单位又分为绝对长度和相对长度. 绝对长度指的是现实世界的度量单位,CSS 支持五种绝 ...
- WPF数据双向绑定
设置双向绑定,首先控件要绑定的对象要先继承一个接口: INotifyPropertyChanged 然后对应被绑定的属性增加代码如下: 意思就是当Age这个属性变化时,要通知监听它变化的人. 即:Pr ...