位运算的应用:集合运算

问题:如何通过位运算求两个集合的交集并集以及对称差呢?

运行截图:


其实很简单,步骤如下:

①将所有可能出现的元素从1~n编上号

这里我们假设所有可能的元素为'0'~'9','A'~'Z','a'~'z'

则编号为'0'~'9':0~9  'A'~'Z':10~35  'a'~'z':36~61


②利用一个整数保存一个集合的信息

C++中long long类型占有64个比特位,第i个比特位就表示了对应字符的有无:1代表有,0代表无


③利用两个整数的位运算即可表示相应集合的运算

"集合的交" --- (a & b)

"集合的并" --- (a | b)

"集合的差" --- a & (~b)


"集合的对称差" ---  (a | b) & (~(a&b))


④根据整数的运算结果反写出集合的运算结果即可

注意:系统默认只支持32位的移位运算,因此将1左移32位以上时:

1 << 40(×)

long long one = 1; one << 40; (√)

C++11代码如下:

/*C++11*/
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
//改进1:将字符操作改为string操作

//'0'~'9':0~9  'A'~'Z':10~35  'a'~'z':36~61
char getKey(int i)
{
	if (i <= 9) return '0' + i;
	else if (i <= 35) return 'A' + i - 10;
	else return 'a' + i - 36;
}

//从字符串中得到64位的比特串 
long long input()
{
	string a;
	cin >> a;
	long long tmp = 0, one = 1;
	for (auto p : a)
	{
		//改进2:判断'0'~'9'/'A'~'Z'/'a'~'z'时运用isnum(),isupper(),islower()函数 
		if (isdigit(p)) tmp |= one << (p - '0');
		else if (isupper(p)) tmp |= one << (p - 'A' + 10);
		else if (islower(p)) tmp |= one << (p - 'a' + 36);
	}
	return tmp;
}

//相应的字符集合 
string output(long long a)
{
	string tmp = "{";
	long long one = 1;
	for (int i = 0; i <= 61; ++i)
	{
		if (a & (one << i))
			tmp = tmp + getKey(i) + ',';
	}
	if (*(tmp.end() - 1) == ',') *(tmp.end() - 1) = '}';
	else tmp += '}';
	return tmp+"\n";
}

//笛卡儿积 
string outputDsc(long long a, long long b)
{
	string tmp;
	long long one = 1;
	for (int i = 0; i <= 61; ++i)
		for (int j = 0; j <= 61; ++j)
			if ((a&(one << i) && (b&(one << j))))
				tmp = tmp + '<' + getKey(i) + ',' + getKey(j) + '>' + ',';
	if (!tmp.empty()) tmp.erase(tmp.end() - 1, tmp.end());
	return '{'+tmp+"}\n";
}

int main()
{
	long long a = 0, b = 0;
	cout << "输入集合A:";
	a = input();
	cout << "输入集合B:";
	b = input();

	//改进3:使用位运算代替双重for循环查找 
	cout << "集合A:" << output(a);
	cout << "集合B:" << output(b);
	cout << "集合的交:" << output(a & b);
	cout << "集合的并:" << output(a | b);
	cout << "集合的差:" << output(a & (~b));
	cout << "集合的对称差:" << output((a | b) & (~(a&b)));
	cout << "集合的笛卡尔积:" << endl << outputDsc(a, b);
	system("pause");
	return 0;
}

谢谢观看~ 

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/80251902