[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("\n執行時間 : %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:\n" );
   gets( string );

   /* Reverse string and compare (ignore case): */
   result = _stricmp( string, _strrev( _strdup( string ) ) );
   if( result == 0 )
      printf( "The string \"%s\" is a palindrome\n\n", string );
   else
      printf( "The string \"%s\" is not a palindrome\n\n", 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 末位的'\0',
        ;             // 因為上面 string++,實際指針在 '\0'的后一個
    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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM