知识梳理—-字符串
二. 字符串包含
题目描述: (此题是我2016年4月15腾讯实习生一面时的一道面试题)
给定两个字符串str1和str2,请尽可能快的判断str2中的字符是否全都在str1中出现.
实现的方法还是有蛮力轮询和带技巧的方法之分:
- 蛮力轮询:
对于str2中的每个字符串,都逐个与str1中的字符进行比较,查看是否包含在str1中.(时间复杂度O(mn))
#include <string>
#include <iostream>
using namespace std;
bool stringContain(string &str1, string &str2);
int main()
{
string str1 = "haha, just cool.";
string str2 = "cool";
string str3 = "gaga";
if(stringContain(str1, str2))
cout << "str2 in str1." << endl;
else
cout << "str2 not in str1." << endl;
if(stringContain(str1, str3))
cout << "str3 in str1." << endl;
else
cout << "str3 not in str1." << endl;
return 0;
}
bool stringContain(string &str1, string &str2)
{
for(int i = 0; i < str2.length(); i++)
{
int j;
for(j = 0; j < str1.length(); j++)
{
if(str2[i] == str1[j])
break;
}
if(j >= str1.length())
return false;
}
return true;
}
也可以在蛮力轮询时,先将两个字符串进行排序:
#include <algorithm>
bool stringContain(string &str1, string &str2)
{
sort(str1.begin(), str1.end());
sort(str2.begin(), str2.end());
for(int i = 0, j = 0; j < str2.length();)
{
while(i < str1.length() && str1[i] < str2[j])
i++;
if(i < str1.length() || str1[i] > str2[j])
return false;
j++;
}
return true;
}
2 .使用素数相乘:
让每个字符都对应一个素数,然后分别将str1和str2中的对应素数连乘得到num1和num2,然后用num1除以num2,若结果没有余数即为str1包含str2,否则不包含.(次方法的一个问题是,字符稍多就会产生连乘结果太大而溢出.)
素数相乘法,代码略......
3 .使用一个数组记录str1中每个字符的出现次数(ASCII字符有256个),操作方法是,定义一个长度为256的int型数组初始化为0,遍历str1,将下标为出现的字符的对应int值的元素值+1,然后遍历str2,查看数组对应下标元素的值,若有为0的情况则表示不包含,否则为包含.
bool stringContain(string &str1, string &str2)
{
int num[256] = {0};
for(int i = 0; i < str1.length(); i++)
{
num[int(str1[i])] += 1;
}
for(int j = 0; j < str2.length(); j++)
{
if(num[int(str2[j])] == 0)
return false;
}
return true;
}