剑指offer--7题
*题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
*句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
*例如输入“I am a student.”,则输出“student. a am I”。
终于有一道题的思路是一样的了! 感觉自己的基础太差了!
思路:整体反转+单词再反转。
//时间复杂度为O(n)
//自己编写
#include "stdafx.h"
#include<iostream> void ReserveSentence(char str[]); using namespace std;
int main(int argc, char* argv[])
{
char str[] = "Hello! Ms. World!";
ReserveSentence(str);
return 0;
} void ReserveSentence(char str[])
{
int len = strlen(str);
int i,j;
for(i=0,j=len-1; j>i; i++,j--)
{
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
char* kptr,*iptr;
char ytemp;
char* temptr;
kptr = iptr = str;
bool ReachEnd = false;
while(*iptr != '\0' && !ReachEnd)
{
while(*iptr != ' ' && *iptr != '\0')
iptr++;
if(*iptr == '\0')
ReachEnd = true;
temptr = iptr+1;
iptr--;
while(iptr > kptr)
{
ytemp = *iptr;
*iptr = *kptr;
*kptr = ytemp;
iptr--;
kptr++;
}
kptr = iptr = temptr; }
cout<<str<<endl;
} //标准答案
/*//////////////////////////////////////////////////////////////////////
// Reverse a string between two pointers
// Input: pBegin - the begin pointer in a string
// pEnd - the end pointer in a string
///////////////////////////////////////////////////////////////////////
void Reverse(char *pBegin, char *pEnd)
{
if(pBegin == NULL || pEnd == NULL)
return; while(pBegin < pEnd)
{
char temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp; pBegin ++, pEnd --;
}
} ///////////////////////////////////////////////////////////////////////
// Reverse the word order in a sentence, but maintain the character
// order inside a word
// Input: pData - the sentence to be reversed
///////////////////////////////////////////////////////////////////////
char* ReverseSentence(char *pData)
{
if(pData == NULL)
return NULL; char *pBegin = pData;
char *pEnd = pData; while(*pEnd != '\0')
pEnd ++;
pEnd--; // Reverse the whole sentence
Reverse(pBegin, pEnd); // Reverse every word in the sentence
pBegin = pEnd = pData;
while(*pBegin != '\0')
{
if(*pBegin == ' ')
{
pBegin ++;
pEnd ++;
continue;
}
// A word is between with pBegin and pEnd, reverse it
else if(*pEnd == ' ' || *pEnd == '\0')
{
Reverse(pBegin, --pEnd);
pBegin = ++pEnd;
}
else
{
pEnd ++;
}
} return pData;
}*/
由该题+博主程序+相关评论,自己也学到不少东西(我发现看评论也很费劲啊,参差不齐,估计像我这样的fish不少吧)。
首先,与博主的程序相比,自己所写并未考虑到单词与单词之间或者句子开头有可能是空格的情况,区别点如下:
if(*pBegin == ' ')
{
pBegin ++;
pEnd ++;
continue;
}
其次,有很多问题得到解决,在这里总结下,帮助记忆和回顾
1、就ReverseSentence(char *pData)而言,其输入参数为char*类型,这本身就要求了pData所指向的字符串可被修改;如果为const char*,则pData所指向的字符串只能读,而不能被修改。所以,自己在之前所遇到的“can't convert const char[] to char*”,就是指只能被读的字符串不能转换为既能被读又能被写的字符串。
针对评论:
如果是这样使用,程序正常
char pSentence[] = "I am a student.";
char *p = ReverseSentence(pSentence);
但如果是这样:
char *pSentence = "I am a student.";
char *p = ReverseSentence(pSentence);
程序会在*pBegin = *pEnd; 处异常,
应该是由于这种情况下pSentence指向的是常量字符串,编译器不允许对常量字符串修改的缘故。
楼主代码还不够健壮 ;-)
及回复:
这个函数的作用就是翻转一个句子,会修改字符串的内容。调用者传入常量字符串,本身不符合这个函数的语义。不过从设计API的角度,的确不过健壮。请问哪位有好的解决方案吗? API设计的角度,你使用char*就是要求调用者给出的字符串可修改。
楼上的写法 char* p = "const string"; 本身就是不合规范的,新的编译器都会给严重的警告。
char pSentence[] = "I am a student."; 将常量字符串"I am a student."(位于静态存储区)复制到堆栈中,并将复制后的字符串的地址赋予pSentence,所以char pSentence[] = "I am a student.";所造成的结果:当调用ReverseSentence(pSentence)时,pSentence为char*类型,成功!
char *pSentence = "I am a student."; 将常量字符串"I am a student."(位于静态存储区)的地址赋给pSentence,为常量指针(其实应当声明为
const char *pSentence = "I am a student.";),所以当调用ReverseSentence(pSentence)时,会报错!
2、函数调用的问题(基本问题,看来自己基础不太扎实)
博主 你好 Reverse函数中的pBegin 和pEnd 在翻转完一个单词后分别指向的是单词中间的位置,并不是一开始的头和尾。那
else if(*pEnd == ' ' || *pEnd == '\0')
{
Reverse(pBegin, --pEnd);
pBegin = ++pEnd;
}
这里执行完的话两个指针的位置还是在一个单词内部吧?没有起到指向单词后面的空格的效果?不知是不是我理解错误了。
其实是在该函数被调用时,按值传递!!!所以原pEnd和pBegin不变!
3、当使用指针时,先判空:
1、函数无返回值时,则如下:
if(pBegin == NULL || pEnd == NULL)
return;
2、函数返回char*时,则如下:
if(pData == NULL)
return NULL;
剑指offer--7题的更多相关文章
- 剑指 offer 第一题: 二维数组中的查找
打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- 剑指offer刷题(Tree)
开篇 二刷剑指offer了,本来用Tyora记的笔记,发现字数到四万了就变得好卡o(╥﹏╥)o,刚好开始写博客,就转过来吧,记下来子自己看.不废话,开刷... JZ26. 树的子结构 输入两棵二叉树A ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- 剑指offer刷题
1.面试题43. 1-n整数中1出现的次数 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次 ...
- 剑指offer编程题Java实现——替换空格
题目描述 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. package ...
随机推荐
- Eruda——手机网页前端调试面板
前言 进行移动端网页开发时,想要查看手机浏览器信息从来都不是一件容易的事.特别是当目标环境为APP内置WebView,需要调用特定的JsBridge接口时,你根本都干不了什么,只能一遍又一遍地修改代码 ...
- python学习第二天第一部分
备注:写程序不能写重复性的代码 学习内容:数据类型.for循环.while循环.字符编码.文件处理 一.for循环 1.简单的for循环 for i in range(10): # 此处意思为:循环r ...
- <?php>慢慢写一些php的cookie问题<?>
写网站是个爬坑的过程,在你设计完功能之后,就会发现:卧槽,这个怎么实现?你妹,这个能实现么? 进了公司分工明确还好说(= =学长们都这么说),在学校自己没事写一些项目的话只能自己爬坑了. 蹬蹬瞪蹬,登 ...
- SQLserver查询数据库所有字段-表名
SELECT * FROM INFORMATION_SCHEMA.columns WHERE TABLE_NAME='Account' SELECT (case when a.colorder=1 t ...
- Android判断当前的android设备是否处于联网状态
首先,要想获得当前android设备是否处于联网状态,那么android本身给我们提供了一个服务 private ConnectivityManager connectivityManager;//用 ...
- Android中BaseAdapter的基本用法和加载自定义布局!
public class MainActivity extends Activity { ListView listView = null; @Override protected void onCr ...
- poj 2631 Roads in the North
题目连接 http://poj.org/problem?id=2631 Roads in the North Description Building and maintaining roads am ...
- android开发系列之回调函数
想必对于回调函数大家肯定不陌生,因为这是我们开发里面常用的代码技巧.我也就不废话了,让我们直接来看代码吧! public class TestCallback { public interface I ...
- Android开发初始
由于本人一直的主攻方向是.NET平台,所以移动开发方面主要是Windows Phone平台,但是确实Windows Phone的市场占有率太小了,在加上本人是个技术迷,希望尝试新的东西,所以Andro ...
- 使用spring dynamic modules的理由
spring的主要功能 spring框架提供了轻量级的容器和非侵入式的编程模型,这来自于其依赖注入.AOP和便携服务概念. osgi的主要功能 osgi服务平台提供了动态的应用程序执行环境,支持模块( ...