字符串包含

说明:转载请注明出处

首先感谢各位大牛的想法和思路,参考了很多地方。

题目:

给定两个分别由字母组成的字符串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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值