• 字符串逆序小结


    1.普通逆序

            可以任意申请内存或变量,对于指针版本,此方法不好,需要在函数内开辟空间,在函数结束前返回该空间首地址,由于不能释放该内存,出现内存泄漏 ,所以这里只提供引用版本:

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void Reverse(string &str) 
    {
        int len = str.size();
        int i, j;
        char tmp;
    
        for (i = 0, j = len - 1; i < j; i++, j--) 
        {
            tmp = str[i];
            str[i] = str[j];
            str[j] = tmp;
        }
    }
    
    int main(void) 
    {
        string tmp;
        cin >> tmp;
    
        Reverse(tmp);
        cout << tmp << endl;
    
        return 0;
    }

    2.字符串原地逆序

            即不能开辟额外的内存空间,思想是将字符串两边的字符逐个交换位置。定义两个指针分别指向字符串头部和尾部。

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    using namespace std;
    
    char* Reverse(char *str)
    {
        char* p = str;        //    p指针指向字符串头部
        
        char* q = str;
    
        while (*q != '')
            q++;
    
        q--;                //q指针指向字符串尾部
    
        while (p < q)
        {
            char temp;
            temp = *p;    *p++ = *q;    *q-- = temp;
        }
    
        return str;    
    }
    
    int main()
    {
        char str[50];
    
        printf("请输入一个小于50的字符串:
    ");
    
        gets(str);
        
        cout<< endl << "原地逆序结果为:" << Reverse(str) << endl;
    
        return 0;
    }

    3.字符串原地逆序-异或版

            在要求不使用临时变量情况下可以使用异或交换两个变量的值。   先唠唠异或操作:

    参与异或运算的两个变量,如果两个相应bit位相同,则结果为0,否则为1。

    即:
    0^0 = 0,      1^0 = 1,      0^1 = 1,      1^1 = 0
    不难得出按位异或的几个特点:
    (1) 任何数与全0异或,不变
    (2) 任何数与全1异或, 取反
    (3) 任何数与自己异或,则把自己置0

    类似于不用中间变量交换两个变量的值:a = a + b;  b = a – b;  a = a – b;

    不用中间变量交换两个变量的值还可以使用异或操作:

    例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
    a = a^b; //a=10100111
    b = b^a; //b=10100001
    a = a^b; //a=00000110

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    using namespace std;
    
    char* Reverse(char* str)
    {
        char* p = str;
    
        char* q = str;
    
        while (*q != '')
            q++;
    
        q--;
    
        while (p < q)
        {
            *p = *p ^ *q;
            *q = *p ^ *q;
            *p = *p ^ *q;
    
            p++; q--;
        }
    
        return str;
    }
    
    int main()
    {
        char str[50];
    
        printf("请输入一个小于50的字符串:
    ");
    
        gets(str);
    
        cout<< endl << "原地逆序结果为:" << Reverse(str) << endl;
    
        return 0;
    }

    4.对一个句子按单词逆序

             比如,输入”I am a student”,要求输出”student a am I”

    参考字符串原地逆序,不妨先将句子的输出结果逆序,即为”I ma a tneduts”,可以看出正好是输入句子中的每个单词的逆序。   则解题思路可以先将输入的句子按单词逆序,最后将结果再次逆序即可。

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    using namespace std;
    
    
    void ReverseWord(char* p, char* q) 
    {
        while (p < q)
        {
            char temp;    
            temp = *p;    *p++ = *q;    *q-- = temp;
        }
    }
    
    
    char* ReverseSentence(char* str) 
    {
        char* p = str;
    
        char* q = str;
        
        /*  处理整个句子内的单词  */
        while (*q != '')
        {
            if (*q == ' ')        /*  遇到空格:标志着单词结束*/
            {
                ReverseWord(p, q-1);
    
                p = ++q;        /*  指向下一个单词首字母  */
            }
            else
            {
                q ++;
            }
    
        }
        /**  对最后一个单词逆序  **/
        ReverseWord(p, q-1);
    
        /**  最后将整个句子逆序  **/
        ReverseWord(str, q-1);
    
        return str;
    }
    
    int main()
    {
        char str[50];
    
        printf("请输入一个小于50的字符串:
    ");
    
        gets(str);
    
        cout<< endl << "原地逆序结果为:" << ReverseSentence(str) << endl;
    
        return 0;
    }

    5.字符串逆序打印

            此类问题因为不需要存储,比较简单,这里只介绍一个利用递归的调用和回溯正好相反的小技巧。

    比如:

    zfc

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    using namespace std;
    
    //利用递归调用顺序和回溯顺序相反
    
    void PrintString()
    {
        char char1;
    
        scanf("%c", &char1);
    
        if (char1 != '#')
        {
            PrintString();
        }
        
        if(char1 != '#')
        {
            printf("%c", char1);
        }
    }
    
    int main()
    {
        PrintString();
    
        return 0;
    }

    更多阅读参考:http://www.cnblogs.com/graphics/archive/2011/03/09/1977717.html

  • 相关阅读:
    大话计算机网络一 聊聊UDP
    Go调度器系列(2)宏观看调度器
    Go语言高阶:调度器系列(1)起源
    gin+go-micro+etcd实战一
    记录一次云主机部署openstack的血泪史
    paste deploy 学习笔记
    Openstack计算Nova组件
    jumpserver docker简单搭建
    [原创][开源] SunnyUI.Net 帮助文档目录
    [原创][开源]SunnyUI.Net, C# .Net WinForm开源控件库、工具类库、扩展类库、多页面开发框架
  • 原文地址:https://www.cnblogs.com/HHxiaoyi/p/4812004.html
Copyright © 2020-2023  润新知