假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字
母数相对少一些。从算法是讲,什么方法能最快的查出所有小字符串里的字母在大字符串里
都有?
比如,如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOM
答案是 true,所有在 string2 里的字母 string1 也都有。
如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOZ
答案是 false,因为第二个字符串里的 Z 字母不在第一个字符串里
最简单的思路就是,让子串中的每一个字符都去与目标串的字符去匹配,匹配成功就继续匹配,若匹配失败直接false。时间复杂度为O(n^2),空间复杂度为O(1);
C
#include<stdio.h> #include<string.h> #include<stdbool.h> //暴力求解 bool CompareSting(char* dest, int dlen, char* sub, int slen) { int i = 0;//目标串指针 int j = 0;//子串指针 for (j = 0; j < slen; j++)//O(n^2) { int flag = 0; for (i = 0; i < dlen; i++) { if (sub[j] == dest[i]) { flag = 1; break; } } if (flag == 0) { return false; } } return true; } int main() { char dest[] = "ABCDEFGHLMNOPQRS"; char sub[] = "DCGSRQPOM"; int dlen = sizeof(dest) / sizeof(dest[0]) - 1; int slen = sizeof(sub) / sizeof(sub[0]) - 1; bool ret = CompareSting(dest, dlen, sub, slen); if (ret) { printf("true\n"); } else { printf("false\n"); } return 0; }
暴力法高额的时间复杂度是因为字符是无序的。所以这里我们先排序后一遍匹配就可以了。这里时间复杂度最大就是排序算法的,这里用的是qsort库排序算法。时间复杂度O(n*logn)
C
#include<stdio.h> #include<string.h> #include<stdbool.h> #include<stdlib.h> int compar_char(const void* e1, const void* e2) { return *(char*)e1 - *(char*)e2; } bool CompareSting(char* dest, int dlen, char* sub, int slen) { //先让目标串和子串排序,以便后面对比 qsort(dest, dlen, sizeof(dest[0]), compar_char);//O(n*logn) qsort(sub, slen, sizeof(sub[0]), compar_char); int i = 0;//目标串指针 int j = 0;//子串指针 for(i = 0; i < dlen; i++) { if (sub[j] == dest[i])//相等,子串指针移动 { j++; } if (j < slen)//若在目标串走完前,发现子串匹配完,就表示成功了 { return true; } } return false; } int main() { char dest[] = "ABCDEFGHLMNOPQRS"; char sub[] = "DCGSRQPOM"; int dlen = sizeof(dest) / sizeof(dest[0]) - 1; int slen = sizeof(sub) / sizeof(sub[0]) - 1; bool ret = CompareSting(dest, dlen, sub, slen); if (ret) { printf("true\n"); } else { printf("false\n"); } return 0; }
这里题目并没有说只有大写,为了保险起见,我用了128大小的数组来表示。
把子串中存在的字符以字符值对应数组下标,数组中存1来表示该字符存在。
然后再遍历目标串,把目标串的字符对应的下标存的值均修改为0。
然后再遍历一遍数组,只要发现还有1的值,就便是匹配失败,否则匹配成功。
C
#include<stdio.h> #include<string.h> #include<stdbool.h> #include<stdlib.h> //哈希表 - 数组 bool CompareSting(char* dest, int dlen, char* sub, int slen) { int ASC[128] = { 0 }; int i = 0; //将子串中所有的字母放入哈希表 for (i = 0; i < slen; i++) { ASC[sub[i]] = 1; } //用目标串来拿出哈希表 for (i = 0; i < dlen; i++) { ASC[dest[i]] = 0; } //遍历哈希表,若发现还没拿出完,就是false, for (i = 0; i < 128; i++) { if (ASC[i] != 0) { return false; } } return true; } int main() { char dest[] = "ABCDEFGHLMNOPQRS"; char sub[] = "DCGSRQPOM"; int dlen = sizeof(dest) / sizeof(dest[0]) - 1; int slen = sizeof(sub) / sizeof(sub[0]) - 1; bool ret = CompareSting(dest, dlen, sub, slen); if (ret) { printf("true\n"); } else { printf("false\n"); } return 0; }
本章完!