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里的串大小,若设置大小大于当前串长度,则用字符来填充多余的.
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
",&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

原文地址:https://www.cnblogs.com/lemaden/p/10120660.html