编程艺术 - 第二章 第一节、俩个字符串是否包含
作者:互联网
题目
假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字
母数相对少一些。从算法是讲,什么方法能最快的查出所有小字符串里的字母在大字符串里
都有?
比如,如果是下面两个字符串:
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;
}
本章完!
标签:slen,sub,int,编程,第一节,char,dest,俩个,sizeof 来源: https://blog.csdn.net/qq_45254369/article/details/116333875