每天三道冲刺工作--颠倒一个句子中的词的顺序,比如将“我叫克丽丝”转换为“克丽丝叫我”,

本文探讨了如何使用指针技巧来实现字符串中单词顺序的翻转,同时保持单词内部字符顺序不变。文章深入解析了指针操作的具体实现,并讨论了不同内存区域的作用及其存储特性。

转自 点击打开链接

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

例如,输入"I am a student.",则输出"student. a am 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 }
复制代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值