对整数数组的Java操作

时间:2018-06-10 23:41:30

标签: java arrays boolean xor nim-game

我考虑使用Java中的整数数组。数组大小由用户在程序开始时确定

我的想法是 - 给定相应二进制值的任何位置 - 结果应该对任何位显示1,其中只有一个操作数具有1和0用于任何其他组合。通过以下示例可以更好地解释该过程

{4,5,6}这样的数组应该返回3,因为:

  100
  101
  110
  ---
= 011

OR为数字{12,4,9}

12 = 1100
 4 = 0100
 9 = 1001
---------
Val- 0001

我想过这样做,但我意识到 - 因为我使用XOR - 我的第一个例子的代码将返回7:

static void cpuTurn(int[] nimArray){
    int[] val = new int[nimArray.length];
    int holding = 0;

    for (int i = 0; i < nimArray.length; i++) {
        holding = holding^nimArray[i];
    }
}

如何正确实施此操作?

3 个答案:

答案 0 :(得分:2)

可能有一种更聪明的方法,但你可以通过选择只在数组中出现一次并将它们“或”在一起的位来迭代地解决它。以下是使用流来实现此目的的方法:

IntStream.range(0, 32)
        .map(i -> 1 << i)
        .filter(i -> Arrays.stream(array).filter(n -> (n & i) != 0).count() == 1)
        .reduce(0, (a, b) -> a | b)

Ideone Demo

答案 1 :(得分:0)

了解这种方式:

holding = 0
at 4:
holding = holding ^ 4; // 0 ^ 4 = 4 i.e. holding = 4, binary => 0 ^ 100 = 100  
at 5:
holding = holding ^ 5; // 4 ^ 5 = 1 i.e. holding = 1, binary => 100 ^ 101 = 1 
at 6:
holding = holding ^ 6; // 1 ^ 6 = 7 i.e. holding = 7, binary => 1 ^ 110 = 111 

因此持有的最终价值为7。

如果要将两个以上的1个外观设置为0

    public static int[] split(int num){
        int[] splits = new int[31]; 
        for(int i=0; i < 31; ++i){
            splits[i] = (num>>i & 1);
        }
        return splits;
    }

    static void cpuTurn(int[] nimArray){
        int[] val = new int[nimArray.length];
        int holding = 0;
        int [] holdings = split(holding);
        for (int i = 0; i < nimArray.length; i++) {
            int [] splits = split(nimArray[i]);
            for(int j = 0; j < splits.length; ++j)
                 holdings[j]+=splits[j]
        }

        int [] newVal = new int[31];
        int k =0;
        for(k = 0; k < 31; ++k)
            if(holdings[k]>1 || holdings[k]==0)
                newVal[k] = 0;
            else
                newVal[k] = 1;

        int finalValue = 0;
        for(k = 0; k < 31; ++k)
             finalValue |= newVal[k]<<k;

        System.out.println(finalValue);

    }

答案 2 :(得分:0)

我认为你可以通过跟踪哪些比特不唯一来相当简单地做到这一点。

static int xor(int[] arr) {
    int all = 0;
    int dup = 0;

    for (int x : arr) {
        // for each x in arr, record the bits which are
        // in common with the bits we've already seen
        dup |= x & all;
        all |= x;
    }

    // remove bits which were not unique
    return all & ~dup;
}

考虑这是如何工作的,你可以说变量all为每个位保留一个计数器,但我们只能计数到1.当我们x & all时,我们每个位得到1我们在x中再次看到 plus 一次,实际上让我们数到2. dup然后跟踪我们不止一次看到的每一位

最后我们只做all & ~dup,它会删除我们多次看到的任何位。