我正在执行以下编程练习:Counting power sets。该语句是:


  在此kata中,您必须创建一个函数powers / Powers,该函数需要一个
  数组,并返回可以从中创建的子集数
  清单。换句话说,计算功率集。
  
  例如
  
  powers([1,2,3])=> 8
  
  ...由于...
  
  powers([1,2,3])=> [[],1,[2],[3],[1,2],[2,3],[1,3],
  [1,2,3]
  
  您的函数应该能够计数最多500个的设置,因此
  小心;那里有很大的数字!
  
  为了进行比较,我的Haskell解决方案可以计算出
  不到一秒钟的长度为90 000的数组,所以要快!
  
  您应该为此将传递的每个数组视为一组唯一值
  kata。
  
  例子:
  
  Powers.powers(new int [] {}); // 1 Powers.powers(new int [] {1});
  // 2 Powers.powers(new int [] {1,2}); // 4 Powers.powers(新
  int [] {1,2,3,4}); // 16


我写了以下答案:

import java.math.BigInteger;
import java.util.*;
public class Powers {
  public static BigInteger powers/*🔋*/(int[] list) {
    System.out.println("list: "+Arrays.toString(list));
    System.out.println("list length: "+list.length);
    double pow = Math.pow(2, list.length);
    System.out.println("pow: "+pow);
    return new BigInteger(String.valueOf((long)pow));
  }
}


但是,对于100个数组,它不会输出预期的结果。例如,对于以下数组:

list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
list length: 100


它输出:

9223372036854775807


代替:

1267650600228229401496703205376


我认为困难是由于将pow结果从double转换为long而产生的,因为它的输出是:

pow: 1.2676506002282294E30


然后,我尝试使用modPow来获得更大数字的结果:

import java.math.*;
import java.util.*;
public class Powers {
  public static BigInteger powers/*🔋*/(int[] list) {
    System.out.println("list: "+Arrays.toString(list));
    System.out.println("list length: "+list.length);
    BigInteger pow = BigInteger.valueOf(2).modPow(BigInteger.valueOf(list.length), BigInteger.valueOf(Long.MAX_VALUE));
    System.out.println("pow: "+pow);
    return new BigInteger(String.valueOf(pow));
  }
}


但是,当我们使用100个长度的数组进行测试时,输出为:

137438953472


什么时候应该是:

1267650600228229401496703205376


我认为挑战在于Long.MAX_VALUE等于modPow计算的最大值,因为它输出:

pow: 137438953472


之后,我尝试在modPow函数中为模数编写一个更大的数字,并写成这样:

import java.math.*;
import java.util.*;
public class Powers {
  public static BigInteger powers/*🔋*/(int[] list) {
    System.out.println("list: "+Arrays.toString(list));
    System.out.println("list length: "+list.length);
    BigInteger modulus = BigDecimal.valueOf(Double.POSITIVE_INFINITY).toBigInteger();
    BigInteger pow = BigInteger.valueOf(2).modPow(BigInteger.valueOf(list.length), modulus);
    System.out.println("pow: "+pow);
    return new BigInteger(String.valueOf(pow));
  }
}


但是,将引发以下异常:

java.lang.NumberFormatException: Character I is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:518)
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:401)
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:834)
    at java.base/java.math.BigDecimal.valueOf(BigDecimal.java:1304)
    at Powers.powers(Powers.java:7)


我认为它是由Double.POSITIVE_INFINITY生成的,而不是BigInteger所代表的最高数字。

因此,前两个代码可以通过以下测试:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.Ignore;
import java.math.BigInteger;

public class PowersTest {

  @Test
  public void testPactical() {
    assertEquals("An empty array should return 1!", Powers.powers(new int[]{}), BigInteger.valueOf(1));
    assertEquals(Powers.powers(new int[]{1}), BigInteger.valueOf(2));
    assertEquals(Powers.powers(new int[]{1,2,3,4,5}), BigInteger.valueOf(32));
  }

}


但是,这两个代码都很难通过100长度数组测试。

另外我读过:


BigInteger.pow(BigInteger)?
https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#modPow(java.math.BigInteger,%20java.math.BigInteger)
https://www.tutorialspoint.com/java/math/biginteger_modpow.htm
What does BigInteger having no limit mean?
How to implement infinity in Java?


您能帮我找出如何用Java中的超大数组对幂集进行计数吗?‽

编辑:

解决方法是:

import java.math.*;
import java.util.*;
public class Powers {
  public static BigInteger powers/*🔋*/(int[] list) {
    return BigInteger.valueOf(2).pow(list.length);
  }
}

最佳答案

嗯...我检查了一下,我认为这可行:

public static BigInteger powers(int[] list) {
    return BigInteger.valueOf(2).pow(list.length);
  }

07-26 08:54