简体   繁体   English

用非常大的数组计算幂集,Java?‽

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM