Java 和其他语言在生成子序列时的输出差异

Difference in Output in Java and other Languages in generating subsequences

更新:我的问题是为什么我们在 Java 中需要 BigInteger。为什么我们不能直接在伪代码上解决问题,因为它适用于所有其他语言。

这是生成数组子序列的伪代码。

int[] arr = {1,2,3} ;

int opsize = 2^size_of_array ;   

for (int counter = 1; counter < opsize; counter++)
{
    for (int j = 0; j < n; j++)
    {
        if (counter & (1<<j))
            print(arr[j] + " ");
    }
    print new line ;
}

它适用于除 Java 以外的所有语言。在所有其他语言中,输出是

1 
2 
1 2 
3
1 3 
2 3
1 2 3 

在Java中,代码为

class Solution
{
public static void main (String[] args) throws java.lang.Exception
    {
        int[] arr = {1,2,3};
        int n = arr.length ; ;
        int res = (int) Math.pow(2,n);
        for(int i = 1 ; i < res ; i++)
        {
            for(int j = 0 ; j  < n ; j++)
                if ((i & (1<<j)) == 1 )
                    System.out.print(arr[j] + " ");
            System.out.println();
        }
    }
}

在Java中,相同代码的输出是

1 

1 

1 

1 

在Java中,我们需要BigInteger来解决同样的问题

int opsize = (int)Math.pow(2, n);

    for (int counter = 1; counter < opsize; counter++)
    {
        for (int j = 0; j < n; j++)
        {
            if (BigInteger.valueOf(counter).testBit(j))
                System.out.print(arr[j]+" ");
        }
        System.out.println();
    }

编辑:我读错了问题。

没有BigInteger的代码有问题:

if ((i & (1<<j)) == 1 )

在位移中,你移动了j。这仅在 j = 0 且 i 设置了第一位时才成立。

假设我们有:

i=5
j=2

然后我们进行位移并具有以下二进制表示:

i = 0101
j = 0100

AND 运算后我们有:

0100

这显然不满足条件。

如果将其更改为:

if ((i & (1<<j)) > 0 )

有效,因为如果设置了 1 << j 定义的特定位,则答案 > 0。

编辑:删除了未回答问题的原始答案。

这是有问题的代码行:

if ((i & (1<<j)) == 1 )

这与 C 中的 if (counter & (1<<j)) 不同 - 在 C 中,如果整数的值为 非零 ,则整数等同于 "true" 条件.

要更正此问题,您应该这样写:

if ((i & (1<<j)) != 0)

更改之后,输出就是您所期望的。

你的状态不好: (i & (1<<j)) == 1

应该是 (i & (1<<j)) != 0

一个例子,对于i=6=0b0110j=1=0b0001

1<<j == 2 == 0b0010
i & (1<<j) == 0b0110 & 0b0010 == 0b0010 == 2