C++string类型详解

字符串算法

回顾字符串基本操作


c风格的字符串
char str[]="aaabbbccc";
scanf("%s",str);
int len=strlen(str);
int size=sizeof(str);
cout<<str<<' '<<len<<' '<<size<<endl;

char str2[20];
strcpy(str2,str);
len=strlen(str2);
size=sizeof(str2);
cout<<str2<<' '<<len<<' '<<size<<endl;

strcat(str2,str);
len=strlen(str2);
size=sizeof(str2);
cout<<str2<<' '<<len<<' '<<size<<endl;

strcmp(str,str2);

c++风格的字符串

问题1:创建一个字符串,赋值为空,怎么写?

string s;//默认构造函数,初值为空
//构造函数
String(const char* str = "")
    :_str(nullptr)
        , _capacity(0)
    {
        _size = strlen(str);
        Reserve(_size);
        strcpy(_str, str);
    }

// 拷贝构造
String(const String& s)
    :_str(nullptr)
        , _size(0)
        , _capacity(0)
    {
        String tmp(s._str);
        Swap(tmp); // tmp.Swap(*this);
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
问题2:创建一个函数,参数为string[]类型s1,返回一个string字符串,为s1数组拼接结果

string f(string s[],int n){
    string ss;
	for(int i=0;i<n;i++){
        ss+=s[i];
    }
    return ss;
}

问题3:创建一个函数,参数为char[]类型str,返回一个string字符串,为str字符拼接结果

string f(char str[],int n){
    string ss;
    for(int i=0;i<n;i++){
        ss+=str[i];
    }
    //如果n是str的长度的话,可以这么写
    //string ss;
    //ss+=str;
    //
    //或者干脆直接 string ss=str;
    return ss;
}
string s;
char ch='A';
char str[]="666";
s+=ch;
s+=str;
s+=s;
cout<<s<<endl;

s+=99999999;
s+=999999999;
	String& operator+=(char ch){
		PushBack(ch);
		return *this;
	}

	// operator+= 操作符重载 ->字符串
	String& operator+=(const char* str){
		Append(str);
		return *this;
	}
	String operator+(char ch) const{
		String tmp(*this);
		tmp.PushBack(ch);
		return tmp;
	}

	//operator+运算符重载 -> 字符串
	String& operator+(const char* str){
		String tmp(*this);
		tmp.Append(str);
		return tmp;
	}

比较两个字符串相对大小

bool operator<(const String& s)const {
		size_t i = 0;
		size_t j = 0;
		while (i < _size && j < s._size){
			if (_str[i] < s[j]){
				return true;
			}
			else if (_str[i] > s[j]){
				return false;
			}
			else{
				++i;
				++j;
			}
		}
		if (j < s._size){	//左值字符串长度小于右值
			return true;
		}
		else{				//左值字符串长度大于右值
			return false;
		}
	}
	bool operator<=(const String& s)const {
		return *this < s || *this == s;
	}
	bool operator>(const String& s)const {
		return !(*this <= s);
	}
	bool operator>=(const String& s)const {
		return !(*this < s);
	}
	bool operator==(const String& s)const {
		size_t i = 0;
		size_t j = 0;
		while (i < _size && j < s._size){
			if (_str[i] != s[j]){
				return false;
			}
			else{
				++i;
				++j;
			}
		}

		if (i == _size && j == s._size){
			return true;
		}
		else{
			return false;
		}
	}
	bool operator!=(const String& s)const {
		return !(*this == s);
	}

string根本上来说,就是封装的字符串类!因为其方便,所以我们能用string来解决问题就不用char[]。

string s="000111";
s[3]='3';
s_str[3]

char& operator[](size_t pos){
		assert(pos < _size);	

		return _str[pos];
	}

	const char& operator[](size_t pos) const{
		assert(pos < _size);

		return _str[pos];
	}
private://成员变量
	char*  _str;
	size_t _size;
	size_t _capacity;

	static size_t npos;

底层源码见大神博客


真题

解码
#include<iostream>
#include<cstdio>
using namespace std;
int main(){	
	string s,res;
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		int k=s[i]-'0';
		if(k<=9&&k>1){
			for(int j=1;j<k;j++){
				res+=s[i-1];
			}
		}
		else{
			res+=s[i]; 
		}
	}
	cout<<res<<endl;
	return 0;
}
字符串对比
#include<iostream>
#include<cstdio>
using namespace std;
int ck(string s1,string s2){
    if(s1.size()!=s2.size()) return 1;
    int n=s1.size();
    bool flag=true;
    for(int i=0;i<n;i++){
        if(tolower(a[i])!=tolower(b[i])){//toupper()
            return 4;
        }
       	if(a[i]!=b[i]){
           flag=false;
        }
    }
    if(flag==false){
        return 3;
    }
    return 2;
}
int main(){
	string s1,s2;
	cin>>s1>>s2;
    cout<<ck(s1,s2)<<endl;
	return 0;
}

FJ的字符串
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
	string a="A",b;
	int n;
	cin>>n;
	for(int i=2;i<=n;i++){ 
		b='A'+i-1;
        b+=a;
        a+=b;
	}
	cout<<a<<endl;
	return 0; 
}
日期问题
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool ck(int y,int m,int d){
    if(y%4==0&&y%400!=0||y%100==0) month[2]=29;
    else month[2]=28;
    if(m>12||m<1) return false;
    if(d<1||d>month[m]) return false;
    return true;
}
string op(int x,int y,int z){
    if(x>=60) x+=1900;
    else x+=2000;
    
    string s;
    s+=(x/1000)+'0';
    x%=1000;
    s+=(x/100)+'0';
    x%=100;
    s+=(x/10)+'0';
    x%=10;
    s+=x+'0';
    s+='-';
    if(y<10) s+='0';
    else s+=y/10+'0',y%=10;
    s+=y+'0';
    s+='-';
    if(z<10) s+='0';
    else s+=z/10+'0',z%=10;
    s+=z+'0';
    
    return s;
}
int main(){
    int a[3];
    string s[6];
    int cnt=0;
    scanf("%d/%d/%d",a,a+1,a+2);
    // cout<<a[0]<<' '<<a[1]<<' '<<a[2]<<endl;
    // for(int i=0;i<3;i+=2){
    //     for(int j=0;j<3;j++){
    //         for(int k=0;k<3;k++){
    //             if(i!=j&&j!=k&&i!=k&&ck(a[i],a[j],a[k])){
    //                 s[cnt++]=op(a[i],a[j],a[k]);
    //             }
    //         }
    //     }
    // }
    if(ck(a[0],a[1],a[2])) s[cnt++]=op(a[0],a[1],a[2]);
    if(ck(a[2],a[1],a[0])) s[cnt++]=op(a[2],a[1],a[0]);
    if(ck(a[2],a[0],a[1])) s[cnt++]=op(a[2],a[0],a[1]);
    sort(s,s+cnt);
    for(int i=0;i<cnt;i++)
        if(i==0||s[i]!=s[i-1]){
            cout<<s[i]<<endl;
        }
    return 0;
}

有用的string函数

getline
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    string s;
    getline(cin,s);
    cout<<s[0];
    for(int i=1;i<s.size();i++){
        cout<<' '<<s[i];
    }
    return 0;
}
insert
#include<iostream>
#include<cstdio>
using namespace std;
int locate(string s){
    int idx=0;
    for(int i=1;i<s.size();i++){
        if(s[i]>s[idx]){
            idx=i;
        }
    }
    return idx;
}
int main(){
    string s1,s2;
    while(cin>>s1>>s2){
        int k=locate(s1);
        s1.insert(k+1,s2);
        cout<<s1<<endl;
    }
    // string s1="01234",s2="sss";
    // s1.insert(0,s2);
    // cout<<s1<<endl;
    return 0;
}
find
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    string s1,s2;
    cin>>s1>>s2;
    string ss1=s1;
    ss1+=s1;
    string ss2=s2;
    ss2+=s2;
    if(ss1.find(s2)!=-1||ss2.find(s1)!=-1){//find是从左往右找,findr是从右往左找
        cout<<"true"<<endl;
    }
    else cout<<"false"<<endl;
    return 0;
}

字符串函数

字符串哈希

从问题入手:回文子串的最大长度

#include<iostream>
#include<cstdio>
using namespace std;
typedef unsigned long long ull;
const int N=100010,P=131;
char str[N];
ull a[N],p[N];
int n;
ull get(int l,int r){return a[r]-a[l-1]*p[r-l+1];}
int main(){
    int m;
    scanf("%d%d%s",&n,&m,str+1);
    p[0]=1;
    for(int i=1;i<=n;i++){
        p[i]=p[i-1]*P;
        a[i]=a[i-1]*P+str[i];
    }
    int l1,r1,l2,r2;
    while(m--){
        cin>>l1>>r1>>l2>>r2;
        if(get(l1,r1)==get(l2,r2)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}


/*
RE的string
#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    int n,m;
    cin>>n>>m>>str;
    int l1,r1,l2,r2;
    while(m--){
        cin>>l1>>r1>>l2>>r2;
        if(str.substr(l1-1,r1-l1)==str.substr(l2-1,r2-l2)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}
*/
kmp字符串匹配算法

从问题入手:剪花布条

#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010,M=1000010;
char ss[N],s[M];
int ne[N];
int n,m;
int main(){
    scanf("%d%s%d%s",&n,ss+1,&m,s+1);
    for(int i=2,j=0;i<=n;i++){
        while(j&&ss[i]!=ss[j+1]) j=ne[j];
        if(ss[i]==ss[j+1]) j++;
        ne[i]=j;
    }
    for(int i=1,j=0;i<=m;i++){
        while(j&&s[i]!=ss[j+1]) j=ne[j];
        if(s[i]==ss[j+1]) j++;
        if(j==n){
            cout<<i-n<<' ';
        }
    }
    return 0;
}
大数加减乘除算法

从问题入手:黄金连分数

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
using namespace std;
vector<int> add(vector<int>&A,vector<int>&B){
    if(A.size()<B.size()) return add(B,A);
    vector<int>C;
    int t=0;
    for(int i=0;i<A.size();i++){
        t+=A[i];
        if(i<B.size()) t+=B[i];
        C.push_back(t%10);
        t/=10;
    }
    if(t) C.push_back(t);
    return C;
}
int main(){
    string a,b;
    cin>>a>>b;
    vector<int>A,B;
    for(int i=a.size()-1;~i;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;~i;i--) B.push_back(b[i]-'0');
    auto C=add(A,B);
    for(int i=C.size()-1;~i;i--) cout<<C[i];
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值