C++ String (例题:洛谷P1032 字串变换)

Powered by:AB_IN 局外人

简单记一下 C + + C++ C++ S t r i n g String String里的知识。可能以后就用 P y Py Py

insert() 插入

a . i n s e r t ( p o s , s t r ) a.insert(pos,str) a.insert(pos,str)
p o s pos pos前插入 s t r str str

	string a="abcd";
    a.insert(2,"lsy");
    cout<<a;
    //ablsycd

erase() 删除

a . e r a s e ( p o s , n ) a.erase(pos,n) a.erase(pos,n)
p o s pos pos后删 n n n个字符。

	string a="abcd";
    a.erase(2,2);
    cout<<a;
    //ab

replace() 替换

a . r e p l a c e ( p o s , l e n , s t r ) a.replace(pos,len,str) a.replace(pos,len,str)
替换 a a a p o s pos pos开始往后 l e n len len的这些字符为 b b b

	string a="abcd";
    a.replace(1,2,"lsy");
    cout<<a;
    //alsyd

a.find() 查找

a . f i n d ( b ) a.find(b) a.find(b)
从开始找 b b b第一次出现的位置并返回下标。

a . f i n d ( b , p o s ) a.find(b,pos) a.find(b,pos)
从pos开始找b第一次出现的位置并返回下标。

r f i n d ( b ) rfind(b) rfind(b) r f i n d ( b , p o s ) rfind(b,pos) rfind(b,pos)
倒着找

如果没有则返回 − 1 -1 1(打印出来是 4294967295 4294967295 4294967295)

	string a="abcda";
    cout<<a.find("a")<<endl;
    cout<<a.find("a",0)<<endl;
    cout<<a.find("a",1)<<endl;
    cout<<
    /*
    0
    0
    4
    4294967295
    */

find_first_of()与find_last_of()

a a a开始(或从 p o s pos pos开始)向后查找,只要在 a a a中遇到一个字符,该字符与 c c c中任意一个字符相同,就停止查找,返回该字符在 a a a中的位置;若匹配失败,返回 − 1 -1 1

	string a="wo xi huan ni ya";
    string b="aeiou";
    int pos=a.find_first_of(b);
    while(pos!=-1)
    {
    
    
        a[pos]='.';
        pos=a.find_first_of(b,pos+1);
    }
    printf("%s",a.c_str());//cout<<a;
    //w. x. h..n n. y.

c _ s t r ( ) c\_str() c_str()可以用 p r i n t f printf printf输出。
f i n d _ l a s t _ o f ( ) find \_last \_of() find_last_of()倒着找

扫描二维码关注公众号,回复: 11782049 查看本文章

find_first_not_of()与find_last_not_of()

即在 a a a中搜寻 b b b中没有的字符并返回位置。

substr() 字串

s u b s t r ( p o s , l e n ) substr(pos,len) substr(pos,len)
返回从 p o s pos pos号位置开始,长度为 l e n len len的字符串。

	string a="abcd";
    cout<<a.substr(1,2);
    //bc

reverse() 取反

r e v e r s e ( 迭 代 器 , 迭 代 器 ) reverse(迭代器,迭代器) reverse( 用于字符串。

	string a="abcd";
    reverse(a.begin(),a.begin()+2);
    cout<<a;
    //bacd

r e v e r s e ( a + p o s 1 , a + p o s 2 ) reverse(a+pos1,a+pos2) reverse(a+pos1,a+pos2) 用于数组。

	char a[4]={
    
    '0','1','2','3'};
    reverse(a,a+3);
    for(char i:a) cout<<i<<" ";
    //2 1 0 3
	int a[4]={
    
    0,1,2,3};
    reverse(a,a+3);
    for(int i:a) cout<<i<<" ";
    //2 1 0 3

P1032 字串变换

以前看着好难的的 b f s bfs bfs题,现在一看,还蛮简单的。
R E RE RE了将近 2 h 2h 2h,终于 D u b u g Dubug Dubug出了问题。
先给出原来的 R E RE RE代码(80分)

#include <bits/stdc++.h>

using namespace std;
struct sa{
    
    
    string s;
    int step;
};
queue<sa> q;
string a,b,a1,b1,a2[8],b2[8];
unordered_map<string,int>m;
int n=1;
int main()
{
    
    
	cin>>a>>b;
    while(cin>>a2[n]>>b2[n]) n++;
    q.push( (sa) {
    
    a,0});
    while(!q.empty())
    {
    
    
        sa tmp=q.front();
        string s=tmp.s;
        if(m[s]){
    
    
            q.pop();
            continue;
        }
        q.pop();
        int step=tmp.step;
        if(s==b&&step<=10){
    
    
            cout<<step<<endl;
            return 0;
        }
        if(step>10){
    
    
            cout<<"NO ANSWER!"<<endl;
            return 0;
        }
        m[s]=1;
        for(int i=1;i<=n;i++){
    
    
            a1=a2[i];
            b1=b2[i];
            string s1=s;
            for(int j=s1.find(a1);j<s1.size();j=s1.find(a1,j+1)){
    
    
                s1=s;
                s1.erase(s1.begin()+j,s1.begin()+j+a1.size());
                s1.insert(j,b1);
                q.push( (sa) {
    
    s1,step+1});
            }
        }
    }
    cout<<"NO ANSWER!"<<endl;
	return 0;
}

主要在于这

		for(int i=1;i<=n;i++){
    
    
            a1=a2[i];
            b1=b2[i];
            string s1=s;//重定义了s1
            for(int j=s1.find(a1);j<s1.size();j=s1.find(a1,j+1)){
    
    
                s1=s;
                s1.erase(s1.begin()+j,s1.begin()+j+a1.size());
                s1.insert(j,b1);
                q.push( (sa) {
    
    s1,step+1});
            }
        }

据报错,是string越界了,报错信息如下:

terminate called after throwing an instance of ‘std::out_of_range’
what(): basic_string::replace: __pos (which is 31) > this->size()
(which is 1 4)

其实是 j = 31 j=31 j=31 s 1. s i z e ( ) = 14 s1.size()=14 s1.size()=14导致越界

什么原因呢?

前后两次赋值str的首地址极有可能是变化的。

因为string里面的内存是动态分配的,想要赋值新的值,必须把上一次分配的空间收回,然后再分配更大的空间,所以首地址很有肯能是变化的。

可能被分配的地址还是上一个字符串的地址,所以导致越界。

所以

如果要定义一个与 x x x相同的值并需要用它,那么尽量在循环内定义。

正解在下:

u n o r d e r e d _ m a p unordered \_map unordered_map 用来剪枝。
q u e u e queue queue 用来实现 b f s bfs bfs
e r a s e + i n s e r t erase+insert erase+insert r e p l a c e replace replace都可以做。
输入时 a 1 , a 2 a1,a2 a1,a2字符串数组,正好一 一对应字符串。

#include <bits/stdc++.h>
using namespace std;
struct sa{
    
    
    string s;
    int step;
};
queue<sa> q;
string a,b,a1,b1,a2[8],b2[8];
unordered_map<string,int>m;
int n=1;
int main()
{
    
    
	cin>>a>>b;
    while(cin>>a2[n]>>b2[n]) n++;
    n--;
    q.push( (sa) {
    
    a,0});
    while(!q.empty())
    {
    
    
        sa tmp=q.front();
        string s=tmp.s;
        if(m[s]){
    
    
            q.pop();
            continue;
        }
        q.pop();
        int step=tmp.step;
        if(s==b && step<=10){
    
    
            cout<<step<<endl;
            return 0;
        }
        if(step>10){
    
    
            cout<<"NO ANSWER!"<<endl;
            return 0;
        }
        m[s]=1;
        for(int i=1;i<=n;i++){
    
    
            a1=a2[i];
            b1=b2[i];
            if(s.find(a1)==-1) continue;
            for(int j=s.find(a1);j<s.length()&&j!=-1 ;j=s.find(a1,j+1)){
    
    
                string s1=s;
                //s1.erase(s1.begin()+j,s1.begin()+j+a1.size());
                //s1.insert(j,b1);
                s1.replace(j,a1.size(),b1);
                q.push( (sa) {
    
    s1,step+1});
            }
        }
    }
    cout<<"NO ANSWER!"<<endl;
	return 0;
}

完结。

猜你喜欢

转载自blog.csdn.net/qq_45859188/article/details/108587847
今日推荐