题目描述:
给定由字母组成的字符串 s1 和 s2,其中 s2 中的字母的个数少于 s1,如何判断 s1 是否包含 s2?
例如,s1=‘abcdef’,s2=‘acf’,那么s1即包含s2;
若s s1=‘abcdef’,s2=‘acg’,则s1不包含s2。
方法:
- 直接法
- 空间换时间法
1.直接法
对于s2中的每个字符,通过遍历字符串s1,查看s1中是否包含该字符。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/4 17:44
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def isContain(str1, str2):
len1 = len(str1)
len2 = len(str2)
if len1 < len2: # str1是否包含在str2中
i = 0
while i < len1: # 对str1中每个字符
j = 0
while j < len2: # 判断是否包含在str2中
if list(str1)[i] == list(str2)[j]:
break
j += 1
if j >= len2:
return False
i += 1
else: # str2是否包含在str1中
i = 0
while i < len2:
j = 0
while j < len1:
if list(str2)[i] == list(str1)[j]:
break
j += 1
if j >= len1:
return False
i += 1
return True
if __name__ == '__main__':
str1 = 'abcdef'
str2 = 'acf'
if isContain(str1, str2):
print('yes!')
else:
print('no!')
结果:
算法性能分析:
时间复杂度为O(m*n);
2.空间换时间法
首先,定义一个flag数组来记录较短的字符串中字符出现的情况,如果出现,记为1,否则记为0,同时记录flag数组中1的个数count;
接着遍历较长的字符串,对于字符a,若原来flag[a]==1,则修改flag[a]=0,并将count减1;若原来flag[a]=0,则不做处理,最后判断 count的值,如果count等于0,说明这两个字符串有包含关系。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/4 18:41
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def isContain(str1, str2):
k = 0 # 字母对应数组的下标
flag = [None] * 52 # 用来记录52个字母的出现情况
i = 0
while i < 52:
flag[i] = 0
i += 1
count = 0 # 记录字符串中不同字符出现的个数
len1 = len(str1)
len2 = len(str2)
# shortStr,longStr分别用来记录较短和较长的字符串
# maxLen,minLen分别用来记录较长和较短字符串长度
if len1 < len2:
longStr = str2
shortStr = str1
minLen = len1
maxLen = len2
else:
longStr = str1
shortStr = str2
minLen = len2
maxLen = len1
# 遍历短字符串
i = 0
while i < minLen:
# 把字符转换成数组对应下标(大写字母:0~25,小写字母:26~51)
if ord(list(shortStr)[i]) >= ord('A') and ord(list(shortStr)[i]) <= ord('Z'):
k = ord(list(shortStr)[i]) - ord('A')
else:
k = ord(list(shortStr)[i]) - ord('a') + 26
if flag[k] == 0:
flag[k] = 1
count += 1
i += 1
# 遍历长字符串
j = 0
while j < maxLen:
if ord(list(longStr)[j]) >= ord('A') and ord(list(longStr)[j]) <= ord('Z'):
k = ord(list(longStr)[j]) - ord('A')
else:
k = ord(list(longStr)[j]) - ord('a') + 26
if flag[k] == 1:
flag[k] = 0
count -= 1
if count == 0:
return True
j += 1
return False
if __name__ == '__main__':
str1 = 'abcdef'
str2 = 'acf'
if isContain(str1, str2):
print('yes!')
else:
print('no!')
结果:
算法性能分析:
时间复杂度为O(m+n);
与方法一相比,本方法效率有了提升,但是申请了52个额外的存储空间。
end
来源:CSDN
作者:布欧不欧
链接:https://blog.csdn.net/weixin_44321080/article/details/104172549