字符串

字符串是一个我大一大二就没学好的知识点,现在要补回来,有的知识点还不是特别清楚,比如操作啥的,后续要增添操作。

字符串的基本知识

构造函数

字符串有几种常见的构造函数,包括默认构造函数和复制构造函数。

  1. 默认构造函数
    string str;

  2. 一般构造方法
    string str("abc")
    和拷贝构造string str(str1).

除此之外还有一些不常见但是可能会很有用的版本.

  1. 将构造的对象初始化为s的前n个字符,s不够n个时将相邻的内存单元的内容当作s的一部分继续复制:

    string(const char *s, size_type n, const Allocator &a = Allocator());
    string ett("Telephone home.", 4)
    (std::string &) "Tele" 
  2. 将构造的对象初始化为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."
  3. 创建一个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个字符组成的字符串。

几个清除函数

  1. string & erase (size_t pos =0,size_len=npos)
    参数1是起始位置,默认是0,参数2是长度
  2. interator erase(const_interator position)
    参数1是迭代器,返回值是下一个元素的迭代器
  3. 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']即可。

字符串匹配

图片说明