5.5python如何判断两个字符数组的包含关系

北慕城南 提交于 2020-02-04 22:41:51

题目描述:

给定由字母组成的字符串 s1 和 s2,其中 s2 中的字母的个数少于 s1,如何判断 s1 是否包含 s2?
例如,s1=‘abcdef’,s2=‘acf’,那么s1即包含s2;
若s s1=‘abcdef’,s2=‘acg’,则s1不包含s2。

方法:

  1. 直接法
  2. 空间换时间法

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!