long类型代码转BitSet实现:位运算含义与add方法问题求解
问题解答
一、原代码位运算含义解释
原代码是为孔明棋(Peg Solitaire)生成同一直线三个连续点位的两种合法跳步,每个long[]数组固定长度为3,三个元素的含义对应跳步规则的三个掩码,按位或|的作用就是同时将多个指定位置为1:
- 第一种跳步:棋子从
bit3位跳过中间bit2位落到bit1位,对应数组三个元素:- 第一个元素
1L << bit1:落子后需要置为1的点位(bit1) - 第二个元素
(1L << bit2) | (1L << bit3):落子后需要清为0的点位(被跳过的bit2、原起跳位bit3) - 第三个元素
三个位的或:用于校验跳步合法性的掩码,判断前置状态是否满足bit3、bit2有棋子,bit1无棋子
- 第一个元素
- 第二种跳步:棋子从
bit1位跳过中间bit2位落到bit3位,对应第二个add的数组元素,逻辑和上面对称。
你理解的没错,按位或对应BitSet的操作就是对多个点位依次调用set()方法即可。
二、add方法报错原因及解决方案
你不需要改成嵌套ArrayList,报错的原因是:
你的moves参数定义是ArrayList<BitSet[]>,也就是列表的每个元素是长度为3的BitSet数组,而List.add()方法一次只能接收一个元素,你直接传三个BitSet对象当然不符合参数要求,只要把三个BitSet拼成数组再传入add即可。
另外需要注意BitSet是可变对象,不要重复使用同一个BitSet实例修改后多次添加,会导致之前添加的内容被覆盖,每次生成跳步都要新建对应的BitSet实例。
三、正确转换后的代码
private static void createMoves(int bit1, int bit2, int bit3, ArrayList<BitSet[]> moves) { // 生成第一种跳步的三个BitSet BitSet set1 = new BitSet(100); set1.set(bit1); BitSet clear1 = new BitSet(100); clear1.set(bit2); clear1.set(bit3); BitSet check1 = new BitSet(100); check1.set(bit1); check1.set(bit2); check1.set(bit3); // 拼成数组加入列表 moves.add(new BitSet[]{set1, clear1, check1}); // 生成第二种跳步的三个BitSet BitSet set2 = new BitSet(100); set2.set(bit3); BitSet clear2 = new BitSet(100); clear2.set(bit1); clear2.set(bit2); BitSet check2 = new BitSet(100); check2.set(bit1); check2.set(bit2); check2.set(bit3); // 拼成数组加入列表 moves.add(new BitSet[]{set2, clear2, check2}); }
内容的提问来源于stack exchange,提问作者pileup
相关产品推荐
相关产品推荐

