题目:给定一长字符串a和一短字符串b。请问,如何最快地判断出短字符串b中的所有字符是否都在长字符串a中?(假设输入的字符串只包含大写英文字母)
解法一:蛮力轮询
解题思路:(1) 首先轮询短字符串中的每一个字符,并逐个与长字符中的每个字符进行比较,判断是否都在长字符串中。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool str_contain(string &str1,string &str2)
{
for(int i=0;i<str2.length();++i)
{
int j;
for(j=0;j<str1.length()&&(str1[j]!=str2[i]);++j)
;
if(j>str2.length())
{
return false;
}
}
return true;
}
int main()
{
string a="abcde";
string b="f";
bool c=str_contain(a,b);
cout<<c<<endl;
return 0;
}
假设长字符串长度为n;短字符串长度为m;
时间复杂度为:O(nm)
解法二:先排序后轮询
解题思路:(1)先对两个字符串中的元素进行排序。(2)在对两个字符串依次进行轮询比较
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool str_contain(string &str1,string &str2)
{
sort(str1.begin(),str1.end());
sort(str2.begin(),str2.end());
for(int s_str1=0, s_str2=0;s_str2<str2.length();)
{
while((s_str1<str1.length()) && (str1[s_str1]<str2[s_str2]))
{
++s_str1;
}
if((s_str1>str1.length())||(str1[s_str1]>str2[s_str2]))
{
return false;
}
++s_str2;
}
return true;
}
int main()
{
string str1="bfdesg";
string str2="ed";
sort(str1.begin(),str1.end());
sort(str2.begin(),str2.end());
cout<<str1<<endl;
cout<<str2<<endl;
bool str=str_contain(str1,str2);
cout<<str<<endl;
return 0;
}
解法三:位运算法
首先(1)将长字符串中的所有字符存入一个散列表中,(2)再轮询短字符串字符,判断短字符串中的每个字符是否都在散列表中
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool str_contain(string &str1,string &str2)
{
int hash=0;
for(int i=0;i<str1.length();++i)
{
hash |= (1<<(str1[i]-'A'));
}
for(int j=0;j<str2.length();++j)
{
if(hash & (1<<(str2[j]-'A'))==0)
{
return false;
}
}
return true;
}
int main()
{
string str1="degae";
string str2="d";
cout<<str1<<endl;
cout<<str2<<endl;
bool str=str_contain(str1,str2);
cout<<str<<endl;
return 0;
}
则空间复杂度为O(1) ,时间复杂度为O(n+m)