字符串的包含

题目:

   给定一个长字符串a,和一个短字符串b,如何最快的判断出短字符串b中的所有字符是否都在长字符串a中?

方法一:暴力轮询。

方法二:先排序后再轮询。

代码:

#include <bits/stdc++.h>
using namespace std;
bool StringContain(string &a,string &b){
	sort(a.begin(),a.end());
	sort(b.begin(),b.end());
	int pa=0,pb=0;
	while(pb < b.length()){
		//直到找到a[pa] == a[pb],否自pa一直前移 
		while((pa < a.length()) && (a[pa] < a[pb])){
			++pa;
		}
		//判出,pa越界 或 找到了后面的大于a[pa]的值,证明不满足条件 
		if((pa >= a.length()) || (a[pa] > a[pb])){
			return false;
		}
		++pb;
	}
	return true;
}
int main(){
	string s1="abcd";
	string s2="bcd";
	if(StringContain(s1,s2)){
		cout<<"yes"<<endl;
	}else{
		cout<<"no"<<endl;
	}
	return 0;
} 

方法三:素数相乘

这是一种解答思路:将26个字符中的每个字符和一个素数相对应,然后算出长字符串a中字符对应的素数的积pro;

然后做 pro / 短字符串b中每个字符对应的素数,如果有余数说明1,个数不达标,2,a中没有出现该字符

注:因为字符串可能很长,所以有可能会溢出,短的可以长的不行。

#include <bits/stdc++.h>
using namespace std;
bool StringContain2(string &a,string &b){
	const int pri[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,
	                   53,59,61,71,73,79,83,89,97,101};
	int pro=1;//a的素数的积 
	for(int i=0;i<a.length();++i){
		int x=pri[a[i] - 'a'];//对应的素数 
		if(pro % x){//省去个数 
			pro*=x;
		}
	}
	for(int j=0;j<b.length();++j){
		int y=pri[b[j]-'a'];
		if(pro % y){
			return false;
		}
	}
	return true;                   
}
int main(){
	string s1="abcd";
	string s2="bcd";
	if(StringContain2(s1,s2)){
		cout<<"yes"<<endl;
	}else{
		cout<<"no"<<endl;
	}
	return 0;
} 

 

方法四:位运算法

更简单的方法是将a中的字符放入散列表中,然后再轮询比较b中的字符,这里可以用位运算为a算出一个 定值 

然后再将b中的字符逐一放到a中去查找。

#include <bits/stdc++.h>
using namespace std;

//实质是用一个整数代替了散列表 
bool StringContain3(string &a,string &b){
	int hash=0;
	for(int i=0;i<a.length();++i){
		hash |= (1<<(a[i]-'a'));
	}
	for(int i=0;i<b.length();++i){
		if((hash & (1<<(b[i]-'a')))==0){
			return false;
		}
	}
	return true;
}
int main(){
	string s1="abcd";
	string s2="bcd";
	if(StringContain3(s1,s2)){
		cout<<"yes"<<endl;
	}else{
		cout<<"no"<<endl;
	}
	return 0;
} 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值