说明:转载请注明出处
首先感谢各位大牛的想法和思路,参考了很多地方。
题目:
给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短。请问,如何最快地判断字符串B中所有字母是否都在字符串A里?
为了简单起见,我们规定输入的字符串只包含大写英文字母,请实现函数bool StringContains(string &A, string &B)
比如,如果是下面两个字符串:
String 1:ABCD
String 2:BAD
答案是true,即String2里的字母在String1里也都有,或者说String2是String1的真子集。
如果是下面两个字符串:
String 1:ABCD
String 2:BCE
答案是false,因为字符串String2里的E字母不在字符串String1里。
同时,如果string1:ABCD,string 2:AA,同样返回true。
思路一:暴力求解,从String2遍历去String1找,如果都满足则为true,否则为false。方法直接,时间复杂度比较高为O(n*m),其中n为String1的长度,m为String2的长度。
思路二:想要降低复杂度,当然考虑排序,按照快速排序后,进行比较。其中排序时间复杂度为O(nlog(n)+mlog(m)),比较时间为O(n+m)。
代码如下:
#include <stdio.h>
#include <stdlib.h>
/*快速排序一次交换,返回索引*/
int partition(char *s, int low, int high)
{
char tmp = s[low]; /*用第一个记录作为判断枢纽*/
while (low < high)
{
/*比枢纽小的值移动到低端*/
while (low<high && s[high]>=tmp)
{
high--;
}
/*将找到的值给低端*/
s[low] = s[high];
/*比枢纽大的值移动到高端*/
while (low<high && s[low]<=tmp)
{
low++;
}
/*将找到的值给高端*/
s[high] = s[low];
}
/*将开始的枢纽值保存,完成一次交换*/
s[low] = tmp;
return low;
}
/*快速排序*/
void qSort(char *s, int low, int high)
{
if (low < high)
{
int mid = partition(s, low, high);
qSort(s, low, mid-1);
qSort(s, mid+1, high);
}
}
/*查看S是否包含T字符串*/
bool stringContain(char *S, char *T)
{
int i;
int j;
qSort(S, 0, strlen(S)-1);
qSort(T, 0, strlen(T)-1);
for (i=0, j=0; *(S+i)!='\0'&&*(T+j)!='\0';)
{
if (*(S+i) == *(T+j))
{
j++;/*此处不要i++,如果T含多次同一个字符*/
}
else if(*(S+i) < *(T+j))
{
i++;
}
else
{
return false;
}
}
return (*(T+j)=='\0');
}
int main()
{
char s[] = "ABCD";
char t[] = "AABD";
if (stringContain(s, t))
{
printf("TRUE\n");
}
else
{
printf("FALSE\n");
}
return 0;
}
思路三:既然要求全部大写,采用HASH方式。将字符对应int的bit位按照位比较即可。时间复杂度为O(n+m)。
代码如下:
#include <stdio.h>
#include <stdlib.h>
/*采用HASH方式,其实质还是置bit位
按照题目要求全部大写,则需要26bit位
一个int位32bit满足题意,故按照此方式即可
也可以直接用byte数组赋值也很方便*/
bool stringContain(char *S, char *T)
{
int hash = 0;
int i = 0;
int j = 0;
while (*(S+i) != '\0')
{
hash |= 1<<(*(S+i)-'A'); /*按照bit位放置到int里面*/
i++;
}
while (*(T+j) != '\0')
{
if ((hash&(1<<(*(T+j)-'A'))) == 0) /*按位比较*/
{
return false;
}
j++;
}
return true;
}
int main()
{
char s[] = "ABCD";
char t[] = "AAE";
if (stringContain(s, t))
{
printf("TRUE\n");
}
else
{
printf("FALSE\n");
}
return 0;
}