【程序员编程艺术】学习记录3:字符串包含问题
来源:互联网 发布:数据分析范例 编辑:程序博客网 时间:2024/06/05 14:58
【程序员编程艺术】学习记录3:字符串包含问题
题目:
假设这有一个各种字母组成的字符串A,和另外一个字符串B,字符串里B的字母数相对少一些。什么方法能最快的查出所有小字符串B 里的字母在大字符串A里都有?
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
方法一:双循环比较法(轮询法)
伪代码:
for(i = 0; i < ShortString.length(); i++){ for(j = 0; j < LongString.length(); j++) { if(LongString[j] == ShortString[i]) { break; } } if(j == LongString.length)//这个有些巧妙 { B中有A中没有的字符 }}反之B中有的字符,A中都可以找到
复杂度:O(n*m)时间开销过大
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
方法二、排序+轮询法
先对两个字符串的字母进行排序,之后同时对两个字符串依次线性扫描轮询
伪代码:
#include <algorithm>sort(ShortString,ShortString + ShortString.length);sort(LongString, LongString + LongString.length);void compare(string str1, string str2){ int i = 0; int j = 0; while(j < str2.length() && i < str1.length()) { while(str1[i] < str2[j] && i < str1.length() - 1) { i++; //如果相等,则不需要动,如果小再动 } if(str1[i] != str2[j]) break; j++; } if(j == str2.length()) { B中有的字符,A中都能找到 } else { B中有A种没有的字符 }}
注意:这里解决了一个如果存在相同字符问题,一定要注意不能直接i++,j++,字符类题目一定要注意考虑字符相同的情况,该算法的复杂度为O(mlogm) + O(nlogn) + O(m+n)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
方法三、哈希表
思路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; //匹配成功}
复杂度为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)
方法5:O(n)到O(m+n)的素数方法
思路:
① 定义最小的26 个素数分别与字符'A'到'Z'对应。
② 遍历长字符串,求得每个字符对应素数的乘积。
③ 遍历短字符串,判断乘积能否被短字符串中的字符对应的素数整除。
伪代码:
#include<iostream>#include<string>using namespace std;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};bool is_contain(string str1, string str2){ int product = 1; //遍历长字符串 for(int i = 0; i < str1.length(); i++) { int index = str1[i] - 'A'; product *= primeNumber[i]; } //遍历短字符串 for(int j = 0; j < str2.length(); j++) { int index = str2[j] - 'A'; if(product % primeNumber[j] != 0) return 0; } return 1;}
纸质手写代码易犯错误:
① 91不是素数
② product初始化为1,不是0
待改进地方
这个程序虽然很巧妙,运用数学知识降低了时间复杂度
1.只考虑大写字符,如果考虑小写字符和数组的话,素数数组需要更多素数
2.没有考虑重复的字符,可以加入判断重复字符的辅助数组。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<完结于2014.7.26 11:42
- 【程序员编程艺术】学习记录3:字符串包含问题
- 程序员编程艺术学习笔记(二)字符串是否包含问题
- 程序员编程艺术--2、字符串包含问题
- 程序员编程艺术:第二章、字符串是否包含问题
- 程序员编程艺术:第二章、字符串是否包含问题
- 程序员编程艺术2:字符串是否包含问题
- 读程序员编程艺术第二章---字符串包含问题
- 读程序员编程艺术第二章---字符串包含问题(二)
- 【程序员编程艺术】第二章:字符串是否包含问题
- 程序员编程艺术:第二章、字符串是否包含问题
- 程序员编程艺术:第二章、字符串是否包含问题
- 程序员编程艺术:第二章、字符串是否包含问题
- [整理]程序员编程艺术:第二章、字符串是否包含问题
- 【July程序员编程艺术】之字符串是否包含问题
- 程序员编程艺术学习笔记(一)字符串左旋问题
- 程序员编程艺术:第二章、字符串是否包含及匹配/查找/转换/拷贝问题
- 程序员编程艺术:第二章、字符串是否包含及匹配/查找/转换/拷贝问题
- 程序员编程艺术:第二章、字符串是否包含及匹配/查找/转换/拷贝问题
- HDU 1588 斐波那契数列数列变形和矩阵连乘
- 7/26
- tar.bz2 解压命令
- python 进阶学习之14
- aul 文件操作
- 【程序员编程艺术】学习记录3:字符串包含问题
- hdu 2565
- UVa11609 - Teams(快速求幂)
- unity3d input输入
- VMware Workstation安装CentOS7.0 图文版
- 【线程管理】之篇一
- js访问web,并处理返回值
- hdoj 2045 不容易系列之(3)—— LELE的RPG难题 【动态规划】
- 考研路上的那些一战二战三战成功与失败的故事系列之二