字符串的包含

问题描述: 给定一个长字符串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)。

时间: 2024-10-05 11:50:38

字符串的包含的相关文章

Openjudge-NOI题库-字符串移位包含问题

题目描述 Description 对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串. 给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串.例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串. 输入输出格式 Input/output 输入: 一行,包含两个字符串,中间由单个空格隔开.字符串只包含字母和数字,长度不超过30. 输

编程之美之字符串移位包含问题

[题目] 给定两个字符串s1和s2,要求判断s2是否能够被通过s1做循环移位(rotate)得到的字符串包含.例如,S1=AABCD和s2=CDAA,返回true:给定s1=ABCD和s2=ACBD,返回false. [分析] [思路一] 从题目中可以看出,我们可以使用最直接的方法对S1进行循环移动,再进行字符串包含的判断,从而遍历其所有的可能性. 字符串循环移动,时间复杂度为O(n),字符串包含判断,采用普通的方法,时间复杂度为O(n*m),总体复杂度为O(n*n*m). 字符串包含判断,若采

CareerCup之1.8 字符串移位包含问题

[题目] 原文: 1.8 Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring ( i.e., "waterbottle" is a rotat

mysql 检查字符串是否包含子串

1.使用substring_index(src,target,index) 从src的开头查找第index个target.返回的substring为从src的开头到第num个target这段字符串.比如 substring_index('absscdessfss','ss',1) 返回ab substring_index('absscdessfss','ss',2) 返回absscde substring_index('absscdessfss','tt',1) 返回absscdessfss 因

php如何判断一个字符串是否包含另一个字符串

来自1:http://blog.sina.com.cn/s/blog_8edc37a801016yha.html -------------------------------------------------------------------- 我觉得最简单的就是:(用这种最好,StrPos效率最高) strpos($a, $b) !== false 如果$a 中存在 $b,则为 true ,否则为 false. 用 !== false (或者 === false) 的原因是如果 $b 正

php 判断字符串是否包含中文

正则表达式: /[\x7f-\xff]/ 如: var_dump(preg_match("/[\x7f-\xff]/",'Hello 你好')); 那么它会返回true,因为字符串中包含中文

第3章 结构之法——字符串移位包含的问题

字符串移位包含的问题 问题描述 分析与解法 [解法一] 具体代码如下: 1 package chapter3jiegouzhifa.QuestionOfStringMove; 2 /** 3 * 字符串移位包含的问题 4 * [解法一] 5 * @author DELL 6 * 7 */ 8 public class StringMove { 9 /** 10 * 寻找移位后的字串(左移) 11 * @param src 源字符串 12 * @param des 要查找的子串 13 * @ret

String的两个API,判断指定字符串是否包含另一字符串,在字符串中删除指定字符串。

// 在字符串中删除指定字符串. String phoneNum="1795112345"; phoneNum = phoneNum.replace("17951", ""); System.out.println(phoneNum); //判断指定字符串是否包含另一字符串 String phoneNum="1795112345"; String IpNum="17951"; return phoneNum

判断字符串是否包含其他字符串

//判断两字符串是否相等- (BOOL)isEqualToString:(NSString *)aString; //判断开头是否包含该字符串- (BOOL)hasPrefix:(NSString *)aString; //判断结尾是否包含该字符串- (BOOL)hasSuffix:(NSString *)aString; //该字符串在那个位置- (NSRange)rangeOfString:(NSString *)aString; 判断字符串是否包含其他字符串,布布扣,bubuko.com

字符串是否包含问题

题目描述 假设这有两个分别由字母组成的字符串A另外字符串B,字符串B的字母数较字符串A少一些.什么方法能最快地查出字符串B所有字母是不是都在字符串A里?也就是说判断字符串B是不是字符串A的真子集(为了简化,姑且认为两个集合都不是空集,即字符串都不为空.). 分析与解法 解法一:暴力轮询 就是将B中的每一字符都和A中的字符做对比,思想简单此处就不再实现 解法二:普通排序 就是先对A 和 B做排序,然后对比B和A /** * <p> * 普通排序的方式 * </p> * @author