zoukankan      html  css  js  c++  java
  • 字符串的包含

    问题描述: 给定一个长字符串a和一个短字符串b。请问,如何最快地判断出短字符串b中的所有字符都在长字符串a中?请编写函数bool StringContain(string &a, string &b)实现此功能。为简单起见,假设输入的字符串只包含大写英文字母。

    下面举几个例子:

    (1)如果字符串a是"ABCD",字符串b是"BAD",答案是true,因为字符串b中的字母都在字符串a中,或者说b是a的真子集。

    (2)如果字符串a是"ABCD",字符串b是"BCE",答案是false,因为字符串b中的字母E不在字符串a中。

    (3)如果字符串a是"ABCD",字符串b是"AA",答案是true,因为字符串b中的字母A包含在字符串a中。

    解题思路:

    1.最直接的办法,蛮力轮询。对于这种方法,如果长字符串a的长度为n,短字符串b的长度为m,那么此算法需要比较次数为O(n*m)。显然该方法时间开销很大。

    2.排序后轮询,根据题目只包括大写的英文字母,对两个字符串分别进行排序需要操作:O(mlogm)+O(nlogn),之后进行线性扫描需要O(n+m)

    参考代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    bool StringContain( string &a , string &b )
    {
        sort( a.begin() , a.end() );
        sort( b.begin() , b.end() );
        int lena = a.length();
        int lenb = b.length();
        for(int pa = 0 , pb = 0 ; pb < lenb ; )
        {
            while((pa < lena) && (a[pa] < b[pb]))
            {
                ++pa;
            }
            if((pa >= lena) || (a[pa] > b[pb]))
            {
                return false;
            }
            ++pb;
        }
        return true;
    }
    int main()
    {
        string a  = "ABCD";
        string b[3];
        b[0] = "BAD";
        b[1] = "BCE";
        b[2] = "AA";
        for(int i=0;i<3;i++)
        {
            if(StringContain(a,b[i]))
                cout<<a<<"  contains  "<<b[i]<<endl;
            else
                cout<<a<<"  don't contain  "<<b[i]<<endl;
        }
        return 0;
    }

    GCC运行结果:

    3.位运算法。

    将长字符串a的所有字符都存放在一个散列表(hash table)中,然后轮询短字符串b,看b中的每一个字符是否都在散列表中,若果都在则返回true,否则返回false

    可以用位运算(26位整数表示)给相应的长字符串a就算出一个相对应的"签名",然后将字符串b的每一个字符都放在a中进行查找。

    参考代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    bool StringContain( string &a , string &b )
    {
        int hash = 0;
        int lena = a.length();
        int lenb = b.length();
        for( int i = 0 ; i < lena ; i++)
        {
            hash |= (1 << (a[i] - 'A'));
        }
        for(int i = 0; i < lenb ; i++)
        {
            if( ( hash & ( 1 << ( b[i] - 'A' ) ) ) == 0)
                return false;
        }
        return true;
    }
    int main()
    {
        string a  = "ABCD";
        string b[3];
        b[0] = "BAD";
        b[1] = "BCE";
        b[2] = "AA";
        for(int i=0;i<3;i++)
        {
            if(StringContain(a,b[i]))
                cout<<a<<"  contains  "<<b[i]<<endl;
            else
                cout<<a<<"  don't contain  "<<b[i]<<endl;
        }
        return 0;
    }

    GCC运行结果:

    该算法的空间复杂度为O(1),时间复杂度为O(n+m)。

  • 相关阅读:
    第一篇
    面试题
    CSS样式
    html初步学习
    web开发项目连接访问数据库
    oracle数据库操作之连接
    oracle数据库的基本操作(create创建表,update更新表,drop删除表,select查询表,insert插入数据)
    用js在前台界面进行账户密码的检测,账户和密码符合要求后可进行登录
    用servlet代替js对登录进行检测
    JSP转发和重定向的区别,以及如何获取数据
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5334076.html
Copyright © 2011-2022 走看看