字符串包括

字符串包括

题目:如果这有一个各种字母组成的字符串A,和另外一个字符串B,字符串里B的字母数相对少一些。什么方法能最快的查出全部小字符串B 里的字母在大字符串A里都有?

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

a是长字符串,b是短字符串

方法一:双循环比較法(轮询法)

针对b中的每个字符。逐个与a中每个字符比較

伪代码:

bool StringContain(string &a, string &b)
{
    for(int i = 0; i < b.length(); i++)
    {
        for(int j = 0; (j < a.length()) && (a[j] != b[i]); j++);
        if(j >= a.length())
        {
            return false;
        }
    }
    return true;
}

复杂度:O(n*m)时间开销过大

方法二、排序+轮询法

先对两个字符串的字母进行排序。之后同一时候对两个字符串依次线性扫描轮询

伪代码:

//注意AB中可能包括反复字符,所以注意A下标不要轻易移动,这样的方法改变了字符串,假设不想改变能够选择复制bool StringContain(string &a, string &b)
{
    sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    for(int pa = 0, pb = 0; pb < b.length();)
    {
        while((pa < a.length()) && (a[pa] < b[pb]))
            ++pa;
        if((pa >= a.length()) || (a[pa] > b[pb]))
            return false;
        ++pb;
    }
    return true;
}

注意:这里攻克了一个假设存在同样字符问题,一定要注意不能直接i++。j++,字符类题目一定要注意考虑字符同样的情况。该算法的复杂度为O(mlogm) + O(nlogn) + O(m+n)

方法三:数组存储法

首先标记短字符串中有哪些字符,则在store数组中标记为true,store数组事实上就是起到一个映射的作用;之后遍历长字符串。假设为true的则辩称false,否则不处理;最后遍历store数组,假设所有元素都是false那么说明短字符串中元素长字符串中所有有。否则没有。

伪代码:

bool store[maxn];
memset(store, false, 58);
for(i = 0; i < len1; i++)
{
    store[short[i] - 65] = true;
}

for(i = 0; i < len2; i++)
{
    if(store[long[i] - 65] != false)
        store[long[i] - 65] = false;
}

for(i = 0; i < maxn; i++)
{
    if(store[i] != false)
    {
        短字符中有长字符中没有的字符;
        break;
    }
    if(i == len2-1)//事实上也能够通过return来完毕
    {
        短字符中没有长字符中没有的字符;
    }
}

复杂度为O(m+n)

方法四:O(n)到O(m+n)的素数方法

思路:

① 定义最小的26 个素数分别与字符‘A‘到‘Z‘相应。

② 遍历长字符串,求得每一个字符相应素数的乘积。

③ 遍历短字符串,推断乘积是否能被短字符串中的字符相应的素数整除。

伪代码:

//这种方法仅仅有理论意义,因此整数乘积非常大,有溢出风险bool StringContain(string &a, string &b)
{
    const int primeNumber[26] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97,101};
    int product = 1;

    //遍历长字符串
    for(int i = 0; i < a.length(); i++)
    {
        int index = a[i] - ‘A‘;
        product *= primeNumber[index];
    }

    //遍历短字符串
    for(int j = 0; j < b.length(); j++)
    {
        int index = b[j] - ‘A‘;
        if(product % primeNumber[index] != 0)
            return false;
    }
    return true;
}

纸质手写代码易犯错误:

① 91不是素数

② product初始化为1,不是0

待改进地方

这个程序尽管非常巧妙。运用数学知识减少了时间复杂度

1.仅仅考虑大写字符,假设考虑小写字符和数组的话,素数数组须要很多其它素数

2.没有考虑反复的字符,能够增加推断反复字符的辅助数组。

方法五、哈希表

思路1:将短的字符串存储在哈希表hashTable中,对于字符串中字符为1,而且用num统计1的个数cnt之后再扫描长字符串的每一个字符。若原来hashTable[*pHashKey]为1时。我们改动为0。且将cnt减去1,否则不处理;若cnt == 0或者扫描结束,循环结束;

伪代码:

bool  is_contain(string LongStr, string ShortStr)
{
    bool is_pipei = false;
    const  int tableSize = 256;
    unsigned int hashTable[tableSize];
    int i,cnt = 0;

    for(i = 0; i < tableSize; i++)
    {
        hashTable[i] = 0;
    }

    for(i = 0; i < ShortStr.length(); i++)
    {
        hashTable[i] = 1;
        cnt ++;
    }

    for(i = 0; i < LongStr.length(); i++)
    {
        if(hashTable[LongStr[i]] == 1)
        {
            hashTable[LongStr[i]] = 0;
            cnt --;
        }
    }
    if(cnt == 0)
    {
        is_pipei = true;
    }
    return is_pipei;
}

思路2:事实上能够依据存储长的字符串,对于哈希表值为1,之后再去扫描短字符串中的每一个字符。假设存在哈希表值为0。则说明短字符中存在长字符中不含有的字符。反之不存在。

伪代码:

bool is_contain(char *src, char *des)
{
    bool is_pipei = true; //创建一个哈希表,并初始化
    const int tableSize = 256;
    int hashTable[tableSize];
    int len1,len2,i;
    for(i=0; i< tableSize; i++)
        hashTable[i] = 0; 

    len1 = strlen(src);
    for(i=0; i< len1; i++)
        hashTable[src[i]] = 1;
    len2 = strlen(des);
    for(i=0; i< len2; i++)
        {
            if(hashTable[des[i]] == 0)
                is_pipei = false; //匹配失败
        } 

        return is_pipei; //匹配成功
}

思路3、先轮询长字符串,用位运算计算出一个”签名“,再用短字符串中字符去长字符串中去查找

//最好的方法。时间复杂度O(n+m) 空间复杂度为O(1)bool StringContain(string &a, string &b)
{
    int hash = 0;
    for(int i = 0; i < a.length(); ++i)
    {
        hash |= (1 << (a[i] - ‘A‘));
    }
    for(int i = 0; i < b.length(); ++i)
    {
        if((hash & (1 << (b[i] - ‘A‘))) == 0)
            return false;
    }
    return true;
}

这样的方法实质上是用整数替代了哈希表。时间复杂度O(n+m) 空间复杂度为O(1)

最优质的算法

时间: 2024-10-09 19:45:41

字符串包括的相关文章

JavaScript基础 Date(日期字符串 包括时分秒)

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut

【字符串处理算法】字符串包括的算法设计及C代码实现

一.需求描写叙述 给定一个长字符串和一个短字符串.编敲代码推断短字符串中的全部字符是否都在长字符串中.假设是,则长字符串包括短字符串:反之,不包括. 为了尽量包括大多数情况,字符串中能够包括大写和小写英文字母.数字和各种标点符号.而且区分大写和小写字母. 以下举几个样例予以说明: 1.假设长字符串是"ABCDE",短字符串是"ADC",那么短字符串中的全部字符都在长字符串中.即长字符串包括了短字符串. 2.假设长字符串是"ABCDE",短字符串是

奔五的人学ios:swift竟然没有字符串包括,找个简单的解决方法

swift关于字符串的推断中 有前导.有后缀 两个方法.竟然没有包括推断. 经过学习找了个简单的解决方法: extension String { func has(v:String)->Bool { return self.componentsSeparatedByString(v).count > 1 } }

js获取(包括中文)字符串长度与截取字符串

/** * @param begin 截取开始的索引 * @param num 截取的长度 */ //截取字符串(包括中文) function SetString(str, len) { var strlen = 0; var s = ""; for (var i = 0; i < str.length; i++) { var m = str.charAt(i).match(/[^\x00-\x80]/g);//利用match方法检索出中文字符并返回一个存放中文的数 if (m!

剑指offer之【把字符串转换成整数】

题目: 把字符串转换成整数 链接: https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&tqId=11202&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一个合法的数值则返回0

python内置的一个好玩的函数-zip,并且巧妙的实现按概率随机生成有限个数的字符串。

python有一个比较有意思的内置函数-----zip,可以把传入的两组list进行一个组合变形,再输出子元素为tuple的list,不过变形的方式比较抽象. 举个例子: A=[1,2,3,4,5,6] B=['a','b','c','d'] v1=zip(A,B) v1的结果为: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')] 比较直观的理解就是,A和B是两道拉链上的扣子,生成的list的子tuple,每一组tuple就是一对扣好了的扣子,并且从每组list的

C++用%20替换字符串中的空格(O(n)的时间效率)

#include <iostream> #include <malloc.h> #include <string.h> using namespace std; //将字符串中的空格用%20替换. void Grial(char *str) { if(str==NULL)return ; char *p = str; char *q = NULL; char buf[strlen(str)+1]; int count = 0;//计数空格数. while(*p!='\0

DB2数据库中DB2字符串类型

DB2字符串是DB2数据库中的基础知识,下面就为您分类介绍DB2字符串,供您参考,如果您对DB2字符串方面刚兴趣的话,不妨一看. DB2字符串是字节序列.DB2字符串包括 CHAR(n) 类型的定长字符串和 VARCHAR(n).LONG VARCHAR 或 CLOB(n) 类型的变长字符串.字符串的长度就是序列中的字节数. *定长字符串,CHARACTER(n) 或 CHAR(n):定长字符串的长度介于 1 到 254 字节之间.如果没有指定长度,那么就认为是 1 个字节. *变长字符串,VA

字符串逆转-压缩连续空格

一.算法描述 给定一个字符串,对于字符串包括多个连续空格的情况,压缩并只保留一个空格,同时以空格隔离的子串逆转. 二.算法思路 其本质是字符串逆转的变体,即在字符串逆转的基础上,还要压缩多余空格,这种情况相比单纯的字符串逆转多了一步判断连续空格的条件 如下代码中,包括单纯的字符串逆转函数,实现比较简单,主要是注意下标的位置 三.算法代码 #include <iostream> #include <string.h> #include <stdio.h> #include