A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘蕴学   /  2012-5-17 07:12  /  5436 人查看  /  29 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

帮忙总结下大家解决问题的思路。
1、先把十进制的A、B、C分别按照<<、~和|循环32遍全部表示出来,再通过 Integer.toBinaryString打印出来。
2、加入一个31个0的字符串,放在B前,每次if循环字符串减少一个0.
另:我想玄机就在这个31位0的字符串吧,只有完全不用字符串才算是完成了整个题目,不知道是不是这样。

点评

我说的不用字符串是指不能直接字符串操作而不做运算  发表于 2012-5-18 00:10
回复 使用道具 举报
package aa;

/**
* 第二个,集合
*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变量的每位分别代表1到31个元素  由于这里只有0到31所以最低为代表0 最高位代表31 当那为为1代表这个集合里有这个数
*为0代表集合里没这个数
*集合A用int变量listA表示的话为每位都是1所以为-1
*集合B用int变量listB表示的话为5到11位
*求A和B的交际 就是listA&listB的结果位数为1的就是交际
*/
public class MyListDemo {
        public static void main(String[] args) {
                int listA=-1;
                //集合b是5到11 所以我拿12位表示它  因为重0开始 由于这个集合头前五位是0
                //地6为到12为1 用16进制表示为0xfe0我拿这个数|上0就是我要的数了
                int listB=0|0xfe0;
                //求listA与listB的交际 拿listA&上listB 定义一个int型变量存储交集
                int jiaoJi=listA&listB;
                //应为是交际而listB的元素是5到11所以取出6到12位中改位为1的数在-1即可
                System.out.println("交集为:");
                get(jiaoJi,6,12);
                int bingJi=listA|listB;
                //并集拿2个集合代表的数进行或运算就可以了  次数为大的集合1到32
                System.out.println("并集为:");
                get(bingJi,1,32);
                System.out.println("补集为:");
                //补集listA有的listB没有 ^是2进制位相同为0不同为1 应为listA所有位都是1所以不会
                //出现listB有的listA没有
                int buJi=listA^listB;
                get(buJi,1,32);
                //求给定集合 C{7,9} 是 A 和 B 哪个集合的子集
                //先创建个c集合  每个16进制位代表4位
                //集合c和集合A,B&操作 8到10位为1那么就是它的子集
                int listC=0|0x380;
                if (contains(listC&listA,8,10)){
                        System.out.println("listC是listA的子集");
                }
                if (contains(listC&listB,8,10)){
                        System.out.println("listC是listB的子集");
                }
               
               
//                System.out.println(Integer.toBinaryString());
        }
        /**
         * @param list
         * @param start
         * @param end
         * @return
         */
        static boolean contains(int list,int start,int end){
                boolean flag=false;
                if(get(list,start,end,true)){
                        flag=true;
                }
                return flag;
               
        }
        /**
         * 把int集合所带表的集合的元素循环拿出来
         * 从list集合里面的指针为start-1处开始check匹配到end处当符合要求就打印出来
         * flag 为true的话就不打印当匹配不成功的话就把ret设置为false退出循环换回ret
         */
        static boolean get(int list,int start,int end,boolean flag){
                boolean ret=false;
                int arg=(start/start)<<start-1;
                for(int row=start;row<=end;row++){
                        if(check(list,arg)){
                                if(flag){
                                        arg<<=1;
                                        ret=true;
                                        continue;
                                }
                                System.out.print(row-1+" ");
                        }
                        if(flag){
                                ret=false;
                                break;
                        }
                        arg<<=1;
//                        System.out.println(arg);
                }
                return ret;
        }
        /**
         * 打印集合中的数
         */
        static void get(int list,int start,int end){
                get(list,start,end,false);
                //没打印完一个空行一次
                System.out.println();
        }
         /**
         * 用于检测元素是否存在
         * 判断该位是否有元素只需要用那位为1其他未为0的数&int集合在看结果是否等于&操作的数
         */
        static boolean check(int list,int arg){
                boolean flag=false;
                list=list&arg;
                if(list==arg){
                        flag=true;
//                        System.out.println(list==arg);
                }
                return flag;
        }
}

点评

思路清晰,实现方式正确,注释完整,so cool,代码略微有些臃肿  发表于 2012-5-18 16:03

评分

参与人数 1技术分 +3 收起 理由
贠(yun)靖 + 3

查看全部评分

回复 使用道具 举报
本帖最后由 王永旺 于 2012-5-18 20:26 编辑

说明自己做的,绝对没有参考上边童鞋的   另:输出方法不是使用的查表法。判断子集的打印方法不太好,暂时没想到更好方法
  1. package cn.wangwang.day2;

  2. /**
  3. * 1.        所有集合均用int对应的二进制每一位表示,1表示该位存在,0表示该位不存在;
  4. *                 从右至左依次表示0~31位;
  5. *
  6. * 2.         A集合二进制形式为:1111111111111111111111111111111 int类型为:-1
  7. *                 B集合二进制形式为:0000000000000000000111111100000 int类型位4064
  8. *                 C集合二进制形式为:0000000000000000000001010000000 int类型位:640
  9. *
  10. * 3.        a&b可表示A和B集合的交集
  11. *                a|b可表示A和B集合的并集
  12. *                a^b可表示B相对于 A的补集
  13. *                ~(a^b)可表示 A 对 B 差集
  14. *
  15. * 4.判断C集合是否为A子集可看其是否有交集,没有则判定不是子集。
  16. */
  17. public class abc {
  18.         public static void main(String[] args) {
  19.                 int a = -1;
  20.                 int b = 4064;
  21.                 int c = 640;
  22.                 int and = a&b;                  //and表示A和B集合的交集
  23.                 int or = a|b;        //or表示A和B集合的并集
  24.                 int xor=a^b ;        //xor表示B相对于 A的补集
  25.                 int eor=~xor;                   //eor表示 A 对 B 差集
  26.          
  27.                 System.out.println("A与B交集为:");   myPrint(and);           //myPrint用于将结果打印
  28.                 System.out.println("A与B并集为:");   myPrint(or);
  29.                 System.out.println("A与B补集为:");   myPrint(xor);
  30.                 System.out.println("A与B差集为:"); myPrint(eor);
  31.                
  32.                 isSubArray(a,c);                //判断是否为a子集。
  33.                 isSubArray(b,c);            //判断是否为b子集。
  34.         }

  35.         //下面为打印方法
  36.         private static void myPrint(int value) {
  37.                 boolean haveHigh=false;                   //是否有最高位.
  38.                 if(value<0){
  39.                         haveHigh=true;                  
  40.                         value=value&2147483647;                    //最高位设为0
  41.                 }
  42.                
  43.                 System.out.print("[");                 //逐位打印
  44.                 for(int i=0;i<31;i++){
  45.                         if(value%2==1)               
  46.                                 System.out.print(i+" ");
  47.                         value=value/2;
  48.                 }
  49.                
  50.                 if(haveHigh)                         //是否输出最高位
  51.                         System.out.print(31);
  52.                
  53.                 System.out.println("]");
  54.         }        

  55.         //下面为判断子集的方法
  56.         private static void isSubArray(int a, int c) {
  57.                 if((c&a)!=0){
  58.                         System.out.println("集合"+Integer.toBinaryString(c)+"是集合"+Integer.toBinaryString(a)+"的子集");
  59.                 } else               
  60.                 System.out.println("集合"+Integer.toBinaryString(c)+"不是集合"+Integer.toBinaryString(a)+"的子集");
  61.         }
  62. }
复制代码

点评

不过你这个用 ^ 和 ~ 来区分补集和差集的做法让我眼前一亮  发表于 2012-5-19 02:08
也就是说判断每一位是否为1  发表于 2012-5-19 01:17
在一个,打印方法上,你没招到规律,其实还是位移,A集合的所有元素没发现规律么?如果你按位存储映射,正好就是位移次数  发表于 2012-5-19 01:13
你这个要比老罗那个简单的多,不过判断子集我的用子集 & 父集,结果如果是子集为真,否则为假。另外一个是,这里int只做存储,不涉及最高位符号   发表于 2012-5-19 01:11

评分

参与人数 1技术分 +4 收起 理由
贠(yun)靖 + 4

查看全部评分

回复 使用道具 举报
本帖最后由 刘蕴学 于 2012-5-19 02:16 编辑


  1. public class Test7
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 // & 按位与
  6.                 //看这行像什么,像逻辑运算符哪里我们写的吧
  7.                 //0为假,1为真,那么结论就是第四行为1
  8.                 //而在运算方面,我们可以根据这个规则进行
  9.                 //逐位运算,即同为1为1,否则为0
  10.                 System.out.println(0 & 0);
  11.                 System.out.println(0 & 1);
  12.                 System.out.println(1 & 0);
  13.                 System.out.println(1 & 1);
  14.                 System.out.println("======================================>");
  15.                 //可以明确的看到只有最后1位都为1吧,结果就是1
  16.                 System.out.println(getIntegerToBinary(3).substring(24));
  17.                 System.out.println(getIntegerToBinary(5).substring(24));
  18.                 System.out.println(getIntegerToBinary(3 & 5).substring(24));
  19.                 System.out.println("======================================>");
  20.                 //在观察这个我们发现一点有趣的现象?
  21.                 System.out.println(getIntegerToBinary(7).substring(24));
  22.                 System.out.println(getIntegerToBinary(5).substring(24));
  23.                 System.out.println(getIntegerToBinary(7 & 5).substring(24));
  24.                 System.out.println("======================================>");
  25.                 //一排1也就是-1 & 任何数,结果还是他自己
  26.                 //可以发现所有任意数为1的位都和-1中的该位
  27.                 //重合
  28.                 //可以把这个理解成数学中的求交集
  29.                 System.out.println(getIntegerToBinary(-1));
  30.                 System.out.println(getIntegerToBinary(1644687));
  31.                 System.out.println(getIntegerToBinary(-1 & 1644687));
  32.                 System.out.println("======================================>");
  33.                 //任何数和0 进行&操作都会得到0,这个操作经常用来清0
  34.                 //而在数学中,任何集合都不可能和一个空集产生交集
  35.                 System.out.println(getIntegerToBinary(0));
  36.                 System.out.println(getIntegerToBinary(1644687));
  37.                 System.out.println(getIntegerToBinary(0 & 0));
  38.                 System.out.println("======================================>");
  39.                 //这里可以看到,0x1f是前边我们讲的拿一个数最后5位,
  40.                 //而这个0xaaaaaaaa,最后五位01010,前边数据被抛弃
  41.                 //这里可以很简单的综合上边的结论,0x1f的5位前都是0吧?
  42.                 //任何数跟0 & 都是0,而后边是不是跟咱们的-1那个很像?
  43.                 //而这个数跟1排1 & 还是自己吧?
  44.                 //这个操作我们叫做取指定位
  45.                 System.out.println(getIntegerToBinary(0x1f));
  46.                 System.out.println(getIntegerToBinary(0xaaaaaaaa));
  47.                 System.out.println(getIntegerToBinary(0x1f & 0xaaaaaaaa));
  48.                 System.out.println("======================================>");
  49.                 //0xaaaaaaaa 中间的0不太好看拿了多少位,所以用-1
  50.                 System.out.println(getIntegerToBinary(0xffffffff));
  51.                 //取后四位
  52.                 System.out.println(getIntegerToBinary(0xf & 0xffffffff));
  53.                 //取前四位
  54.                 System.out.println(getIntegerToBinary(0xf0000000 & 0xffffffff));
  55.                 //同时取前四位和后四位,至于怎么玩,那是你自己的事情。
  56.                 //在这里我们用的是16进制,那么16进制表示的是4位2进制位
  57.                 //表示16进制的1位,所以我们只需要写8位。
  58.                 //如果觉得16进制的4位有点大,可以考虑用8进制,但是不好用
  59.                 //一般人都不认识,再说位不是整除的32/3你还少1位,蛋疼
  60.                 System.out.println(getIntegerToBinary(0xf000000f & 0xffffffff));
  61.                 System.out.println("======================================>");
  62.                
  63.                 // | 按位或
  64.                 //有一个为1,就为1,看着就懂,不多说
  65.                 //这个运算符可以当成数学中的求并集
  66.                 System.out.println(0 | 0);
  67.                 System.out.println(0 | 1);
  68.                 System.out.println(1 | 0);
  69.                 System.out.println(1 | 1);
  70.                 System.out.println("======================================>");
  71.                 //可以看到,结果是111,这就是 | 的用法,低3位都有1出现,所以是111
  72.                 System.out.println(getIntegerToBinary(3).substring(24));
  73.                 System.out.println(getIntegerToBinary(5).substring(24));
  74.                 System.out.println(getIntegerToBinary(3 | 5).substring(24));
  75.                 System.out.println("======================================>");
  76.                 //有趣的现象又来了,呵呵
  77.                 System.out.println(getIntegerToBinary(7).substring(24));
  78.                 System.out.println(getIntegerToBinary(5).substring(24));
  79.                 System.out.println(getIntegerToBinary(7 | 5).substring(24));
  80.                 System.out.println("======================================>");
  81.                 //-1 | 上任何数,结果还是-1,只能说-1这个集合里涵盖了你的任何组合
  82.                 System.out.println(getIntegerToBinary(-1));
  83.                 System.out.println(getIntegerToBinary(1644687));
  84.                 System.out.println(getIntegerToBinary(-1 | 1644687));
  85.                 System.out.println("======================================>");
  86.                 //0 | 上任何数,结果还是这个数,这个操作没什么太多实际意义
  87.                 //但如果是开发中,发现|操作的值没有改变,你首先应该想到|0了
  88.                 System.out.println(getIntegerToBinary(0));
  89.                 System.out.println(getIntegerToBinary(1644687));
  90.                 System.out.println(getIntegerToBinary(0 | 1644687));
  91.                 System.out.println("======================================>");
  92.                 //这个你会发现是往上填数据
  93.                 System.out.println(getIntegerToBinary(0));
  94.                 System.out.println(getIntegerToBinary(0xf));
  95.                 //低4位填1
  96.                 System.out.println(getIntegerToBinary(0 | 0xf));
  97.                 //高4位填1,这里没写0xf0000000,就是说一下这个数怎么来的
  98.                 System.out.println(getIntegerToBinary(0 | (0xf << 28)));
  99.                 //高低四位同时填1      0 | 0xf000000f是一样的
  100.                 System.out.println(getIntegerToBinary(0 | (0xf | (0xf << 28))));
  101.                 System.out.println("======================================>");
  102.                
  103.                 // ^ 按位异或
  104.                 //两位不一样为1,一样为假
  105.                 System.out.println(0 ^ 0);
  106.                 System.out.println(0 ^ 1);
  107.                 System.out.println(1 ^ 0);
  108.                 System.out.println(1 ^ 1);
  109.                 System.out.println("======================================>");
  110.                 //有效位的头两位都是不一样的吧,所以最后结果是110
  111.                 System.out.println(getIntegerToBinary(3).substring(24));
  112.                 System.out.println(getIntegerToBinary(5).substring(24));
  113.                 System.out.println(getIntegerToBinary(3 ^ 5).substring(24));
  114.                 System.out.println("======================================>");
  115.                 //这个更有趣,有什么发现?好好想想
  116.                 System.out.println(getIntegerToBinary(7).substring(24));
  117.                 System.out.println(getIntegerToBinary(5).substring(24));
  118.                 System.out.println(getIntegerToBinary(7 ^ 5).substring(24));
  119.                 System.out.println("======================================>");
  120.                 //这是神马?还没发现么?传说中的取反
  121.                 System.out.println(getIntegerToBinary(-1));
  122.                 System.out.println(getIntegerToBinary(1644687));
  123.                 System.out.println(getIntegerToBinary(-1 ^ 1644687));
  124.                 //有什么感想?呵呵
  125.                 System.out.println((-1 ^ 1644687) + 1);
  126.                 System.out.println("======================================>");
  127.                 //0 ^ 上任何数,结果还是这个数,这让我们想起来什么了呢?
  128.                 //跟按位或一样的是吧。
  129.                 System.out.println(getIntegerToBinary(0));
  130.                 System.out.println(getIntegerToBinary(1644687));
  131.                 System.out.println(getIntegerToBinary(0 ^ 1644687));
  132.                 System.out.println("======================================>");
  133.                 //按位异或的魅力不止于此,它可以实现局部取反
  134.                 System.out.println(getIntegerToBinary(0x6ffffff6));
  135.                 //低4位取反
  136.                 System.out.println(getIntegerToBinary(0x6ffffff6 ^ 0xf));
  137.                 //高4位取反
  138.                 System.out.println(getIntegerToBinary(0x6ffffff6 ^ 0xf0000000));
  139.                 //高低四位同时取反
  140.                 System.out.println(getIntegerToBinary(0x6ffffff6 ^ 0xf000000f));
  141.                 System.out.println("======================================>");
  142.                
  143.                 // ~ 取反运算符
  144.                 // 0变1 1变0
  145.                 //但跟 ^ 不一样,~是全取反,不能实现局部取反
  146.                 System.out.println(getIntegerToBinary(0));
  147.                 System.out.println(getIntegerToBinary(~0));
  148.                 System.out.println("======================================>");
  149.                 System.out.println(getIntegerToBinary(1));
  150.                 System.out.println(getIntegerToBinary(~1));
  151.                 System.out.println("======================================>");
  152.         }
  153.        
  154.         public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
  155.         public static final String getIntegerToBinary(int value)
  156.         {
  157.                 String binary = Integer.toBinaryString(value);
  158.                 int length = Integer.SIZE - binary.length();
  159.                 return DEFAULT_INT_ZERO.substring(0, length) + binary;
  160.         }
  161. }
复制代码

评分

参与人数 1黑马币 +30 收起 理由
贠(yun)靖 + 30

查看全部评分

回复 使用道具 举报


  1. public class Test8
  2. {
  3.         public static void main(String[] args)
  4.         {
  5. //                1.给定集合A{0,1,2.....30,31}
  6. //                2.给定集合B{5,6....10,11}
  7. //                3.求 A 和 B 的交集
  8. //                4.求 A 和 B 的并集
  9. //                5.求 B 相对于 A 的补集
  10. //                6.求 A 对 B 差集
  11. //                7.求给定集合 C{7,9} 是 A 和 B 哪个集合的子集,并实现任意集合子集的查询功能
  12. //                8.以上所有集合必须使用一个int表示而非数组,所有代码均以按位运算符进行
  13. //                9.使用查表法可以根据int表示的集合正确输出该集合所表示的数组。
  14. //                10.必须详细写出解题思路,实现方法。
  15.                
  16.                 //首先考虑,如何使用int来保存一个集合,貌似很难,我们都知道
  17.                 //int表示的是一个数,表示集合怎么表示?
  18.                 //先看集合A,0-31,是不是很眼熟?在哪里见过?这不就是int的位移区间么?
  19.                 //那么是不是可以这样,我们用一个数的位移次数来表示集合?关键是怎么在一个
  20.                 //数中表示这么多数的位移次数,而且还要保持这个数每一种位移次数的值不重复。
  21.                
  22.                 //注意我这里用的mask是java里常见的掩码,shift表示位移,以后看见源文件
  23.                 //中出现这些变量的名字就知道是做什么的了
  24.                
  25.                 //这里边打印了1的不同位移情况下的掩码,我们可以想想,如果我拿没一个掩码
  26.                 //表示一个数,是不是形成一种映射关系?类似map的key 和 value,那么这个
  27.                 //key是什么?其实key就是掩码,而这个value就是1到这个掩码的位移次数。
  28.                
  29.                 //看这个图是不是眼前一亮,其实跟之前的位移那个图差不多,一个是1,一个是-1
  30.                 int mask = 0;
  31.                 for (int shift = 0; shift < 32; shift++)
  32.         {
  33.                 System.out.println(getIntegerToBinary((mask = (1 << shift))));
  34.         }
  35.                 System.out.println("======================================>");
  36.                
  37.                 //下面做下尝试,比如我们自己做一个012的集合
  38.                 //这里我们得想下,一个空集,怎么往里边加数据?前边讲过| ^ + 都行吧,
  39.                 //其实还是 | 好一些,其他的在某些情况下会有点小问题
  40.                 int set = 0;
  41.                 set = set | 1 << 0;
  42.                 set = set | 1 << 1;
  43.                 set = set | 1 << 2;
  44.                 //这里发现我们成功了对么?我们可以用最低位表示这个集合中有0对吧
  45.                 //而顺序是什么呢?从右往左每一位为1表示有该位位移次数的这个数。
  46.                 //当然你如果喜欢从左往右也可以,呵呵,自己可以尝试一下
  47.                 System.out.println(getIntegerToBinary(set));
  48.                 System.out.println("======================================>");
  49.                
  50.                 //1第一点,我们就这么做出来了,B 和 C 的话如法炮制,由于题目里边都是连续的数
  51.                 //咱就可以投机取巧了
  52.                 int A = 0, B = 0, C = 0;
  53.                 for (int shift = 0; shift < Integer.SIZE; shift++)
  54.         {
  55.                         mask = 1 << shift;
  56.                         //注意这里我为什么要12在前,4在后
  57.                         if((shift < 12) && (shift > 4))
  58.                                 B |= mask;
  59.                         if((shift == 7) || (shift == 9))
  60.                                 C |= mask;
  61.                 A |= mask;
  62.         }
  63.                 System.out.println(getIntegerToBinary(A));
  64.                 System.out.println(getIntegerToBinary(B));
  65.                 System.out.println(getIntegerToBinary(C));
  66.                 System.out.println("======================================>");
  67.                
  68.                 //3,求 A 和 B 的交集,这个在Test7里边咱讲了交集用什么?
  69.                 System.out.println(getIntegerToBinary(A & B));
  70.                 System.out.println("======================================>");
  71.                
  72.                 //4,求 A 和 B 的并集
  73.                 System.out.println(getIntegerToBinary(A | B));
  74.                 System.out.println("======================================>");
  75.                
  76.                 //5,求 B 相对于 A 的补集
  77.                 //6, 跟 5 一样
  78.                 System.out.println(getIntegerToBinary(A ^ B));
  79.                 System.out.println("======================================>");
  80.                
  81.                 //7.求给定集合 C{7,9} 是 A 和 B 哪个集合的子集
  82.                 //这个检查很简单,先求交集,如果这个交集还是他
  83.                 //自己,那么就是这个集合的子集
  84.                 System.out.println((C & A) == C);
  85.                 System.out.println((C & B) == C);
  86.                 System.out.println("======================================>");
  87.                 System.out.println(isChid(C, A));
  88.                 System.out.println(isChid(C, B));
  89.                 System.out.println("======================================>");
  90.                
  91.                 System.out.print("A     ");printIntegerSet(A);
  92.                 System.out.print("B     ");printIntegerSet(B);
  93.                 System.out.print("C     ");printIntegerSet(C);
  94.                 System.out.print("A & B ");printIntegerSet(A & B);
  95.                 System.out.print("A | B ");printIntegerSet(A | B);
  96.                 System.out.print("A ^ B ");printIntegerSet(A ^ B);
  97.                 System.out.print("C & B ");printIntegerSet(C & B);
  98.                 System.out.print("C | B ");printIntegerSet(C | B);
  99.                 System.out.print("C ^ B ");printIntegerSet(C ^ B);
  100.         }
  101.        
  102.         public static final void printIntegerSet(int set)
  103.         {
  104.                 StringBuilder sb = new StringBuilder("Set{");
  105.                 int mask;
  106.                 for (int shift = 0; shift < Integer.SIZE; shift++)
  107.         {
  108.                 mask = 1 << shift;
  109.                 if(mask == (set & mask))
  110.                         sb.append(digits[shift] + ",");
  111.         }
  112.                 sb.deleteCharAt(sb.length() - 1);
  113.                 sb.append("}");
  114.                 System.out.println(sb.toString());
  115.         }
  116.        
  117.         public final static int[] digits;
  118.         static
  119.         {
  120.                 digits = new int[Integer.SIZE];
  121.                 for (int i = 0; i < digits.length; i++)
  122.         {
  123.                 digits[i] = i;
  124.         }
  125.         }
  126.        
  127.         /**
  128.          * 求前一个集合是不是后一个集合的子集
  129.          * @return true表示是,false表示不是
  130.          */
  131.         public static final boolean isChid(int arg0, int arg1)
  132.         {
  133.                 //子集判断的两种方法,其他位运算符一样可以
  134.                 //可以自己思考下如何实现
  135. //                return arg1 == (arg0 | arg1);
  136.                 return arg0 == (arg0 & arg1);
  137.         }
  138.        
  139.         public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
  140.         public static final String getIntegerToBinary(int value)
  141.         {
  142.                 String binary = Integer.toBinaryString(value);
  143.                 int length = Integer.SIZE - binary.length();
  144.                 return DEFAULT_INT_ZERO.substring(0, length) + binary;
  145.         }
  146. }
复制代码

评分

参与人数 1黑马币 +30 收起 理由
贠(yun)靖 + 30 给你点小费花花

查看全部评分

回复 使用道具 举报
  1. public class Test9
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 User user = new User();
  6.                 //这里我们给了用户两个权限,一个注册,一个登陆
  7.                 //01 | 10 结果是 11,这没什么好说的了,都讲过了
  8.                 user.setPermission(Permission.BBS_PERMISSION_REGISTER | Permission.BBS_PERMISSION_LOGIN);
  9.                 System.out.println(getIntegerToBinary(user.getPermission()));
  10.                 //这里修改了用户的权限,变成了登陆和退出
  11.                 user.setPermission(Permission.BBS_PERMISSION_LOGIN | Permission.BBS_PERMISSION_LOGOUT);
  12.                 System.out.println(getIntegerToBinary(user.getPermission()));
  13.                 //而这,我们给用户增加了一个包括登陆和评论的功能,
  14.                 //说是回复也行,都一样,但要注意,登陆前边咱已经
  15.                 //有了吧?这地方就是为什么用 | ,当然你用 & ^
  16.                 //也能行,不过你是不是得求一下补集或者差集呢? 
  17.                 user.addPermission(Permission.BBS_PERMISSION_LOGIN | Permission.BBS_PERMISSION_COMMENT);
  18.                 System.out.println(getIntegerToBinary(user.getPermission()));
  19.                 //删除这里比较有意思,其实就是求两个集合的并集
  20.                 //并从用户权限集合中把这个并集干掉,就哦拉。
  21.                 user.deletePermission(Permission.BBS_PERMISSION_LOGIN | Permission.BBS_PERMISSION_ACCESS);
  22.                 System.out.println(getIntegerToBinary(user.getPermission()));
  23.                 System.out.println("======================================>");
  24.                
  25.                 //这里边列出了查询中会碰到的一些情况,
  26.                 //也是用来测试这个功能是不是好用
  27.                 System.out.println(user.contains(Permission.BBS_PERMISSION_COMMENT));
  28.                 System.out.println(user.contains(Permission.BBS_PERMISSION_LOGOUT));
  29.                 System.out.println(user.contains(Permission.BBS_PERMISSION_COMMENT | Permission.BBS_PERMISSION_LOGOUT));
  30.                 System.out.println(user.contains(Permission.BBS_PERMISSION_ACCESS));
  31.                 System.out.println(user.contains(Permission.BBS_PERMISSION_LOGOUT | Permission.BBS_PERMISSION_ACCESS));
  32.                 System.out.println("======================================>");
  33.                
  34.                 //这个逐级审查其实有个小窍门,只要在找到这个掩码表示的权限之前
  35.                 //发现1个0,那肯定就是假,至于这个应用在什么地方,方法的注释上有
  36.                 user.setPermission(Permission.BBS_PERMISSION_REGISTER | Permission.BBS_PERMISSION_LOGIN | Permission.BBS_PERMISSION_COMMENT);
  37.                 System.out.println(getIntegerToBinary(user.getPermission()));
  38.                 System.out.println(user.containsBits(Permission.BBS_PERMISSION_COMMENT));
  39.                 System.out.println(user.containsBits(Permission.BBS_PERMISSION_LOGIN));
  40.                 System.out.println("======================================>");
  41.                
  42.                 user.setPermission(Permission.BBS_PERMISSION_REGISTER | Permission.BBS_PERMISSION_LOGIN | Permission.BBS_PERMISSION_COMMENT | Permission.BBS_PERMISSION_PUBLISH);
  43.                 System.out.println(getIntegerToBinary(user.getPermission()));
  44.                 System.out.println(user.containsBits(Permission.BBS_PERMISSION_COMMENT));
  45.                 System.out.println(user.containsBits(Permission.BBS_PERMISSION_LOGIN));
  46.                 System.out.println("======================================>");
  47.         }
  48.        
  49.         public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
  50.         public static final String getIntegerToBinary(int value)
  51.         {
  52.                 String binary = Integer.toBinaryString(value);
  53.                 int length = Integer.SIZE - binary.length();
  54.                 return DEFAULT_INT_ZERO.substring(0, length) + binary;
  55.         }
  56. }
  57. class User
  58. {
  59.         private int permission = 0;
  60.        
  61.     public void setPermission(int permission)
  62.     {
  63.             this.permission = permission;
  64.     }
  65.    
  66.     public int getPermission()
  67.     {
  68.             return this.permission;
  69.     }
  70.    
  71.     /**
  72.      * 检查用户是否具有指定的权限集合
  73.      * @param masks
  74.      * @return
  75.      */
  76.     public boolean contains(int masks)
  77.     {
  78. //            return (this.permission | masks) == this.permission;
  79.             return (this.permission & masks) == masks;
  80.     }
  81.    
  82.     /**
  83.      * 逐级审查
  84.      * 这个用在这里其实并不恰当,举个例子说下
  85.      * 比如说在10层楼里,很多重要地方都是有权限的吧
  86.      * 比如职员只能在1楼,经理可以去2楼,老总在顶楼之类的
  87.      * 那么也就是说我有2楼的权限是不是也能去1楼,老总的10层权限
  88.      * 哪层都可以吧?
  89.      *
  90.      * 另外一个是,这个函数的方法是不是最优的,其实还有简便写法
  91.      * 你可以自己尝试下。我现在这个写法仅是用来符合逻辑
  92.      *
  93.      * 从1楼到10检查,比如看你有没有3层的权限,是不是意味着,如果
  94.      * 你没有1楼的就直接不可能有3楼的权限,因为你连这个楼的大门都进不来吧?
  95.      * 换句话说你想到几楼去,这个楼层之前任何的一层楼你没有权限你都不能到这个楼去
  96.      *
  97.      * 虽然这个方法的局限性很大,但应用范围也很广
  98.      * @param mask
  99.      * @return
  100.      */
  101.     public boolean containsBits(int mask)
  102.     {
  103.             //这个0其实会略微影响效率,正常开发不会写这个
  104.             //因为0基本上不会有人传进来,这个看似是提高
  105.             //效率的办法其实是错的。
  106.             if(mask == 0)
  107.                     return false;
  108.             int tmp = 1;
  109.             while (true)
  110.         {
  111.                     if((tmp & this.permission) == tmp)
  112.                             //这个if千万不能合并到上边,否则必错
  113.                             //因为这里的else的作用域也被提升了
  114.                             if(tmp == mask)
  115.                                     return true;
  116.                             else
  117.                             {
  118.                                     //这里的两行不能写进下边的else里
  119.                                     tmp <<= 1;
  120.                                     continue;
  121.                             }
  122.                     else
  123.                             return false;
  124.             }
  125.     }
  126.    
  127.     /**
  128.      * 为用户添加权限
  129.      * @param masks 需要添加的权限集合
  130.      */
  131.     public void addPermission(int masks)
  132.     {
  133.             //这里为什么不用检测是否有某些权限?
  134.             this.permission |= masks;
  135.     }
  136.    
  137.     /**
  138.      * 为用户取消权限
  139.      * @param masks 需要取消的权限集合
  140.      */
  141.     public void deletePermission(int masks)
  142.     {
  143.             //这里主要分析的是,用户和你要删除的权限的交集
  144.             //用户没有的没必要进行操作
  145.             this.permission ^= (this.permission & masks);
  146.     }
  147. }
  148. //这里的接口是用来封装掩码集的,其实这在java里很常见
  149. //接口并不意味着必须要有功能抽象
  150. interface Permission
  151. {
  152.         public static final int BBS_PERMISSION_REGISTER = 1;
  153.         public static final int BBS_PERMISSION_LOGIN = 2;
  154.         public static final int BBS_PERMISSION_PUBLISH = 4;
  155.         public static final int BBS_PERMISSION_COMMENT = 8;
  156.         public static final int BBS_PERMISSION_ACCESS = 16;
  157.         public static final int BBS_PERMISSION_LOGOUT = 32;
  158. }
复制代码

评分

参与人数 1黑马币 +30 收起 理由
贠(yun)靖 + 30 给你点小费花花

查看全部评分

回复 使用道具 举报
自己试着弄了一下,呵呵感觉不错,但是结果不一样呀。期待楼主跟多技术

点评

有什么问题你可以跟帖,我们都会帮忙的  发表于 2012-5-19 13:23
回复 使用道具 举报
嘿嘿!根据第二题的思路想了下,一下是代码:
  1. public class Test12{
  2.        
  3.         //1个int字节全部用来存储,最多用来存32个数
  4.         //那么可以提取出其中的3位用来做标识位,那么就最多可以存储 2*2*2 * 29 = 232个数字
  5.         //这样就完全可以容纳174个数字的集合
  6.         public static void main(String[] args){
  7.                 int A = 0 ;
  8.                 int mask = 0 ;
  9.                 int sign = 5;                                //这里只需要调出3位就可以标识,故只需要000 到101 就可以,故最大极限为5
  10.                
  11.                 for(int shift = 3 ; shift < Integer.SIZE ; shift ++){
  12.                         mask |= 1 << shift;       
  13.                         }
  14.                 A = mask | sign ;
  15.                 System.out.println(getIntegerToBinary(A));
  16.                 System.out.print("A  :");printIntegerSet(A,sign);
  17.         }

  18.          public static final void printIntegerSet(int set,int  sign)
  19.      {
  20.         StringBuilder sb = new StringBuilder("Set{");
  21.         int mask;
  22.                 for(int i = 0 ; i <= sign ; i ++){
  23.         for (int shift = 3; shift < Integer.SIZE; shift++){
  24.              mask = 1 << shift;
  25.              if(mask == (set & mask))
  26.                                  sb.append(digits[shift-3] + i*29 + ",");
  27.                          }
  28.                          sb.deleteCharAt(sb.length() - 1);
  29.                          
  30.         } sb.append("}");System.out.println(sb.toString());
  31.          }
  32.          //取出三位用来做标识位那么就只剩下29位.
  33.         public final static int[] digits;
  34.         static
  35.         {
  36.                 digits = new int[29];
  37.                 for (int i = 0; i < 29; i++)
  38.                                 {
  39.                 digits[i] = i;
  40.                                 }
  41.         }
  42.         public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
  43.         public static final String getIntegerToBinary(int value)
  44.         {
  45.                 String binary = Integer.toBinaryString(value);
  46.                 int length = Integer.SIZE - binary.length();
  47.                 return DEFAULT_INT_ZERO.substring(0, length) + binary;
  48.         }
  49. }
复制代码

点评

昨天我就说了,哈哈,中国砖家为什么坑爹,我这第三题典型的例子,实际上连续的集合你只需要记录起始和结束就可以了  发表于 2012-5-20 08:38

评分

参与人数 1技术分 +2 收起 理由
贠(yun)靖 + 2

查看全部评分

回复 使用道具 举报
用1个int类型存放128个数 我觉得是不可行的。。。
当你用个int类型的3位当标志位时  如标志为001存放1-29 010存放30-58    那么存放{1--32}时  存放1-29把1和4-32位填充了1  这时你存放30-32时  应该是把标志位2和数据位4-5填充为1把?4和5也已经填充为1了 填不填充没区别 那么我想问下 当你取出来时标志位为001你取出了1-29 标志位为010时你取出的应该是30-58把 然而并没有存放33-58啊  而且当你在容器里删除1 的话 就不说该不该把标志位填充为0  当你把4位清空为0时  当其他标志位地4位有数据时是不是也意味着把该标志位的地4位也清空为0了
回复 使用道具 举报
第一题第一个反应是
for(int i =1;i<=31;i++)
{        System.out.print(Integer.toBinaryString(-1<<i));
        System.out.print(" ? ");
        System.out.print(Integer.toBinaryString(~(-1<<i)));
        System.out.print(" = ");
        System.out.println(Integer.toBinaryString(-1));
}
打印出来类似 11111111111111110 ? 1 = 111111111111111
后来用个subString(00000000000)可以做,不过看到13楼的解法类似,回个帖看第二题了,先不看答案试试。
回复 使用道具 举报
12
您需要登录后才可以回帖 登录 | 加入黑马