# C语言 练习第三天 字符串是否包含问题

C语言练习第三天 字符串是否包含问题

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

比如,如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPO
答案是true,所有在string2里的字母string1也都有。

如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPZ
答案是false,因为第二个字符串里的Z字母不在第一个字符串里。

问题及主要思路来自于 July
链接: link.

第一种方法 暴力比较法

这种方法是最简单也最好想的一种方法 无论对于字符串是否有大小写区别及不是英文字符的字符串都适用,但其复杂度最多为 o(m*n) 是一种时间维度较为复杂的算法

代码如下 (全文代码均用 VS Studio 2013 测试 均通过 正确运行 如有错误大家可以指证)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//暴力逐个比较法  复杂度 m*n
int compare(char* s1, char* s2){
	int a1 = strlen(s1);
	int a2 = strlen(s2);
	int i = 0;
	int j = 0;
	for (i = 0; i < a2; i++){
		for (j = 0; j < a1; j++){
			if (s2[i] == s1[j]){
				break;
			}
		}
		if (j == a1){
			puts("false");
			return 0;
		}
	}
	puts("true");
	return 1;
}

//测试函数
int main(void){
	char str1[] = "ABCDEFGHLMNOPQRS";
	char str2[] = "DCGSRQPO";

	//暴力逐个比较法
	compare(str1,str2);

	return 0;
}

第二种方法 排序比较法

相比于暴力比较法 排序比较法先将字符串分别排序
本例中用C语言库函数 qsort()进行排序

因为字符在计算机中用ASCII码进行储存 ,排序的实质是按ASCII码大小进行储存
所以 如果str2完全在str1中,呢么str2[0]绝对大于等于str1[0]
用 str2[flag2] > str1[flag1]作为循环条件 跳出循环时
则有两种可能性
可能性1 str1[flag1]=str2[flag2],呢么外循环继续 flag2++;
如果str1[flag1]>str2[flag2],呢么str2中的这个字符在str1中绝对没有 则str1中不完全包含str2
则返回false
这个方法看似和第一种方法复杂度差不多 实则在字母个数较多时 这个方法的复杂度将显著低于第一种方法.

代码如下

//排序比较法   复杂度O(mlogm)+O(nlogn)+O(m+n)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int qsort_letter(const void* e1, const void* e2){
	return *(char*)e1 - *(char*)e2;
}
int compare1(char* s1, char* s2){
	int flag1 = 0;
	int flag2 = 0;
	while (flag1 < strlen(s1) && flag2 < strlen(s2)){
		//防止指针越界,从数组的开始到末尾依次进行比较

		while (s2[flag2] > s1[flag1] && flag1 < strlen(s1) - 1){
			//因为字符串为按ASCII码排序 
			//如果s1包含s2
			//呢么s2的第一个元素必然大于等于s1的第一个元素
			//如果s2的第一个元素小于s1的第一个元素 呢么说明s2[0]在s1中没有
			//以此类推比较 
			//如果这个循环结束 s2中的这个元素还依然大于s1中最后一个元素,呢么循环结束
			//表示s2中的元素s1中没有 呢么两个字符串不一样
			flag1++;
		}
		if (s1[flag1] != s2[flag2]) break;//只要有一个字符s1中没有 呢么s2和s1不同
		flag2++;
	}
	if (flag2 == strlen(s2)){
		puts("ture");
		return 1;
	}
	else{
		puts("false");
		return 0;
	}
}
//测试函数
int main(void){
	char str1[] = "ABCDEFGHLMNOPQRS";
	char str2[] = "DCGSRQPO";
	//排序比较法
	qsort(str1, strlen(str1), sizeof(str1[0]), qsort_letter);
	qsort(str2, strlen(str2), sizeof(str2[0]), qsort_letter);
	compare1(str1,str2);
	//相比于暴力逐个比较法 在元素个数较多时 这个算法的复杂度远低于暴力逐个比较法

	return 0;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卧槽你有120斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值