题目描述:
有两个字符串一个长字符串str1,一个短字符串str2,查找第二个字符串的所有字符是否第一个字符串里面都包含。
例如:
str1:ASDFGHJKL
str2:ADFGH
查找,第二个字符串里的字符都包含在第一个字符串里,结果为true。
这个题目有好多种解法
- 第一种:O(m*n)暴力破解法
针对第二个短字符串在第一个字符串里是否包含
代码如下:
#include<iostream>
#include<string>
using namespace std;
int compare( string str1,string str2)//暴力循环破解的方法
{
int i, j;
for (i = 0; i < str2.length(); i++)
{
for (j = 0; j < str1.length(); j++)
{
if (str1[j] == str2[i])
{
break;
}
}
if (j == str1.length())
{
cout << "false"<<endl;
return 0;
}
}
cout << "true" << endl;
return 1;
}
int main()
{
string str1 = "ASDFGHJKL";
string str2 = "ADFGHJ";
compare(str1, str2);
system("pause");
return 0;
}
- 第二种: O(m+n)HashTable的方法
可以根据哈希的思想,建立一个长度为26的数组,初始化为0,先把第二个短字符串每个字符对应放入数组,当数组相应位置为0时,把该位置置为1然后定义一个计数器,给计数器++当第二个字符串遍历完后,开始遍历第一个字符串当相应位置为1,计数器–;当长字符串遍历完后计数器为0 时,证明包含,当计数器不为0时证明不包含。
代码如下:
#include<iostream>
#include<string>
using namespace std;
int compare(string str1,string str2)//哈希的方法
{
int hash[26] = { 0 };
int num = 0;
for (int j = 0; j < str2.length(); j++)
{
int index = str2[j] - 'A';
if (hash[index] == 0)
{
hash[index] = 1;
num++;
}
}
for (int i = 0; i < str1.length(); i++)
{
int index = str1[i] - 'A';//求该字符应该对应数组中的位置
if (hash[index] == 1)
{
hash[index] = 0;
num--;
if (num == 0)
{
break;
}
}
}
if (num == 0)
{
cout << "true" << endl;
return 0;
}
else
{
cout << "false" << endl;
return -1;
}
}
int main()
{
string str1 = "ASDFGHJKL";
string str2 = "ADFGHJ";
compare(str1, str2);
system("pause");
return 0;
}
第三种:O(m+n)素数的方法
方法来源你可能会这么想:O(n+m)是你能得到的最好的结果了,至少要对每个字母至少访问一次才能完成这项操作,而上一节最后的俩个方案是刚好是对每个字母只访问一次。
假设我们有一个一定个数的字母组成字串,我给每个字母分配一个素数,从2开始,往后类推。这样A将会是2,B将会是3,C将会是5,等等。现在我遍历第一个字串,把每个字母代表的素数相乘。你最终会得到一个很大的整数,对吧?
然后——轮询第二个字符串,用每个字母除它。如果除的结果有余数,这说明有不匹配的字母。如果整个过程中没有余数,你应该知道它是第一个字串恰好的子集了。
1.#include <iostream>
2.#include <string>
3.#include "BigInt.h"
4.using namespace std;
5.
6.// 素数数组
7.int primeNumber[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
8. 61, 67, 71, 73, 79, 83, 89, 97, 101};
9.
10.int main()
11.{
12. string strOne = "ABCDEFGHLMNOPQRS";
13. string strTwo = "DCGSRQPOM";
14.
15. // 这里需要用到大整数
16. CBigInt product = 1; //大整数除法的代码
17.
18. // 遍历长字符串,得到每个字符对应素数的乘积
19. for (int i = 0; i < strOne.length(); i++)
20. {
21. int index = strOne[i] - 'A';
22. product = product * primeNumber[index];
23. }
24.
25. // 遍历短字符串
26. for (int j = 0; j < strTwo.length(); j++)
27. {
28. int index = strTwo[j] - 'A';
29.
30. // 如果余数不为0,说明不包括短字串中的字符,跳出循环
31. if (product % primeNumber[index] != 0)
32. break;
33. }
34.
35. // 如果积能整除短字符串中所有字符则输出"true",否则输出"false"。
36. if (strTwo.length() == j)
37. cout << "true" << endl;
38. else
39. cout << "false" << endl;
40. return 0;
41.}