问题描述:
来自: http://blog.csdn.net/v_JULY_v/article/details/6347454
假设这有一个各种字母组成的字符串A,和另外一个字符串B,字符串里B的字母数相对少一些。什么方法能最快的查出所有小字符串B里的字母在大字符串A里都有?
比如,如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPO
答案是true,所有在string2里的字母string1也都有。
如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPZ
答案是false,因为第二个字符串里的Z字母不在第一个字符串里。
注: 上面链接有关于这个问题的详细解法。
下面是我关于这个问题的思路:
该问题题意很明确了,就是提供两个由字母组成的字符串序列A和B,A中有N个字母,B中有M个,对于B中的每一个字母,看是不是在A中都有出现。如果是,返回true;否则返回false。
解法有很多,首先考虑暴力遍历,对于B中的每一个字母,都在A中查找,若都找到,true,否则false,时间复杂度:O(N*M);
上面的解法在数据量很小的情况下是没有问题的,但数据量很大就不行了,可以考虑优化一下。可以先对每一个序列排一下序,用快排,时间为O(N*lgN),O(M*lgM),综合一下为O(N*lgN),然后去重,时间为O(N),然后就可以让两个排好序的数组进行比较,时间复杂度为O(N),所以这个解法的综合时间复杂度为O(N*lgN);
尽管时间已经优化到了O(N*lgN),但还有没有更好的方式?答案是有的,我们可以换个思路,因为这个问题里面比较的是单个字符,而总共就有26个字母,所以可以使用hash的思想,建一个数组bool hash[26],从hash[0]--hash[25]分别代表A--Z,遍历字符串A,A存在的字符就置其对应的hash[ ]为true,不存在的置为false,然后遍历B串,看B串中每个字母对应的hash[]值即可。如遇到false,则直接返回false,否则true。
代码;
/*
* 1 c++,编译器Code::Blocks 12.11
* 2 时间复杂度:O(N)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int i,j;
bool hash[26];
memset(hash,false,sizeof(hash));
string a,b;
cin>>a>>b;
for( i=0; a[i]!='\0'; i++)
if(!hash[a[i]-'A'])
hash[a[i]-'A']=true;
for( j=0; b[j]!='\0'; j++)
if(!hash[b[j]-'A'])
{
//如果b串含有A串中没有的字母,打印false
cout<<"false"<<endl;
break;
}
if(b[j]=='\0')//成功打印true
cout<<"true"<<endl;
return 0;
}