• 程序员面试题精选100题(07)翻转句子中单词的顺序


    题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标 点符号和普通字母一样处理。

    例如,输入"I am a student.",则输出"student. a am I"。

          第一次遇到这道题是十一之前去一个公司笔试的时候,当时想到一个方法,似乎有点麻烦,只是在纸面上写了出来,并没有电脑上运行。后来去单位,跟几个同事讨论,得出了正确的思路,前段时间准备笔试的过程中在《程序 员面试宝典》中也见过,当时写出了全部代码的实现,并且运行正确,现在一个多月过去了,再次看到的时候该知道的方法依然记得,只是在编程的时候忽略了很多的细节,比如,如果想要在函数内部改变变量的值需要给函数传递的是引用, 数组的越界问题,如何确定互换顺序的中间元素,对于最后一个单词,应该检测的是他的结尾是不是字符串的结束符(我竟然将字符串的结束符写成'0',后来发现后才改为'\0'),有很多的问题听起来都很可笑,因为都是一些基础,但是我还是决定写出来,让自己印象深刻,对于曾经犯过的错误记录下来,过段时间再回过头来看的时候就可以避免相同的问题。

          分析:
          <方法一>:使用字符串。整体的一个思路就是先将整个字符串互换,然后再将相应的单词互换。即遍历全部互换的字 符串,记录起始点的位置,当遇到空格时即停止,此时再记录终止点的位置,互换起点和终点之间的单词即可,句子之中的 一些单词需要的是碰到' ',则停下开始颠倒单词,但是对于最后一个单词,需要判断遍历的数字值是否为'\0'。对于char 型,我们在对其赋值时需要在字符串的末尾加上一个'\0',表示字符串结束,对于string型,C++库函数已经封装好,会在初始化结束之后自动在末尾添加'\0',当我们使用string.length()函数时,获得的大小也是不包含'\0'的值,所以对颠倒后的字符串的遍历需要让循环变量i=string.length()的值,让他指到'\0'所在的位置,并以此来对最后一个单词的位置颠倒启动一定的判断作用。
          在遍历的过程中有一些问题需要注意,基本上都是数组的下标的问题,一开始写的时候很多的一些关系没搞明白,必须不停的断点调试,总结出最后的结果,后来想了想他的原理,不需要举例子就可以相同了。例如,当互换整个句子和每一个单词时,只需要从第一个位置开始遍历到中间即可,在给定的条件中,我们知道的是整个句子的长度,因此只需要让循环变量i小于句子长度的一半即可,i<(length/2);因为length表示的是字符串的大小,所以i<(length/2);i所能到达的范围就是数组的前半部分,奇数时,i到达不了数组中间的元素(因为他也不需要颠倒),偶数时就正好是我们所需要的结果。


    完整代码如下:

        <方法二>:使用指针。主要也是为了能够当使用指针所指向的内容来改变字符串的值。在写代码的过程中依然有一些基础知识的问题困扰过我,主要是程序中不同作用范围的变量的存储问题,例如在一开始编程时写过这样一段代码:

    1 char *pChar = "today is saturday and tomorrow is sunday";

    这个程序在编译时就无法通过,主要是内存的访问问题,因为pChar是一个常量字符串,作用于全局范围,主要放置在静态变量,在程序的所有运行过程中是不变的。下面这段文字摘自《程序员面试宝典》中对于内存的一些讲解:

    栈区(stack):由编译器自动分配和释放,存放函数的参数值,局部变量的值等。

    堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两码事,分配方式倒是类似于链表。

    全局区(静态区)(static):全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域内,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。

    文字常量区:常量字符串就是放在这里的,程序结束后由系统释放。

    程序代码区:存放函数体的二进制代码。

    使用指针的代码如下:

     1 #include <iostream>
    2 using namespace std;
    3
    4 //使用两个指针,分别指向每一句话和每一个单词的开头,使用指针将指针所指内容进行互换进行互换
    5 void Reverse(char *pB, char *pE)
    6 {
    7 //首先进行判断,函数输入的参数是否都为空,如果是,则不进行任何操作,直接返回。
    8 if( pB == NULL || pE == NULL )
    9 return;
    10
    11 //如果pB<pE,则pB++,pE--,并互换他们的内容,主要用于更换整个句子的顺序以及每一个单词内字母的顺序
    12 while(pB < pE )
    13 {
    14 char temp = *pB;
    15 *pB = *pE;
    16 *pE = temp;
    17
    18 pB++;
    19 pE--;
    20 }
    21 }
    22
    23 char* ReversePerWords(char *pData)
    24 {
    25 //如果输入的参数为空,则不进行任何操作,返回NULL
    26 if(pData == NULL)
    27 return NULL;
    28
    29 //初始化三个指针,将其指向初始字符串的开始位置
    30 char *pBegin;
    31 char *pEnd ;
    32
    33 pBegin = pEnd = pData;
    34
    35 //开始进行逐单词的位置互换
    36 while( 1 )
    37 {
    38 //首先判断pEnd是否指向了一个空格位置或者字符串的结束符处,如果不是,则继续循环,是则循环终止
    39 while( *pEnd != ' ' && *pEnd != '\0')
    40 pEnd++;
    41
    42 //判断pEnd是否指向了字符串的结束符处
    43 //如果是,则表明整个字符串只进行一次单词的互换,当互换结束后需要推出循环,并退出整个函数
    44 //如果不是,则对单词内字母顺序互换之后还要处理pBegin和pEnd指针的位置。
    45 if(*pEnd == '\0')
    46 {
    47 pEnd--;
    48 Reverse(pBegin , pEnd);
    49 break;
    50 }
    51 else
    52 {
    53 //先将pEnd指针指回到上一个不是空格的位置
    54 pEnd--;
    55
    56 Reverse(pBegin, pEnd);
    57
    58 pEnd++;
    59
    60 //该处判断主要用于连续空格处,以避免进行了多余的空格和空格的交换
    61 //将pEnd指向下一个可以用于交换的地方,再将该地址赋予pBegin
    62 while( *pEnd == ' ')
    63 pEnd++;
    64
    65 pBegin = pEnd;
    66 }
    67 }
    68 return pData;
    69 }
    70
    71 void main()
    72 {
    73
    74 char pChar[100] = "today is Saturday and tomorrow is Sunday?";
    75 cout<<pChar <<endl;
    76
    77 char *pStart = pChar;
    78 char *pEnd = pChar;
    79
    80 pStart = pEnd = pChar;
    81
    82 //先将pEnd指向整个句子的末尾
    83 while( *pEnd != '\0')
    84 pEnd++;
    85 pEnd--;
    86
    87 //更换整个句子的顺序
    88 Reverse(pStart, pEnd);
    89
    90 //错误提示:由于函数传递参数仅仅是值的传递,pStart和pEnd的值并没有改变,所以不需要对这两个变量进行更新,便可直接使用
    91 //pStart = pEnd = pChar;
    92
    93 //再互换整个句子中每个单词的顺序
    94 ReversePerWords( pStart );
    95
    96 cout<<pChar<<endl;
    97 }



  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/wdw828/p/2337865.html
Copyright © 2020-2023  润新知