第三篇博客——字符串
字符串
字符串是一个我大一大二就没学好的知识点,现在要补回来,有的知识点还不是特别清楚,比如操作啥的,后续要增添操作。
字符串的基本知识
构造函数
字符串有几种常见的构造函数,包括默认构造函数和复制构造函数。
默认构造函数
string str;
一般构造方法
string str("abc")
和拷贝构造string str(str1)
.
除此之外还有一些不常见但是可能会很有用的版本.
将构造的对象初始化为s的前n个字符,s不够n个时将相邻的内存单元的内容当作s的一部分继续复制:
string(const char *s, size_type n, const Allocator &a = Allocator()); string ett("Telephone home.", 4) (std::string &) "Tele"
将构造的对象初始化为s的后n个字符,也就是从s指向的内存的第n个字节开始复制:
string(const string &str, size_type pos,size_type n = npos, const Allocator &a = Allocator()); root [15] string att("Telephone home.") (std::string &) "Telephone home." root [16] string et(att, 4) (std::string &) "phone home."
创建一个n个字符的string对象:
string(size_type n, char c, const Allocator &a = Allocator()) root [6] string(10, 'a') (std::string) "aaaaaaaaaa"
可以看出3和4构造函数的主要区别在于是用字符串常量还是string对象做第一个参数。
另一个区别是,4中的第三个参数是要复制的字符个数,和2的第二个从参数不同的是,如果npos过大的话,它会在复制完str后停止:
root [0] string att("Telephone home.") (std::string &) "Telephone home." root [4] string (att, 4, 100) (std::string) "phone home." root [5] string ("Telephone home.", 4, 5) (std::string) "phone" root [1] string ("Telephone home.", 4, 100) (std::string) "phone home."
上述代码中因为第三个参数是int,所以所有的构造函数都自动和2匹配,并且将字符串常量初始化为临时string对象。
其余常用函数
int found=str.find("abx");
在字符串中找到特定字符的函数是find(),若找到就返回对应的下标,若找不到就返回string::npos。
string substr=str.substr(3,5);
找到从3下标处开始5个字符组成的字符串。
几个清除函数
string & erase (size_t pos =0,size_len=npos)
参数1是起始位置,默认是0,参数2是长度interator erase(const_interator position)
参数1是迭代器,返回值是下一个元素的迭代器interator erase(const_interator position1,const_interator position2)
删除区间是开区间[position1,position2],返回值是被删除后一个字符的迭代器。
字符串处理
特殊乘法
在特殊乘法中,需要将输入的长数字当作字符串来处理,用str[i]-'0'来表示某位上的数字
//写个算法,对2个小于1000000000的输入,求结果。 特殊乘法举例:123 * //45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5(THU) //这题应该用字符串处理 #include <iostream> #include<cstdio> #include <string> using namespace std; int main(){ string a,b; while(cin>>a>>b){ int answer=0; for(int i=0;i<a.size();i++){ for(int j=0;j<b.size();j++){ answer+=(a[i]-'0')*(b[j]-'0'); } } cout<<answer<<endl; } return 0; }
密码类题目
⚠️一个小tips:在遇到输入是一整行字符串的时候,如果用 while(cin>>str)
遇到空格就会停止输入,这样就会与题目要求的不会符合,所以应该用while(getline(cin,str))
关于循环平移的问题,可以使用对字母进行减法操作后,再对字母个数26取模,就可以得到凯撒密码str[i]=(str[i]-'A'-5+26)%26+'A';
统计字符
⚠️初始化数组的技巧:memset(num, 0, sizeof(num));
//统计一个给定字符串中指定的字符出现的次数。 # include<iostream> # include<cstring> #include<string> #include<cstdio> using namespace std; int num[128]; // 标准ASCII码字符集总共的编码有128个, // 包括32个通用控制符,10个十进制数码, // 52个英文大小写字母和34个专用符号. int main(){ string str1,str2; while(getline(cin, str1)){ if(str1 =="#") break; getline(cin,str2); // 内存操作函数 // memset(num,0,sizeof num); // 将以num为起始地址的数组全部初始化为0 memset(num, 0, sizeof(num)); for(int i=0;i<str2.size();i++) num[str2[i]]++;//统计所有字符数量 for(int i=0;i<str1.size();i++) cout<<str1[i]<<" "<<num[str1[i]]<<endl; //只输出需要的 } return 0; }
上面这题是需要统计特殊字符,比如空格啥的。但是如果只是统计字母,那么就只需要准备26个int大小的数组,对应arr[c-'A']即可。
字符串匹配