-2

I'm writing a program for my competitive programming class's homework and I can't get over one problem. This problem requires you to calculate all permutations of a certain string based on certain condition and my program does that. However, the problem is when the input is a really large string, it can be up to 10^6.

Solution to the problem is 2^result, where result depends on length of input string, so for 10^6 it can be up to 5*10^5. Solution must be given in form of: result % (10^9 + 7).

I've tried putting solution into a BigInteger, it runs out of heap space. I've tried working with doubles, it overflows. Is there something I'm missing or is there a way to deal with this? Thank you.

Here are some attempts:

System.out.println((int) (Math.pow(2, counter) % (1e9 + 7)));
//it prints out 0, probably due to overflow?

DecimalFormat df = new DecimalFormat("#");
System.out.println(df.format(Math.pow(2, counter) % (1e9 + 7)));
//prints out �
leonz
  • 1,107
  • 2
  • 10
  • 32
  • Have you looked at [BigDecimal](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html)? – DaoWen Nov 06 '16 at 16:39
  • I've tried BigInteger, it runs out of heap space. Haven't tried BigDecimal, will try it now, thanks. – leonz Nov 06 '16 at 16:39
  • 3
    Your homework is to implement [modular exponentiation](https://en.wikipedia.org/wiki/Modular_exponentiation). BigInteger already implements it as [modPow](https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#modPow(java.math.BigInteger,%20java.math.BigInteger)). You're not supposed to fully calculate the exponent, and then take the remainder. – that other guy Nov 06 '16 at 16:41
  • I can't fully understand your question, because I can't tell when you're talking about a value, vs. when you're talking about the size of a value. For example: when you say the solution can be up to 5*10^5 -- that's actually not a very big number (it's just 500,000). Do you really mean that the solution can have up to 5*10^5 *digits*? (And, so on elsewhere in your question.) – ruakh Nov 06 '16 at 16:41
  • @thatotherguy thanks a lot, it's exactly what I've been looking for. Never heard of modular exponentation before, I've implemented now and it's working. You can post your comment as an answer and I will accept it. – leonz Nov 06 '16 at 16:54

1 Answers1

4

You don't need to handle enormously large numbers to do this.

The assignment intends for you to implement modular exponentiation. BigInteger already implements it as modPow. It allows you to calculate (b^e) % c without having to deal with numbers significantly larger than c.

Here's Wikipedia's pseudo-code for remainder after exponentiation through repeated squaring:

function modular_pow(base, exponent, modulus)
    if modulus = 1 then return 0
    Assert :: (modulus - 1) * (modulus - 1) does not overflow base
    result := 1
    base := base mod modulus
    while exponent > 0
        if (exponent mod 2 == 1):
           result := (result * base) mod modulus
        exponent := exponent >> 1
        base := (base * base) mod modulus
    return result
that other guy
  • 116,971
  • 11
  • 170
  • 194