问答题 5.  给定由字母组成的字符串s1和s2,其中,s2中字母的个数少于s1,如何判断s1是否包含s2?即出现在s2中的字符在s1中都存在。例如s1=“abcdef",s2=“acf”,那么s1就包含s2;如果s1=“abcdef”,s2=“acg”,那么s1就不包含s2,因为s2中有“g”,但是s1中没有“g”。
【正确答案】方法一:直接法
   最直接的方法就是对于s2中的每个字符,通过遍历字符串s1查看是否包含该字符。实现代码如下:
   def isContain(str1,str2):
   len1=len(str1)
   len2=len(str2)
   #字符串ch1比ch2短
   if len1<len2:
   i=0
   while i<len1:
   j=0
   while j<len2:
   if list(str1)[i]==list(str2)[j]:
   break
   j+=1
   if (j>=len2):
   return False
   i+=1
   else:
   #字符串ch1比 ch2长
   i=0
   while i<len2:
   j=0
   while j<len1:
   if (list(str1)[j]==list(str2)[i]):
   break
   j+=1
   if j>=len1:
   return False
   i+=1
   return True
   
   if __name__=="__main__":
   str1="abcdef'
   str2="acf"
   isContain=isContain(str1, str2)
   pririt str1+"与"+str2,
   if (isContain):
   print "有包含关系"
   else:
   print "没有包含关系"
   程序的运行结果为:
   abcdef与acf有包含关系
   算法性能分析:
   这种方法的时间复杂度为O(m*n),其中,m与n分别表示两个字符串的长度。
   方法二:空间换时间法
   首先,定义一个flag数组来记录较短的字符串中字符出现的情况,如果出现,那么标记为1,否则标记为0,同时记录flag数组中1的个数count;接着遍历较长的字符串,对于字符a,若原来flag[a]==1,则修改flag[a]=0,并将count减1;若flag[a]==0,则不做处理。最后判断count的值,如果count==0,那么说明这两个字符有包含关系。实现代码如下:
   def isContain(s1,s2):
   k=0 #字母对应数组的下标
   #用来记录52个字母的出现情况
   flag=[None]*52
   i=0
   while i<52:
   flag[i]=0
   i+=1
   count=0 # 记录段字符串中不同字符出现的个数
   len1=len(s1)
   len2=len(s2)
   #shortStr, longStr 分别用来记录较短和较长的字符串
   #maxLen, minLen 分别用来记录较长和较短字符的长度
   if len1<len2:
   shortStr=s1
   minLen=len1
   longStr=s2
   maxLen=len2
   else:
   shortStr=s2
   minLen=len2
   longStr=s1
   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(short,Str)[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"
   isContain=isContain(str1, str2)
   priit str1+"与"+str2,
   if isContain:
   print "有包含关系"
   else:
   print "没有包含关系"
   算法性能分析:
   这种方法只需要对两个数组分别遍历一遍,因此,时间复杂度为O(m+n)(其中m、n分别为两个字符串的长度),与方法一比,本方法的效率有了明显的提升,但是其缺点是申请了52个额外的存储空间。
【答案解析】[考点] 如何判断两个字符串的包含关系