字符串反转问题

时间:2022-04-22
本文章向大家介绍字符串反转问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

首先是我之前写的程序,同时这也是处理第一类的字符串反转问题,也就是输入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("%sn",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++ != '')
 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("%sn",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++)!='')
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]=='')
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 }

输出为: