字符串的包含问题

问题:给定一个字符串A,问字符串B的所有字符是否都出现在字符A的字符集中,(为了方便说明,字符中均为大写字符)

编写 函数 bool isStringContain(string &a,String &b);

如字符串A=‘ABCDEF’,B=‘BCD’,return true;

A=‘ABCDEF‘,B=‘BDG‘,return false;

A=‘ABCDEF‘,B=‘AAA‘,return true;

初学者可能会用个两层循环遍历解决:

 1 int isStringContain(String &A,String &B)
 2 {
 3    int j;
 4    for(int i=0;i<B.length();i++)
 5   {
 6    for(j=0;j<A.length()&&(a[j]!=b[i]);j++)//相同的会跳出本次循环
 7   {
 8    if(j=(a.length-1))//找到A的倒数最后一位且不相同,证明有B一位字符失配
 9      return false;
10   }
11   }
12     return true;//B所有找完了证明都在A里面
13 }

但是这样的时间复杂度为O(MN),两次遍历且没优化~

方法二:标记数组法

其实问题要求查找是否包含,并未规定其字符出现次数和顺序。

我们可以用某个数组来存储A字符串中字符是否出现,标记为‘1’,然后再直接判断B中字符是否与A中匹配

int isStringContain(String &A,String &B)
{
  char flag[26];//用来标记的数组,方便操作设置成字符(C语言没bool数组只能这样模拟bool数组)
  int i;
 for(i=0;i<A.length();i++)
{
  flag[A[i]-‘A‘]=‘1‘;//A[i]-‘A’代表该字符在26字母中的顺序
}
for(i=0;i<B.length();i++)
{
  if(flag[B[i]-‘A‘]!=‘1‘)//B中字符在flag字符组中没标记有,证明该字符并不是A的字符集中的字符,直接返回false;
  return 0;//0代表不是
}
return 1;//查找完,B中字符都在A中,返回1表示 是包含集
}

方法三:位运算

方法二中我们运用了标记的思想,那算法的优化在于如何对标记数组及其标记方式的优化。

其实计算机中存的本来就是二进制数,天然的0.1标记位。那么我们很自然的想到用位运算去优化标记数组。

关键是我们需要多少位二进制进行标记。

题设中全为大写字母,那么有26个字母,只要位数大于26即可// 当需求扩大时候记得 扩展标记位数

联想到 C语言中 int 数据为4个字节,每个字节8位 (我只需要用一个int 类型便完成了标记长度)

字符是字母表中第几个我就标记第几个~

标记用或 运算,以保证前面标记的数据不丢失

然后匹配时候我直接用与运算 ,只要不全为0即匹配成功。

int isStringContain(char a[],char b[])
{
  int i;
  int table=0;
  for(i=0;i<strlen(a);i++)
  {
    table |=(1<<(a[i]-‘A‘));//选择左移并每次 或运算保留标记
  }
  for(i=0;i<strlen(b);i++)
  {
    if(( table & (1<<(b[i]-‘A‘)))==0)//用B中得到的字符 左移后肯定为00000100000这种(只带一位1)数据,那么相与时候只要该位的table如果为1 肯定结果有一位为1 ,结果就不为0 了
    {
      return 0;
    }
  }
  return 1;
}

最后完整代码:

#include <stdio.h>
#include <string.h>
int isStringContain(char a[],char b[]);
int main()
{
  int flag=0;
  char A[50];
  char B[30];
  scanf("%s",A);
  scanf("%s",B);
  flag=isStringContain(&A,&B);
  if(flag==1)
  {
    printf("true\n");
  }
  else
  {
    printf("false\n");
  }
}
int isStringContain(char a[],char b[])
{
  int i;
  int table=0;
  for(i=0;i<strlen(a);i++)
  {
    table |=(1<<(a[i]-‘A‘));
  }
  for(i=0;i<strlen(b);i++)
  {
    if(( table & (1<<(b[i]-‘A‘)))==0)
    {
      return 0;
    }
  }
  return 1;
}

这是学到的一个比较好的算法,写出来分享下,如果有错误请多多指出,谢谢~

时间: 2024-11-20 14:08:06

字符串的包含问题的相关文章

Openjudge-NOI题库-字符串移位包含问题

题目描述 Description 对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串. 给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串.例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串. 输入输出格式 Input/output 输入: 一行,包含两个字符串,中间由单个空格隔开.字符串只包含字母和数字,长度不超过30. 输

编程之美之字符串移位包含问题

[题目] 给定两个字符串s1和s2,要求判断s2是否能够被通过s1做循环移位(rotate)得到的字符串包含.例如,S1=AABCD和s2=CDAA,返回true:给定s1=ABCD和s2=ACBD,返回false. [分析] [思路一] 从题目中可以看出,我们可以使用最直接的方法对S1进行循环移动,再进行字符串包含的判断,从而遍历其所有的可能性. 字符串循环移动,时间复杂度为O(n),字符串包含判断,采用普通的方法,时间复杂度为O(n*m),总体复杂度为O(n*n*m). 字符串包含判断,若采

CareerCup之1.8 字符串移位包含问题

[题目] 原文: 1.8 Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring ( i.e., "waterbottle" is a rotat

mysql 检查字符串是否包含子串

1.使用substring_index(src,target,index) 从src的开头查找第index个target.返回的substring为从src的开头到第num个target这段字符串.比如 substring_index('absscdessfss','ss',1) 返回ab substring_index('absscdessfss','ss',2) 返回absscde substring_index('absscdessfss','tt',1) 返回absscdessfss 因

php如何判断一个字符串是否包含另一个字符串

来自1:http://blog.sina.com.cn/s/blog_8edc37a801016yha.html -------------------------------------------------------------------- 我觉得最简单的就是:(用这种最好,StrPos效率最高) strpos($a, $b) !== false 如果$a 中存在 $b,则为 true ,否则为 false. 用 !== false (或者 === false) 的原因是如果 $b 正

php 判断字符串是否包含中文

正则表达式: /[\x7f-\xff]/ 如: var_dump(preg_match("/[\x7f-\xff]/",'Hello 你好')); 那么它会返回true,因为字符串中包含中文

第3章 结构之法——字符串移位包含的问题

字符串移位包含的问题 问题描述 分析与解法 [解法一] 具体代码如下: 1 package chapter3jiegouzhifa.QuestionOfStringMove; 2 /** 3 * 字符串移位包含的问题 4 * [解法一] 5 * @author DELL 6 * 7 */ 8 public class StringMove { 9 /** 10 * 寻找移位后的字串(左移) 11 * @param src 源字符串 12 * @param des 要查找的子串 13 * @ret

String的两个API,判断指定字符串是否包含另一字符串,在字符串中删除指定字符串。

// 在字符串中删除指定字符串. String phoneNum="1795112345"; phoneNum = phoneNum.replace("17951", ""); System.out.println(phoneNum); //判断指定字符串是否包含另一字符串 String phoneNum="1795112345"; String IpNum="17951"; return phoneNum

判断字符串是否包含其他字符串

//判断两字符串是否相等- (BOOL)isEqualToString:(NSString *)aString; //判断开头是否包含该字符串- (BOOL)hasPrefix:(NSString *)aString; //判断结尾是否包含该字符串- (BOOL)hasSuffix:(NSString *)aString; //该字符串在那个位置- (NSRange)rangeOfString:(NSString *)aString; 判断字符串是否包含其他字符串,布布扣,bubuko.com

字符串是否包含问题

题目描述 假设这有两个分别由字母组成的字符串A另外字符串B,字符串B的字母数较字符串A少一些.什么方法能最快地查出字符串B所有字母是不是都在字符串A里?也就是说判断字符串B是不是字符串A的真子集(为了简化,姑且认为两个集合都不是空集,即字符串都不为空.). 分析与解法 解法一:暴力轮询 就是将B中的每一字符都和A中的字符做对比,思想简单此处就不再实现 解法二:普通排序 就是先对A 和 B做排序,然后对比B和A /** * <p> * 普通排序的方式 * </p> * @author