public class Test8
{
public static void main(String[] args)
{
// 1.给定集合A{0,1,2.....30,31}
// 2.给定集合B{5,6....10,11}
// 3.求 A 和 B 的交集
// 4.求 A 和 B 的并集
// 5.求 B 相对于 A 的补集
// 6.求 A 对 B 差集
// 7.求给定集合 C{7,9} 是 A 和 B 哪个集合的子集,并实现任意集合子集的查询功能
// 8.以上所有集合必须使用一个int表示而非数组,所有代码均以按位运算符进行
// 9.使用查表法可以根据int表示的集合正确输出该集合所表示的数组。
// 10.必须详细写出解题思路,实现方法。
//首先考虑,如何使用int来保存一个集合,貌似很难,我们都知道
//int表示的是一个数,表示集合怎么表示?
//先看集合A,0-31,是不是很眼熟?在哪里见过?这不就是int的位移区间么?
//那么是不是可以这样,我们用一个数的位移次数来表示集合?关键是怎么在一个
//数中表示这么多数的位移次数,而且还要保持这个数每一种位移次数的值不重复。
//注意我这里用的mask是java里常见的掩码,shift表示位移,以后看见源文件
//中出现这些变量的名字就知道是做什么的了
//这里边打印了1的不同位移情况下的掩码,我们可以想想,如果我拿没一个掩码
//表示一个数,是不是形成一种映射关系?类似map的key 和 value,那么这个
//key是什么?其实key就是掩码,而这个value就是1到这个掩码的位移次数。
//看这个图是不是眼前一亮,其实跟之前的位移那个图差不多,一个是1,一个是-1
int mask = 0;
for (int shift = 0; shift < 32; shift++)
{
System.out.println(getIntegerToBinary((mask = (1 << shift))));
}
System.out.println("======================================>");
//下面做下尝试,比如我们自己做一个012的集合
//这里我们得想下,一个空集,怎么往里边加数据?前边讲过| ^ + 都行吧,
//其实还是 | 好一些,其他的在某些情况下会有点小问题
int set = 0;
set = set | 1 << 0;
set = set | 1 << 1;
set = set | 1 << 2;
//这里发现我们成功了对么?我们可以用最低位表示这个集合中有0对吧
//而顺序是什么呢?从右往左每一位为1表示有该位位移次数的这个数。
//当然你如果喜欢从左往右也可以,呵呵,自己可以尝试一下
System.out.println(getIntegerToBinary(set));
System.out.println("======================================>");
//1第一点,我们就这么做出来了,B 和 C 的话如法炮制,由于题目里边都是连续的数
//咱就可以投机取巧了
int A = 0, B = 0, C = 0;
for (int shift = 0; shift < Integer.SIZE; shift++)
{
mask = 1 << shift;
//注意这里我为什么要12在前,4在后
if((shift < 12) && (shift > 4))
B |= mask;
if((shift == 7) || (shift == 9))
C |= mask;
A |= mask;
}
System.out.println(getIntegerToBinary(A));
System.out.println(getIntegerToBinary(B));
System.out.println(getIntegerToBinary(C));
System.out.println("======================================>");
//3,求 A 和 B 的交集,这个在Test7里边咱讲了交集用什么?
System.out.println(getIntegerToBinary(A & B));
System.out.println("======================================>");
//4,求 A 和 B 的并集
System.out.println(getIntegerToBinary(A | B));
System.out.println("======================================>");
//5,求 B 相对于 A 的补集
//6, 跟 5 一样
System.out.println(getIntegerToBinary(A ^ B));
System.out.println("======================================>");
//7.求给定集合 C{7,9} 是 A 和 B 哪个集合的子集
//这个检查很简单,先求交集,如果这个交集还是他
//自己,那么就是这个集合的子集
System.out.println((C & A) == C);
System.out.println((C & B) == C);
System.out.println("======================================>");
System.out.println(isChid(C, A));
System.out.println(isChid(C, B));
System.out.println("======================================>");
System.out.print("A ");printIntegerSet(A);
System.out.print("B ");printIntegerSet(B);
System.out.print("C ");printIntegerSet(C);
System.out.print("A & B ");printIntegerSet(A & B);
System.out.print("A | B ");printIntegerSet(A | B);
System.out.print("A ^ B ");printIntegerSet(A ^ B);
System.out.print("C & B ");printIntegerSet(C & B);
System.out.print("C | B ");printIntegerSet(C | B);
System.out.print("C ^ B ");printIntegerSet(C ^ B);
}
public static final void printIntegerSet(int set)
{
StringBuilder sb = new StringBuilder("Set{");
int mask;
for (int shift = 0; shift < Integer.SIZE; shift++)
{
mask = 1 << shift;
if(mask == (set & mask))
sb.append(digits[shift] + ",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("}");
System.out.println(sb.toString());
}
public final static int[] digits;
static
{
digits = new int[Integer.SIZE];
for (int i = 0; i < digits.length; i++)
{
digits[i] = i;
}
}
/**
* 求前一个集合是不是后一个集合的子集
* @return true表示是,false表示不是
*/
public static final boolean isChid(int arg0, int arg1)
{
return arg0 == (arg0 & arg1);
}
public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
public static final String getIntegerToBinary(int value)
{
String binary = Integer.toBinaryString(value);
int length = Integer.SIZE - binary.length();
return DEFAULT_INT_ZERO.substring(0, length) + binary;
}
}
复习笔记7 位映射图
最新推荐文章于 2024-03-26 15:00:41 发布