C++字符串反轉


//通過不同的方法,實現對所輸入字符串的反轉,可以很好地復習鞏固 C++ 基礎知識
/*分析過程:
  假設要使傳遞的字符串為常量const字符串,這樣操作更加靈活,可直接傳遞字符串字面值進行反轉,常見的解決方法就是,定義一個新的與傳遞過來字符串長度
  相等的字符數組,然后進行字符串拷貝,把str字符按從左到右放置到字符數組中,然后采用循環來對字符數組中字符反轉
*/
/*第一種,采用以上思路解法,傳遞為const類型C風格字符指針,返回為char*類型*/
//直接使用字符數組賦值

 1 char* strrev1(const char* str)
 2 {
 3    const size_t length = strlen(str);//求字符長度
 4    char *temp = new char[length];//新建一個等長度的字符數組
 5    strcpy(temp,str);//字符串拷貝
 6    for (size_t i = 0; i <= length/2; ++i)//對字符數組中的字符反轉,循環執行條件為標識小於或等於字符長度一半
 7    {
 8       char c = temp[i];
 9       temp[i] = temp[length - i -1];
10       temp[length - i -1] = c;
11    }
12    return temp;//返回反轉后的字符
13 }

 

//采用指針操作方式

 1 char* strrev2(const char* str)
 2 {
 3    char* tmp = new char[strlen(str)]; 
 4    strcpy(tmp,str); 
 5    char* ret = tmp;//用來最后返回數組指針
 6    char* p = tmp + strlen(str) - 1;
 7    while (p > tmp)  
 8    {  
 9       char t = *tmp;  
10       *tmp++ = *p;  
11       *p-- = t;
12    }
13    return ret;
14 }

 

//與上一函數基本相似,只不過本函數使用是移位操作改變字符指針指向

 1 char* strrev3(const char* str)
 2 { 
 3    char* tmp = new char[strlen(str) + 1];
 4    strcpy(tmp,str); 
 5    char* ret = tmp;
 6    char* p = tmp + strlen(str) - 1;
 7    while (p > tmp)  
 8    {  
 9       *p ^= *tmp;
10       *tmp++ ^= *p;           
11       *p-- ^= *tmp;
12    } 
13    return ret;
14 }


//節省幾步,直接給新建的字符數組賦反轉的值,呵呵,簡單明了,只不過循環多執行幾次

1 char* strrev4(const char* str)
2 { 
3    char * temp = new char[strlen(str)]; 
4    for(int i = 0; i <= strlen(str); i++)
5    {
6       temp[i] = str[strlen(str) - i -1];
7    }
8    return temp;
9 }

 

//使用遞歸進行字符反轉,網上看的,不過感覺不好,限制太多
//(不能直接反轉常量字符串,因為沒有定義新的字符數組,而是在原數組上直接進行字符反轉,節省空間,提高效率,還要傳遞字符長度,增加限制,但總歸是個思路)

1 char* strrev5 (char* str,int len)
2 {
3    if (len <= 1)
4       return str;
5    char t = *str; 
6    *str = *(str + len -1); 
7    *(str + len -1) = t; 
8    return (strrev5(str + 1,len - 2) - 1); 
9 }

 

/*如果傳遞是std::string類型字符串且是const的!!
  返回類型為std::string
*/

 1 std::string strrev6(const std::string str)
 2 {
 3   string r ;//定義一個新的字符串變量,用來接收
 4   string r;
 5    for(int i = 0; i < str.length(); ++i)
 6    {
 7       r = str[i] + r;//注意順序
 8    }
 9   return r;
10 }

 

/*如果傳遞是std::string類型字符串,但不是const的!!
  返回類型為std::string,那你將不必再定義一個新的字符串變量
  節省空間,注意:string類型可以直接接受字符串字面值就是啦..
*/ 

 1 std::string strrev6(std::string str)
 2 {
 3   for(int i = 0; i <= str.length()/2; ++i)
 4    {
 5       char c = str[i];
 6       str[i] = str[str.length() - i -1];
 7       str[str.length() - i - 1] = c;
 8      }
 9    return str;
10 }

string類常用的構造函數有:

1 string str;        //生成一個空字符串
2  
3 string str ("ABC")  //等價於 str="ABC"<br>
4 string str ("ABC", strlen)  // 將"ABC"存到str里,最多存儲前strlen個字節
5  
6 string s("ABC",stridx,strlen)   //將"ABC"的stridx位置,做為字符串開頭,存到str里.且最多存儲strlen個字節.
7     
8 string s(strlen, 'A')  //存儲strlen個'A'到str里

string類常用的成員函數有:

 1 str1.assign("ABC");        //清空string串,然后設置string串為"ABC"
 2  
 3 str1.length();                 //獲取字符串長度
 4  
 5 str1.size();            //獲取字符串數量,等價於length()
 6  
 7 str1.capacity();          //獲取容量,容量包含了當前string里不必增加內存就能使用的字符數
 8  
 9 str1.resize(10);           //表示設置當前string里的串大小,若設置大小大於當前串長度,則用字符\0來填充多余的.
10 str1.resize(10,char c);     //設置串大小,若設置大小大於當前串長度,則用字符c來填充多余的
11  
12 str1.reserve(10);         //設置string里的串容量,不會填充數據.
13 str1.swap(str2);              //替換str1 和 str2 的字符串
14  
15 str1.puch_back ('A');      //在str1末尾添加一個'A'字符,參數必須是字符形式
16   
17 str1.append ("ABC");       //在str1末尾添加一個"ABC"字符串,參數必須是字符串形式
18  
19 str1.insert ("ABC",2);       //在str1的下標為2的位置,插入"ABC"
20  
21 str1.erase(2);             //刪除下標為2的位置,比如: "ABCD" --> "AB"
22  
23 str1.erase(2,1);              //從下標為2的位置刪除1個,比如: "ABCD"  --> "ABD"
24  
25 str1.clear();              //刪除所有
26  
27 str1.replace(2,4, "ABCD"); //從下標為2的位置,替換4個字節,為"ABCD"
28  
29 str1.empty();            //判斷為空, 為空返回true
/*assign() :賦值函數 ,里面會重新釋放分配字符串內存 */
 30   str1.assign( "HELLO" );                    //str1="HELLO"
 31  str1.assign( "HELLO" , 4);                 //str1="HELL" ,只保留4個字符
 32  str1.assign( "HELLO" , 2, 3);              //str1="LLO"    ,從位置2開始,只保留3個字符
 33  str1.assign(5,  'c' );                     //str1="CCCCC"             //按字符賦值

const char* c_str();   

返回一個常量C字符串, 內容與本string串相同. 

注意:當本string的內容改變,或被析構后,返回的字符串也不會被改變,因為返回的字符串是從新通過new char[]出來.

參考下面代碼,可以發現返回的C字符串地址和string里的字符串地址完全不同:

 1 string* str = new string("ASD"); //str="ASD" 
 2 const char* c = str->c_str(); 
 3 
 4 cout<<c<<endl;                 //打印 : "ASD" 
 5 
 6 printf("&c[0]=%p,&str[0]=%p\n",&c[0],&str[0]);  
 7                           //打印:c=0x94bf024,&str[0]=0x94bf008
 8 
 9 str->append("dd");            //str="ASDdd"   
10 cout<<c<<endl;                //打印 : "ASD" 
11 
12 delete str;                  //調用析構 
13 
14 cout<<c<<endl;               //打印 : "ASD"

反轉相關(位於頭文件<algorithm>)

1 string str("hello");
2  
3 reverse(str.begin(),str.end());
4  
5 cout<< str <<endl;              //反轉自身字符串,打印olleh

查找相關:

 1 string str("ABCDEFGABCD");                      //11個字符
 2 int n;<br>
 3 /*查找成功返回位置,查找失敗,則n等於-1*/
 4 /*find():從頭查找某個字符串*/
 5 n= str.find('A');              //查找"A",n=0;
 6 n= str.find("AB");             //查找"AB",n=0;
 7 n= str.find("BC",1);           //從位置1處,查找"BC",n=1;
 8 n= str.find("CDEfg",1,3);      //從位置1處,查找"CDEfg"的前3個字符,等價於str.find("CDE",1),n=2;
 9  
10 /*rfind():反向(reverse)查找,從末尾處開始,向前查找*/
11 n= str.rfind("CD");           //從位置10開始向前查找,n=9
12 n= str.rfind("CD",5);         //從位置5開始向前查找,n=2
13 n= str.rfind("CDEfg",5,3);    //等價於str.rfind("CDE",5);       ,所以n=2
14  
15  
16 /* find_first_of ():查找str里是否包含有子串中任何一個字符*/
17 n= str.find_first_of("abcDefg");     //由於str位置3是'D',等於"abcDefg"的'D',所以n=3
18 n= str.find_first_of("abcDefg",1,4); //等價於str. find_first_of ("abcD",1); 所以n=3
19  
20  
21 /* find_last_of ():末尾查找, 從末尾處開始,向前查找是否包含有子串中任何一個字符*/
22 n= str.find_last_of("abcDefg");      //由於str末尾位置10是'D',所以n=10
23 n= str.find_last_of("abcDefg",5,4);  //等價於str. find_last_of ("abcD",5); 所以n=3
24  
25   
26 /* find_first_not_of ():匹配子串任何一個字符,若某個字符不相等則返回str處的位置,全相等返回-1*/
27 n= str.find_last_not_of("ABC");    //由於str位置3'D',在子串里沒有,所以 n=3
28 n= str.find_last_not_of("aABDC");  //由於str位置4 'F',在子串里沒有,所以 n=4
29 n= str.find_last_not_of("aBDC");   //由於str位置0 'A',在子串里沒有,所以 n=0
30 <br>
31 /* find_last_not_of ():反向匹配子串任何一個字符,若某個字符不相等則返回str處的位置,全相等返回-1*/
32 n= str.find_last_not_of("aBDC");  //由於str位置7'A',在子串里沒有,所以 n=7

拷貝相關:

1 str2=str1.substr(2);        //提取子串,提取出str1的下標為2到末尾,給str2
2  
3 str2=str1.substr(2,3);     //提取子串,從 str1的下標為2開始,提取3個字節給str2
4  
5 const char *s1= str.data();   //將string類轉為字符串數組,返回給s1
6 <br>
7 char *s=new char[10];
8 str.copy(s,count,pos);    //將str里的pos位置開始,拷貝count個字符,存到s里.

實例1,通過string類實現字符串循環右移功能

比如:  "abcdefg" 循環右移3位等到: "efgabcd"

代碼如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <sstream>
 4  
 5 using namespace std;
 6  
 7 string operator >>(const string& str,int n)
 8 {
 9        string ret;
10        n %= str.length();
11  
12        ret=str.substr(str.length()-n);              //找到右移的字符串
13        ret+=str.substr(0,str.length()-n); 
14  
15        return ret;
16 }
17  
18 int main()
19 {    
20        string str="abcdefg";
21        string ret= str>>3 ;
22        cout<<ret<<endl;
23  
24        return 0;
25 }

實例2,通過string類實現字符串反轉

比如: "we;tonight;you" -> "ew;thginot;uoy"

代碼如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <sstream>
 4 #include <algorithm>
 5 using namespace std;
 6  
 7 string reverse_func(const string& str)
 8 {
 9        int end;
10        int start=0;
11        int len;
12        string ret="";
13        string tmp;
14  
15       while(1)
16       {
17          end=str.find(';',start);
18  
19          if(end== -1)          //沒找到;
20         {
21          len=str.length()-start;
22          tmp=str.substr(start,len);
23  
24          reverse(tmp.begin(),tmp.end());   //反轉字符串
25  
26          ret+=tmp;
27  
28          return ret;
29         }
30         else               //找到;
31         {
32          len=end-start;
33          tmp=str.substr(start,len);
34  
35          reverse(tmp.begin(),tmp.end());     //反轉字符串
36  
37          ret+=tmp+';';
38          start=end+1;
39         }
40  
41      }  
42  
43 }
44  
45 int main()
46 {    
47        string str("we;tonight;you");
48  
49        string ret=reverse_func(str);
50  
51        cout<< ret<<endl;            
52  
53        return 0;
54 }

 

練習題:

要求:用string完成。題目如下:

1 int main()
2 {
3     cout << reverse("", ';') << endl;                 // 輸出:空字符串
4     cout << reverse(";", ';') << endl;                // 輸出:;
5     cout << reverse("abcde;", ';') << endl;           // 輸出:edcba;
6     cout << reverse("we;tonight;you", ';') << endl;   // 輸出:ew;thginot;uoy
7     
8     return 0;
9 }

參考代碼與思路:

我們觀察,reverse(“”,‘;’)函數需要傳遞‘;’,說明可能需要查找傳入的字符串是否有 ‘;’,查閱資料得到:

string 類中的確有find 成員函數的,它的用法如下:

find():在一個字符串中查找一個指定的單個字符或字符數組。如果找到,就返回首次匹配的開始位置;如果沒有查找到匹配的內容,就返回string::npos。

1.如果是string::npos 輸出空字符串

2.如果找到了‘;’,而且是在位置1,輸出;字符串

3.find_last_of():在一個目標串中進行查找,返回最后一個與指定字符組中任何字符匹配的字符位置。如果沒有查找到匹配的內容,則返回npos。

4.逆轉

5.查找到第一個后繼續往后查找,若count值=2; 記錄;的位置

6.取以;為分割的子串,對每個字串逆序。

7.逆序:二分交換,或者用算法模板begin: end

 

參考博客:https://www.cnblogs.com/lifexy/p/8642163.html


免責聲明!

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



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