ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

编程艺术 - 第二章 第一节、俩个字符串是否包含

2021-05-01 23:02:13  阅读:181  来源: 互联网

标签:slen sub int 编程 第一节 char dest 俩个 sizeof


题目

假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字
母数相对少一些。从算法是讲,什么方法能最快的查出所有小字符串里的字母在大字符串里
都有?
比如,如果是下面两个字符串:
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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有