[英]Counting power sets with very large arrays, Java?‽
I am doing the following programming exercise: Counting power sets .我正在做以下编程练习: Counting power sets 。 The statement is:声明是:
In this kata, you must create a function powers/Powers that takes an array, and returns the number of subsets possible to create from that list.在这个 kata 中,您必须创建一个函数 powers/Powers,它接受一个数组,并返回可以从该列表创建的子集数。 In other words, counts the power sets.换句话说,计算幂集。
For instance例如
powers([1,2,3]) => 8幂([1,2,3]) => 8
...due to... ...由于...
powers([1,2,3]) => [[], 1 , [2], [3], [1,2], [2,3], [1,3], [1,2,3]] powers([1,2,3]) => [[], 1 , [2], [3], [1,2], [2,3], [1,3], [1,2,3 ]]
Your function should be able to count sets up to the size of 500, so watch out;您的函数应该能够计算最大为 500 的集合,因此请注意; pretty big numbers occur there!相当大的数字出现在那里!
For comparison, my Haskell solution can compute the number of sets for an array of length 90 000 in less than a second, so be quick!为了进行比较,我的 Haskell 解决方案可以在不到一秒的时间内计算长度为 90 000 的数组的集合数,所以要快!
You should treat each array passed as a set of unique values for this kata.您应该将传递的每个数组视为此 kata 的一组唯一值。
Examples:例子:
Powers.powers(new int[]{}); Powers.powers(new int[]{}); // 1 Powers.powers(new int[]{1}); // 1 Powers.powers(new int[]{1});
// 2 Powers.powers(new int[]{1,2}); // 2 Powers.powers(new int[]{1,2}); // 4 Powers.powers(new int[]{1,2,3,4}); // 4 Powers.powers(new int[]{1,2,3,4}); // 16 // 16
I have written the following answer:我写了以下答案:
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));
}
}
However for a 100 array it does not output the expected result.但是,对于 100 数组,它不会输出预期的结果。 For example, for the following array:例如,对于以下数组:
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
It outputs:它输出:
9223372036854775807
Instead of:代替:
1267650600228229401496703205376
I thought the difficulty was generated by rounnding the pow result from double to long, because of it outputs:我认为困难是通过将 pow 结果从 double 舍入到 long 产生的,因为它输出:
pow: 1.2676506002282294E30
Then I tried to use modPow to be able to get results with bigger numbers:然后我尝试使用 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));
}
}
However when we test with the 100 length array, the output is:但是,当我们使用 100 长度数组进行测试时,输出为:
137438953472
When it should be:什么时候应该:
1267650600228229401496703205376
I think the challenge is due to Long.MAX_VALUE is equal than the highest value being calculated by modPow, because of it outputs:我认为挑战是由于 Long.MAX_VALUE 等于 modPow 计算的最高值,因为它输出:
pow: 137438953472
After that I tried to write a higher number for modulus inside modPow function and I wrote this:之后,我尝试在 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));
}
}
However the following exception is being thrown:但是,正在抛出以下异常:
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)
I think it is generated because of Double.POSITIVE_INFINITY gives us a bigger number than the highest being represented by BigInteger.我认为它是因为 Double.POSITIVE_INFINITY 给我们一个比 BigInteger 表示的最高数字更大的数字而产生的。
So as a result, the first two codes could pass the following tests:因此,前两个代码可以通过以下测试:
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));
}
}
However both codes, have difficulties to pass the 100 length array test.然而,这两种代码都难以通过 100 长度的数组测试。
In addition I have read:此外,我已阅读:
Could you help me to find out how to count power sets with very large arrays in Java?‽你能帮我找出如何计算 Java 中非常大的数组的幂集吗?‽
EDIT:编辑:
It is solved by writting:它是通过写来解决的:
import java.math.*;
import java.util.*;
public class Powers {
public static BigInteger powers/*🔋*/(int[] list) {
return BigInteger.valueOf(2).pow(list.length);
}
}
Um... I checked and I think this works:嗯......我检查过,我认为这有效:
public static BigInteger powers(int[] list) {
return BigInteger.valueOf(2).pow(list.length);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.