*题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。 
*句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。 
*例如输入“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题的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 剑指offer刷题(Tree)

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

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

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

  9. 剑指offer刷题

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

  10. 剑指offer编程题Java实现——替换空格

    题目描述 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. package ...

随机推荐

  1. Gridview 行变色和行按钮调用前端js

    1.鼠标移动某一行 ,变色 protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Ro ...

  2. 深入浅出MongoDB(三)环境搭建

    上次的博文深入浅出MongoDB(二)概述中我们已经将MongoDB的相关概念讲解了一下,接下来我们继续进行MongoDB学习.在学习之前,大家首先需要在自己的电脑上安装MongoDB. 1.安装 安 ...

  3. 多层级Spinner列表选项实时更新树形层级(选择城市)

    package com.example.spinnerdemo; import android.os.Bundle; import android.app.Activity; import andro ...

  4. Dalvik opcodes

    原文地址: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html Dalvik opcodes Author: Gabor Paller V ...

  5. Toast提示信息

    用Toast来作为操作成功以及用户误操作等等的提示,非常的简单.直接上代码: 创建方式一: ps: 此处没有设置toast的其他属性,均使用默认的风格(个人觉得默认的风格除了字体比较小之外 还是挺好看 ...

  6. Python学习教程(learning Python)--3.3 分支语句的条件表达式详解

    本节主要讨论分支语句的条件表达式问题. 在if或者if-else分支控制语句里由于都用到条件判断(表达式是真还是假),条件判断可以是一种关系运算也可以是布尔表达式. 本节将对if及if-else语句的 ...

  7. Python学习教程(learning Python)--2.3.5 Python返回多个值问题

    本节主要学习Python的函数是如何同时返回多个值的问题. 在学习Python的时候惊奇的发现,Python的函数可以同时返回多个值,很有意思. #define function sum def su ...

  8. Moses manual 中Basline System 2.3.4节用IRSTLM创建语言模型的命令有误

    手册里写到: ~/irstlm/bin/compile-lm \ --text yes \ news-commentary-v8.fr-en.lm.en.gz \ news-commentary-v8 ...

  9. vim命令收集(持续中)

    保存: 按ESC键 跳到命令模式,然后: :w 保存文件但不退出vi:w file 将修改另外保存到file中,不退出vi:w! 强制保存,不推出vi:wq 保存文件并退出vi:wq! 强制保存文件, ...

  10. MIFARE系列5《存储结构》

    Mifare S50把1K字节的容量分为16个扇区(Sector0-Sector15),每个扇区包括4个数据块(Block0-Block3),我们也将16个扇区的64个块按绝对地址编号为0~63,每个 ...