“由各种字母组成的字符串S,另外一个字母数相对少一些的字符串T,设法最快的查出是否T中的字母均在S中?”

问题:“由各种字母组成的字符串S,另外一个字母数相对少一些的字符串T,设法最快的查出是否T中的字母均在S中?”

思路:

判断集合A是否包含集合B,即判断其差(A-B)是否为空集。(A-B)不好算,可换为求(A -(A交B))。

考虑集合的表示方面,没要求顺序,即无序集。

仅考虑26个小写字母的情况,自然地想用位向量。用32位整数表示集合,第0位为1表示含'a',第1位为1表示含'b',……

#include <cassert>
#include <iostream>
using namespace std;

/*
  这个示意性的程序仅考虑了26个小写字母。
  若字符集更大可换用数组作为字符串的“签名”,对UNICODE,0x10FFFF个字符用int[]不过4M内存,也可继续按位存储省点内存。
*/
int str_sig(char const *ps)
{
  assert(ps);
  assert(isalpha(*ps));

  int sig = 0;
  while(*ps){
    sig |= (1 << (*ps - 'a'));
    ++ps;
  }

  return sig;
}

bool contains_charset(char const *psa, char const *psb)
{
  int sig_a = str_sig(psa);
  int sig_b = str_sig(psb);
  return ((sig_a & sig_b) ^ sig_b) == 0;
}

void test(char const *psa, char const *psb)
{
  cout << "\"" << psa << "\" " << (contains_charset(psa, psb) ? "" : "not ") << " contains \"" << psb << "\"\n";
}

int main()
{
  assert(str_sig("") == 0);
  assert(str_sig("a") == (1 <<  0));
  assert(str_sig("z") == (1 << 25));
  assert(str_sig("abcdefghijklmnopqrstuvwxyz") == ((1 << 26) - 1));
  test("", "");
  test("a", "a");
  test("a", "b");
  test("ab", "b");
  test("bc", "b");
  test("abc", "b");
  test("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
  return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值