/*
* 字符串是否包含问题:
* A:abcdef
* B:cf
* C:bx
* StringContains(A, B), 返回ture
* StringContains(A, C), 返回false
*/
/************************************************************
1.Length(A) >= Length(B)
2.
************************************************************/
#include <string>
#include <iostream>
using namespace std;
void TestStringContain();
// 方法一:最简单的两次循环
bool StringContain_1(string str1, string str2);
bool StringcontainChar(string str, char c);
// 方法二:两次排序 + 一次线性遍历
bool StringContain_2(string &str1, string &str2);
// 方法三:首先对str1进行处理,得到其所拥有的字符保存在arr[26]中
// 之后对str2进行遍历
bool StringContain_3(string &str1, string &str2);
// 更快的方法是对str2进行存储。这个可以优化!
bool StringContain_4(string &str1, string &str2);
//将长字符串映射到素数,并相乘。对短字符串,用上述乘积相除,如果不除尽,则false
// 应用位操作
// unsigned char
inline void SetBit(unsigned char *p, int i)
{
*(p) |= 0x1 << i;
}
inline bool GetBit(unsigned char *p, int i)
{
return (((*p) & (0x1 << i)) == 1);
}
// 采用位的方法:将str1映射到位中,将str2映射到位中。
// 两者取或,看str1的映射表是否改变!
// 字符串匹配:不同于经典的字符串匹配。
// 这里只要求:A和B中,出现的字符以及个数相同即可
// 上述方法就可以:1.两重循环 2.hash方法
// 在一个字符串中找出第一个只出现一次的字母
// 1.将str排序。然后遍历,找出第一个 不行!!!
// 2.将str映射到数组中,然后遍历str找第一个...
// 为了实现链式操作,将目的地址返回!!!
char * MyStrCpy(char *dest, const char *src);
#include <algorithm>
#include <assert.h>
#include "2_StringContains.h"
void TestStringContain()
{
string str1 = "cdabef";
string str2 = "be";
string str3 = "bx";
//cout << StringContain_1(str1, str2) << endl;
//cout << StringContain_1(str1, str3) << endl;
cout << StringContain_2(str1, str2) << endl;
cout << StringContain_2(str1, str3) << endl;
cout << StringContain_3(str1, str2) << endl;
cout << StringContain_3(str1, str3) << endl;
}
bool StringContain_1(string str1, string str2)
{
unsigned len2 = str2.length();
for (unsigned i = 0; i < len2; ++i)
{
if (!StringcontainChar(str1, str2[i]))
{
return false;
}
}
return true;
}
bool StringcontainChar(string str, char c)
{
unsigned len = str.length();
for (unsigned i = 0; i < len; ++i)
{
if (str[i] == c)
{
return true;
}
}
return false;
}
bool StringContain_2(string &str1, string &str2)
{
// 1. 对str1、str2按字母序排序
sort(str1.begin(), str1.end());
//cout << str1;
sort(str2.begin(), str2.end());
// 2.遍历str1 str2
unsigned str1Len = str1.length();
unsigned str2Len = str2.length();
for (unsigned i = 0, j = 0; i < str2Len; ++i)
{
while (j < str1Len && str2[i] != str1[j])
{
j++;
}
if (j >= str1Len)
{
return false;
}
}
return true;
}
// 假设都是小写啊。。。
bool StringContain_3(string &str1, string &str2)
{
bool exist[26] = {false};
unsigned len1 = str1.length();
for (unsigned i = 0; i < len1; ++i)
{
exist[ str1[i] - 'a' ] = true;
}
unsigned len2 = str2.length();
for (unsigned i = 0; i < len2; ++i)
{
if (!exist[ str2[i] - 'a' ])
{
return false;
}
}
return true;
}
bool StringContain_4(string &str1, string &str2)
{
bool exist[26] = {false};
unsigned len2 = str2.length();
int num = 0;
for (unsigned i = 0; i < len2; ++i)
{
exist[ str2[i] - 'a' ] = true;
num++;
}
unsigned len1 = str1.length();
for (unsigned i = 0; i < len1; ++i)
{
if (exist[ str1[i] - 'a' ])
{
exist[ str1[i] - 'a' ] = false;
num--;
if (num == 0)
{
return true;
}
}
}
return false;
}
char * MyStrCpy(char *dest, const char *src)
{
assert(dest != NULL && src != NULL);
char *addr = dest;
while ( *dest++ = *src++ );
return addr;
}