(2)字符串包含问题

/*
 * 字符串是否包含问题:
 *	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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值