专栏首页猿人谷字符串反转问题

字符串反转问题

首先是我之前写的程序,同时这也是处理第一类的字符串反转问题,也就是输入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 }

输出为:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 字符串倒序

    以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba” 1 #include<stdio.h> 2 #include<string.h> 3 ...

    猿人谷
  • C++内存管理学习堆和栈

    一 C++内存管理 1.内存分配方式   在讲解内存分配之前,首先,要了解程序在内存中都有什么区域,然后再详细分析各种分配方式。 1.1 C语言和C++内存分...

    猿人谷
  • Reverse Linked List II

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For...

    猿人谷
  • 华为oj之字符串分割

    •连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。

    Enjoy233
  • Leetcode No.7 整数反转

    假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31,  2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

    week
  • C#字符串截取

    yaphetsfang
  • LeetCode 709. 转换成小写字母

    实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。

    Michael阿明
  • 金额转大写

    在处理财务账款时,需要将转账金额写成大写的。也就是说,如果要转账123456.00元,则需要写成“壹拾贰万叁仟肆佰伍拾陆元整”。 所以常常需要通过程序控制自动进...

    崔笑颜
  • Python过滤不可见字符

        for i in range(0,32):         str = str.replace(chr(i),'')

    py3study

扫码关注云+社区

领取腾讯云代金券