• [C/C++] String Reverse 字符串 反转


    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <cstring>
     
    inline void STL_Reverse(std::string& str) // 反转string字符串 包装STL的reverse()  可以inline
    {
        reverse(str.begin(), str.end());
        // STL 反转函数 reverse() 的实现
        /*     template <class BidirectionalIterator>
         *     void reverse(BidirectionalIterator first, BidirectionalIterator last)
         *     {
         *         while ((first != last) && (first != --last))
         *             swap(*first++, *last);
         *     }
         */
    }
     
    void bad_Reverse(std::string& str) // 效率低的反转字符串函数
    {
        std::string tmp(str);
        std::string::size_type ix = str.length() - 1;
        for (std::string::size_type i = 0; i < str.length(); i++) {
            str[i] = tmp[ix];
            ix--;
        }
    }
     
    void good_Reverse(std::string &word)   // 仿制STL的算法的,适合string字符串反转函数
    {                                      // 效率比 C++ Primer Plus 的高一点
        size_t first, last;
        first = 0;
        last = word.size();
        while ((first != last) && (first != --last))
            std::swap(word[first++], word[last]);
    }
     
    void Reverse(std::string &word)   // 适合string字符串反转函数
    {                                 // 来源 C++ Primer Plus 第五章 forstr2.cpp -- reversing an array
        char temp;
        size_t i, j;
        for (j = 0, i = word.size() - 1; j < i; --i, ++j) {
            temp = word[i];
            word[i] = word[j];
            word[j] = temp;
        }
    }
     
    void bad_Reverse(char *str)  // 效率低的反转字符串函数 适合C风格字符串
    {
        char * tmp = new char[strlen(str)];
        strcpy(tmp, str);
        size_t ix = strlen(str) - 1;
        for (size_t i = 0; i < strlen(str); i++) {
            str[i] = tmp[ix];
            ix--;
        }
        delete[] tmp;
    }
     
    void good_Reverse(char *word)   // 仿制STL的算法的,适合C风格字符串反转函数
    {                               // 效率没有 C++ Primer Plus 的高
        size_t first, last;
        first = 0;
        last = strlen(word);
        while ((first != last) && (first != --last))
            std::swap(word[first++], word[last]);
    }
     
    void Reverse(char *word)   // 适合C风格字符串反转函数
    {                          // 来源 C++ Primer Plus 第五章 forstr2.cpp -- reversing an array
        char temp;
        size_t i, j;
        for (j = 0, i = strlen(word) - 1; j < i; --i, ++j) {
            temp = word[i];
            word[i] = word[j];
            word[j] = temp;
        }
    }
     
    int main()
    {
        using namespace std;
        // 1KW 字符串反序函数测试,分别测试同样算法,string 和 C风格字符串的区别
     
        string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for (int i = 0 ; i != 10000001 ; i++)
            //  STL_Reverse(str);   //0.313秒
            //  good_Reverse(str);  //0.875秒
            //  Reverse(str);       //1.063秒
            bad_Reverse(str);       //7.016秒
        cout << str << endl;
     
        char cs[] = "0123456789abcdefghijklmnopqrstuvwxyz";
        for (int i = 0 ; i != 10000001 ; i++)
            // Reverse(cs);        //0.578秒
            // good_Reverse(cs);   //0.859秒
            bad_Reverse(cs);       //13.766秒
        cout << cs << endl;
     
        return 0;
    }

    #define WIN32  // 如果VC编译器定义WIN32 使用gettimeofday()
     
    #include <time.h>
    #ifdef WIN32
    #include <windows.h>
    #else
    #include <sys/time.h>
    #endif
    #ifdef WIN32
    int gettimeofday(struct timeval *tp, void *tzp)
    {
        time_t clock;
        struct tm tm;
        SYSTEMTIME wtm;
        GetLocalTime(&wtm);
        tm.tm_year     = wtm.wYear - 1900;
        tm.tm_mon     = wtm.wMonth - 1;
        tm.tm_mday     = wtm.wDay;
        tm.tm_hour     = wtm.wHour;
        tm.tm_min     = wtm.wMinute;
        tm.tm_sec     = wtm.wSecond;
        tm. tm_isdst    = -1;
        clock = mktime(&tm);
        tp->tv_sec = clock;
        tp->tv_usec = wtm.wMilliseconds * 1000;
        return (0);
    }
    #endif /* WIN32 */
     
     
     
    // 测试执行时间代码
        timeval tv;
        gettimeofday(&tv, NULL);
        double cl = tv.tv_sec + (double)tv.tv_usec / 1000000;
     
    // 添加测试代码
     
        gettimeofday(&tv, NULL);
        cl = (tv.tv_sec + (double)tv.tv_usec / 1000000) - cl;
        printf("
    执行时间 : %0.3f 秒", cl);

    _strrev, _wcsrev, _mbsrev
    Reverse characters of a string.
    
    char *_strrev( char *string );
    
    wchar_t *_wcsrev( wchar_t *string );
    
    unsigned char *_mbsrev( unsigned char *string );
    
    Routine Required Header Compatibility 
    _strrev <string.h> Win 95, Win NT 
    _wcsrev <string.h> or <wchar.h> Win 95, Win NT 
    _mbsrev <mbstring.h> Win 95, Win NT 
    
    
    For additional compatibility information, see Compatibility in the Introduction.
    
    Libraries
    
    LIBC.LIB Single thread static library, retail version 
    LIBCMT.LIB Multithread static library, retail version 
    MSVCRT.LIB Import library for MSVCRT.DLL, retail version 
    
    
    Return Value
    
    Each of these functions returns a pointer to the altered string. No return value is reserved to indicate an error.
    
    Parameter
    
    string
    
    Null-terminated string to reverse
    
    Remarks
    
    The _strrev function reverses the order of the characters in string. The terminating null character remains in place. _wcsrev and _mbsrev are wide-character and multibyte-character versions of _strrev. The arguments and return value of _wcsrev are wide-character strings; those of _mbsrev are multibyte-character strings. For _mbsrev, the order of bytes in each multibyte character in string is not changed. These three functions behave identically otherwise. 
    
    Generic-Text Routine Mappings
    
    TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined 
    _tcsrev _strrev  _mbsrev  _wcsrev  
    
    
    Example
    
    /* STRREV.C: This program checks an input string to
     * see whether it is a palindrome: that is, whether
     * it reads the same forward and backward.
     */
    
    #include <string.h>
    #include <stdio.h>
    
    void main( void )
    {
       char string[100];
       int result;
    
       printf( "Input a string and I will tell you if it is a palindrome:
    " );
       gets( string );
    
       /* Reverse string and compare (ignore case): */
       result = _stricmp( string, _strrev( _strdup( string ) ) );
       if( result == 0 )
          printf( "The string "%s" is a palindrome
    
    ", string );
       else
          printf( "The string "%s" is not a palindrome
    
    ", string );
    }
    
    
    Output
    
    Input a string and I will tell you if it is a palindrome:
    Able was I ere I saw Elba
    The string "Able was I ere I saw Elba" is a palindrome
    
    
    String Manipulation Routines
    
    See Also   strcpy, _strset

    #include <iostream>    // 数据流输入/输出
    char * my_strrev (char * string )
    {
        char *start = string;
        char *left = string;
        char ch;
     
        while (*string++) // 找到string 末位的'',
            ;             // 因为上面 string++,实际指针在 ''的后一个
        string -= 2;      // 所以退2格,回到字符串最后一个字母
        while (left < string) {
            ch = *left;    // 通过临时变量 ch 进行交换
            *left++ = *string;
            *string-- = ch;
        }
        return(start);
    }
    using namespace std;
     
    int main()
    {
        char h[] = "Hello world!";
        cout << my_strrev (h) << endl;
        return 0;
    }

    //通过不同的方法,实现对所输入字符串的反转,可以很好地复习巩固 C++ 基础知识
    /*分析过程:
      假设要使传递的字符串为常量const字符串,这样操作更加灵活,可直接传递字符串字面值进行反转,常见的解决方法就是,定义一个新的与传递过来字符串长度
      相等的字符数组,然后进行字符串拷贝,把str字符按从左到右放置到字符数组中,然后采用循环来对字符数组中字符反转
    */
    /*第一种,采用以上思路解法,传递为const类型C风格字符指针,返回为char*类型*/
    //直接使用字符数组赋值
    char* strrev1(const char* str)
    {
       const size_t length = strlen(str);//求字符长度
       char *temp = new char[length];//新建一个等长度的字符数组
       strcpy(temp,str);//字符串拷贝
       for (size_t i = 0; i <= length/2; ++i)//对字符数组中的字符反转,循环执行条件为标识小于或等于字符长度一半
       {
          char c = temp[i];
          temp[i] = temp[length - i -1];
          temp[length - i -1] = c;
       }
       return temp;//返回反转后的字符
    }
    //采用指针操作方式
    char* strrev2(const char* str)
    {
       char* tmp = new char[strlen(str)];
       strcpy(tmp,str);
       char* ret = tmp;//用来最后返回数组指针
       char* p = tmp + strlen(str) - 1;
       while (p > tmp) 
       { 
          char t = *tmp; 
          *tmp++ = *p; 
          *p-- = t;
       }
       return ret;
    }
    //与上一函数基本相似,只不过本函数使用是移位操作改变字符指针指向
    char* strrev3(const char* str)
    {
       char* tmp = new char[strlen(str) + 1];
       strcpy(tmp,str);
       char* ret = tmp;
       char* p = tmp + strlen(str) - 1;
       while (p > tmp) 
       { 
          *p ^= *tmp;
          *tmp++ ^= *p;          
          *p-- ^= *tmp;
       }
       return ret;
    }
    //节省几步,直接给新建的字符数组赋反转的值,呵呵,简单明了,只不过循环多执行几次
    char* strrev4(const char* str)
    {
       char * temp = new char[strlen(str)];
       for(int i = 0; i <= strlen(str); i++)
       {
          temp[i] = str[strlen(str) - i -1];
       }
       return temp;
    }
    //使用递归进行字符反转,网上看的,不过感觉不好,限制太多
    //(不能直接反转常量字符串,因为没有定义新的字符数组,而是在原数组上直接进行字符反转,节省空间,提高效率,还要传递字符长度,增加限制,但总归是个思路)
    char* strrev5 (char* str,int len)
    {
       if (len <= 1)
          return str;
       char t = *str;
       *str = *(str + len -1);
       *(str + len -1) = t;
       return (strrev5(str + 1,len - 2) - 1);
    }
    /*如果传递是std::string类型字符串且是const的!!
      返回类型为std::string
    */
    std::string strrev6(const std::string str)
    {
      string r ;//定义一个新的字符串变量,用来接收
      string r;
       for(int i = 0; i < str.length(); ++i)
       {
          r = str[i] + r;//注意顺序
       }
      return r;
    }
    /*如果传递是std::string类型字符串,但不是const的!!
      返回类型为std::string,那你将不必再定义一个新的字符串变量
      节省空间,注意:string类型可以直接接受字符串字面值就是啦..
    */
    std::string strrev6(std::string str)
    {
      for(int i = 0; i <= str.length()/2; ++i)
       {
          char c = str[i];
          str[i] = str[str.length() - i -1];
          str[str.length() - i - 1] = c;
         }
       return str;
    }
  • 相关阅读:
    StringTemplate.Net 学习笔记(9):深入了解模板组文件
    StringTemplate.Net 学习笔记(6):自定义输出格式
    StringTemplate.Net 学习笔记(4):表达式元素语法(下)
    StringTemplate.Net 学习笔记(10):模板组继承及模板组接口
    StringTemplate.Net 学习笔记(3):表达式元素语法(上)
    StringTemplate.Net 学习笔记(7):加载模板文件
    StringTemplate.Net 学习笔记(8):加载模板组文件
    十天学会ASP.Net——(10)
    十天学会ASP.Net——(6)
    十天学会ASP.Net——(7)
  • 原文地址:https://www.cnblogs.com/Areas/p/5613019.html
Copyright © 2020-2023  润新知