首先是我之前写的程序,同时这也是处理第一类的字符串反转问题,也就是输入This is a string.,
输出为.gnirts a si sihT:
#include <stdio.h>
#include <string.h>/*我之前的这个代码,有一个很致命的BUG,在字符串长度为奇数的时候运行时正确的
*但是在字符串长度为偶数的时候运行却是错误的,
*比如“ab”,str的地址为0x89,ptr的地址为0x8A,当str++,ptr--执行以后
*str和ptr都是不会相等的,也就是不会结束while循环!!!直到碰巧两者相等
*循环结束,但此时程序已经得不到原先想要的结果了!!!
*/void RevStr(char*str)
{
int len;
char*ptr;
len = strlen(str);
ptr = str + len -1;
while(str != ptr)
{
char ch;
ch =*str;
*str =*ptr;
*ptr = ch;
str++;
ptr--;
}
}
int main()
{
char str[] ="This is a string.";
RevStr(str);
printf("%s/n",str);
return0;
}
在论坛发帖求教后,发现了上述问题,然后改进后的代码如下:
1 #include <stdio.h>
2 #include <string.h>
3
4
5 void RevStr(char *str)
6 {
7 int len;
8 char *ptr;
9
10 len = strlen(str);
11 ptr = str + len - 1;
12
13 while(str != ptr)
14 {
15 char ch;
16 ch = *str;
17 *str = *ptr;
18 *ptr = ch;
19 str++;
20 //ptr自减前,在这里加一个判断,如果相等则结束循环
21 //否则ptr就减一
22 if(str == ptr)
23 break;
24 else
25 ptr--;
26
27 }
28 }
29
30 int main()
31 {
32 char str[] = "This is a string";
33 RevStr(str);
34 printf("%s\n",str);
35 return 0;
36 }
输出结果为:
字符串反转问题的第二类问题是,对于This is a string,最终反转成string a is This。网上对于这个问题,有说用栈来处理。我在看到这个要求,想到上面做的反转问题,觉得可以这样来做:首先,将整个字符串都反转,得到gnirts a si sihT,然后在对每个单词进行反转得到最终的结果,string a is This。
源代码如下:
1 #include <stdio.h>
2
3 int Ustrlen(const char *strSource)
4 {
5 // 声明变量
6 int iLength(0);
7 // 遍历字符串,查找字符'/0'
8 while(*strSource++ != '\0')
9 {
10 ++iLength;
11 }
12 // 返回字符串的长度
13 return iLength;
14 }
15 /************************************************************************/
16 // 函数名称: _ReversalChar
17 // 输入参数: strSouce,待反转字符串;iStart,旋转字符串开始位置;iEnd,旋转字符串结束位置
18 // 输出参数: char*,反转后字符串的指针;
19 // 描 述: 反转iStart到字符串iEnd之间的字符串
20 /************************************************************************/
21 char* _ReversalChar(char *strSouce,int iStart,int iEnd)
22 {
23 // 反转字符串
24 for(;iEnd > iStart; ++iStart,--iEnd)
25 {
26 char ch;
27 ch = strSouce[iStart];
28 strSouce[iStart] = strSouce[iEnd];
29 strSouce[iEnd] = ch;
30 }
31 // 返回字符串指针
32 return strSouce;
33 }
34
35 /************************************************************************/
36 // 函数名称: ReversalChar
37 // 输入参数: strSource,待反转字符串
38 // 输出参数: char*,反转字符串后的指针
39 // 描 述: 按单词反转字符串
40 /************************************************************************/
41 char * ReversalChar(char *strSouce)
42 {
43 // 获取字符串的长度
44 int iLength = Ustrlen(strSouce);
45
46 // 反转整个字符串
47 _ReversalChar(strSouce,0,iLength-1);
48
49 // 声明变量(单词的开始以及结束默认从0开始)
50 int iStart(0),iEnd(0);
51
52 // 查找单词
53 // 像上面讨论的查找单词的情况,我们只需要修改这部分,就可以实现对不
54 // 同格式类型单词进行处理,为了更好的通用性,其实最好把查找单词这部分
55 // 作为单独一个函数,或者一个类来处理
56 for(int i = 0; i <= iLength; ++i)
57 {
58 // 查找空格分割符号
59 //if语句里面第二个判断是用于最后一个单词,不加这个判断最后一个单词反转不了,因为
60 //最后一个单词后面没有空格的,所以只能靠结束符'/0'来判断到达字符串尾,再对其反转
61 if(strSouce[i] == ' ' || strSouce[i] == '/0')
62 {
63 // 找到一个单词
64 iEnd = i-1;
65 // 对于只有一个字符的单词比如说(I)没有必要反转
66 if(iStart < iEnd)
67 {
68 // 反转单词
69 _ReversalChar(strSouce,iStart,iEnd);
70 }
71 // 记录下一个单词的开始位置
72 iStart = i+1;
73 }
74 // 特殊处理几种常见标点符号
75 else if(strSouce[i] == '!' || strSouce[i] == ',' || strSouce[i] == '.')
76 {
77 iStart = i+1;
78 }
79 }
80 // 返回反转后的字符串
81 return strSouce;
82 }
83
84 int main()
85 {
86 char *ptr;
87 char str[] = "This is a string.";
88
89 ptr = ReversalChar(str);
90 printf("%s\n",ptr);
91
92 return 0;
93 }
输出结果为:
给定一字符串,将每个单词的字符顺序倒置,单词间的顺序不变。例如:输入字符串“I love you”,输出“I evol uoy”。
1 #include <iostream>
2 #include <sstream>
3 using namespace std;
4
5 //计算并返回字符串长度
6 int Length(char *str)
7 {
8 int length=0;
9 while((*str++)!='\0')
10 length++;
11 return length;
12 }
13
14 //对单个单词字符反转
15 void _Reverse(char *str,int low,int high)
16 {
17 char tempChar;
18 while(low<high)
19 {
20 tempChar=str[low];
21 str[low]=str[high];
22 str[high]=tempChar;
23 low++;
24 high--;
25 }
26 }
27
28 //利用字符串流读取每个单词并将其反转,单词间有多个空格时合并为一个
29 void Reverse(char *str)
30 {
31 istringstream in(str);
32 int length;
33 for(string s;in>>s;)
34 {
35 length=Length(&s[0]);
36 _Reverse(&s[0],0,length-1);
37 cout<<s<<" ";
38 }
39 }
40
41 //反转的另一个方法,直接对原字符串操作
42 void ReverseVer2(char *str)
43 {
44 int low,high;
45 int length=Length(str);
46 for(int i=0;i<=length;i++)
47 {
48 if(i==0&&str[i]!='\40')
49 {
50 low=i;
51 continue;
52 }
53 if(str[i]!='\40'&&str[i-1]=='\40')
54 {
55 low=i;
56 continue;
57 }
58 if(str[i]=='\40'||str[i]=='\0')
59 {
60 high=i-1;
61 _Reverse(str,low,high);
62 }
63 }
64 }
65
66 int main()
67 {
68 char str[]="I love you";
69 cout<<"first method:";
70 Reverse(str);
71 cout<<endl;
72 ReverseVer2(str);
73 cout<<"second method:"<<str<<endl;
74 return 0;
75 }
输出为: