I'm trying to read a very large input as String and then converting it into long as per follows:[The program works for short input]
The input is two int separated by a space, example: "1248614876148768372675689568324619856329856295619253291561358926935829358293587932857923857934572895729511 413241"
My Code:
import java.io.*;
import java.math.*;
import java.util.*;
public class Solution {
public static void main(String args[] ) throws Exception {
Solution obj = new Solution();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
String input[]=new String[T];
for (int i=0;i<T;i++) {
input[i] = br.readLine();
}
for (int i=0;i<T;i++){
StringTokenizer st = new StringTokenizer(input[i]," ");
BigInteger N = new BigInteger(st.nextToken());
BigInteger P = new BigInteger(st.nextToken());
System.out.println(obj.result(N,P));
}
}
}
public BigInteger result(BigInteger N, BigInteger P){
BigInteger temp=1;
BigInteger c=0;
for (BigInteger i=0;i<=N;i++){
//System.out.println(nck(N,i));
if ((nck(N,i)%P) ==0)
c++;
}
return c;
}
public BigInteger nck(BigInteger N, BigInteger k){
if (k==0)
return 1;
else {
BigInteger temp=1;
BigInteger y=1;
BigInteger z=N;
while(k>=1){
temp=temp*z/y;
y++;
z--;
k--;
}
return temp;
}
}
}
I'm getting a java.lang.NumberFormatException
You can't parse this string into a long, it's too great (greater than Long.MAX_VALUE), you need BigInteger :
BigInteger bi = new BigInteger(st.nextToken());
Following your edit :
Don't try to iterate over a bigInteger : if it's too great to fit in a long, the loop will be too long for your time. Compare it with a reasonable limit and if it's smaller, then get it as int and enter your loop:
BigInteger MAX = new BigInteger("1000000");
if (bi.compareTo(MAX)<0) {
int N = bi.intValue();
for (int i=0; i<N; i++) {
Test...
}
}
If throws NumberFormatException because 248614876148768372675689568324619856329856295619253291561358926935829358293587932857923857934572895729511 is greater than Long.MAX_VALUE (which is 9223372036854775807).
As pointed out by others the valuse is too big for long However another problem is that there can be no spaces in the string which is being converted. There is a handy post on removeing white space from a string here
"The sequence of characters following an (optional) negative sign and/or radix specifier ("0x", "0X", "#", or leading zero) is parsed as by the Long.parseLong method with the indicated radix (10, 16, or 8). This sequence of characters must represent a positive value or a NumberFormatException will be thrown. The result is negated if first character of the specified String is the minus sign. No whitespace characters are permitted in the String." From the Docs
The value is too big for a long to hold. Primitive Data Types
I wonder what you are trying to do with so big integer but what you might be looking for is a BigInteger.
Immutable arbitrary-precision integers. All operations behave as if BigIntegers were represented in two's-complement notation (like Java's primitive integer types). BigInteger provides analogues to all of Java's primitive integer operators, and all relevant methods from java.lang.Math. Additionally, BigInteger provides operations for modular arithmetic, GCD calculation, primality testing, prime generation, bit manipulation, and a few other miscellaneous operations.
It provides methods for mathematical operations. Should also note that since it's immutable, any operation you perform on a BigInteger returns a new BigInteger.
Remember that when changing from type int to BigInteger you are then dealing with an object rather than a primitive. The BigInteger (String val) is probably the most useful constructor.
(i.e.) BigInteger temp = new BigInteger("1");
Related
I want to count set bits of binary number of any given number.
But the range of given number can vary to 10^200.
I tried using BigInteger and converted bigInteger to binary string using num.toString(2);
But maximum range of string is 2^31.
Any idea what else I can use here.
A BigInteger can be converted to a byte[] using BigInteger.toByteArray(). You can then iterate over the byte[] and count the set bits in each byte using code found here:
https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
Note that int can be replaced with byte in that example.
There's bitCount() method you can use for that:
// So, we create a big number
BigInteger num = new BigInteger("10");
num = num.pow(200);
System.out.println(num.bitCount());
Just for fun, you can test that it gives you the correct number:
String binaryNum = num.toString(2);
System.out.println(binaryNum);
System.out.println(binaryNum.chars().filter(c -> c == '1').count());
The maximum range of a String in Java is 2^31 - 1 is true but it's not about the Maximum value of a number it can hold, it is about the Number of characters it can contain.
That said, you don't need BigInteger to find the number of set bits in a number (Even for a large number), just remember the way to find Binary representation of a number.
Ex:
2|12|0
2| 6|0
2| 3|1
2| 1|-
So from the above, we know that the binary representation of 12 is 1100.
We can easily calculate the number of set bits if know the binary representation of a number.
Coming to the problem, you know that you can't handle that big into a number, so use a string to store the number and perform the above method.
To divide a number that is stored in a string start dividing the part of the number from the start,i.e., the most significant digit of the decimal number.
Check whether it propagates a carry to the right, you can do this by a simple &1 which tells about the LSB of those digits.
Finally, count the number of set bits with b.
public class Expelliarmus{
public static void main(String[] args) {
String a = "9000000000000000000000000000000000000000000000000000000000000000000000000000000000000";//88 zeroes, you can test it for other numbers too
System.out.println(fn(a,0L));
}
static long fn(String a, long b){ // Don't ask why I used long here
if(a.length()==0) return b;
if(a.length()==1 && a.charAt(0)=='1') return ++b;
int n = Integer.parseInt(a.charAt(a.length()-1)+"");
if((n&1)==1) ++b;
a = divideMe(a);
return fn(a,b);
}
static String divideMe(String a){
int val = 0;
String bb = "";
for(int i=0;i<a.length();i++){
int dup = 0;
val = val*10 + Integer.parseInt(a.charAt(i)+"");
if((val&1)==1) dup = 1;
val = val/2;
bb = bb + String.valueOf(val);
val = dup;
}
if(bb.charAt(0)=='0') return bb.substring(1);
return bb;
}
}
I know there is quite all of posts for converting characters to integers, strings to BigInteger-s, int-s to BigInteger-s, ... but I just can't figure out why this does not work.
Scanner sc = new Scanner(System.in);
BigInteger sum = 0;
String line = "";
while (sc.hasNext()) {
line = sc.next();
for (char character: vrstica.toCharArray()) {
sum = sum.add(BigInteger.valueOf(Character.getNumericValue(character)));
}
}
I do have Scanner and BigInteger imported. The input data is constructed of lines with numbers, like this: 7218904932283439201\n7218904932283439201 ...
If I understand correctly, addition for BigInteger-s should be written like this: bigInteger1.add(bigInteger2), where both numbers are of type BigInteger. So I should convert that character of type char to type int and then convert that int value to BigInteger with method BigInteger.valueOf(), which takes an int argument.
The error I am getting is the following: incompatible types: int cannot be converted to BigInteger
I am not seeing where I could be wrong so I would appreciate if anyone could point out my mistake.
You're trying to assign an int literal to a BigInteger object.
BigInteger sum = 0;
Use instead the following
BigInteger sum = BigInteger.ZERO;
I am trying to find the sum of the digits of the number 2^1000 and I am using Java BigInteger class for this. However, I could not make it real. Eventually, I get a 0 (zero) with the following code. What might be the problem?
Thanks...
After Kon's help I fixed the problem, but this time I get a wrong result. Can anyone see the problem with the algorithm?
public static void main(String []args) throws Exception
{
BigInteger big = BigInteger.valueOf(2).pow(1000);
BigInteger big2 = BigInteger.valueOf(0);
//System.out.println(big);
for(long i = 1; i<283; i++)
{
big2 = big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));
}
System.out.println(big2);
}
Trying to calculate each digit of BigInteger using mod is not very efficient, because of many method calls you are doing in the process. Instead you can simplify by doing the conversion to String and getting each digit straight away.
BigInteger big = BigInteger.valueOf(2).pow(1000);
String digits = big.toString();
int sum = 0;
for(int i = 0; i < digits.length(); i++) {
int digit = (int) (digits.charAt(i) - '0');
sum = sum + digit;
}
System.out.println(sum);
The BigInteger class is immutable, therefore you have to assign the result of the operation to the variable itself.
big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));
should become
big2 = big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));
For more on immutable objects in Java, please take a look at this documentation.
Also, although your question is not specifically about this, using hard coded literal values in your loops is very bad practice. You want to loop over each digit in the BigInteger 2^1000. Well, you could get the number of digits using something like big.toString().length().
I'm making a program that turns a large number into a string, and then adds the characters of that string up. It works fine, my only problem is that instead of having it as a normal number, Java converts my number into standard form, which makes it hard to parse the string. Are there any solutions to this?
public static void main(String ags[]) {
long nq = (long) Math.pow(2l, 1000l);
long result = 0;
String tempQuestion = Double.toString(nq);
System.out.println(tempQuestion);
String question = tempQuestion.substring(0, tempQuestion.length() - 2);
for (int count = 0; count < question.length(); count++) {
String stringResult = question.substring(count, count + 1);
result += Double.parseDouble(stringResult);
}
System.out.println(result);
Other answers are correct, you could use a java.text.NumberFormat (JavaDoc) to format your output. Using printfis also an option for formatting, similar to NumberFormat. But I see something else here. It looks like you mixed up your data types: In
nq = (long) Math.pow(2l, 1000l);
you are already truncating the double return value from Math to a long. Then you should use long as data type instead of double for the conversion. So use Long.toString(long), this will not add any exponent output.
Use Long.toString(nq) instead of Double.toString(nq); in your code.
As you say: "NumberFormat". The class.
BigInteger is easy to use and you don't risk precision problems with it. (In this particular instance I don't think there is a precision problem, because Math.pow(2, 1001) % 100000 returns the correct last 5 digits, but for bigger numbers eventually you will lose information.) Here's how you can use BigInteger:
groovy:000> b = new BigInteger(2L)
===> 2
groovy:000> b = b.pow(1001)
===> 214301721437253464189685009812000362112280962341106721488750077674070210224
98722449863967576313917162551893458351062936503742905713846280871969155149397149
60786913554964846197084214921012474228375590836430609294996716388253479753511833
1087892154125829142392955373084335320859663305248773674411336138752
groovy:000> ((b + "").toList().collect {new Integer(it)}).inject(0) {sum, n -> sum + n}
===> 1319
Here's the same thing in Java:
public class Example
{
public static void main(String[] args)
{
int sum = 0;
for (char ch : new java.math.BigInteger("2").pow(1001).toString().toCharArray()) {
sum += Character.digit(ch, 10);
}
System.out.println(sum);
}
}
Link to the javadoc for NumberFormat: Javadoc
just replace last line:
System.out.println(result);
with
System.out.printf("%d", result);
Getting following run-time error
C:\jdk1.6.0_07\bin>java euler/BigConCheck
Exception in thread "main" java.lang.NumberFormatException: For input string: "z
"
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.math.BigInteger.<init>(BigInteger.java:314)
at java.math.BigInteger.<init>(BigInteger.java:447)
at euler.BigConCheck.conCheck(BigConCheck.java:25)
at euler.BigConCheck.main(BigConCheck.java:71)
My Code
package euler;
import java.math.BigInteger;
class BigConCheck
{
public int[] conCheck(BigInteger big)
{
int i=0,q=0,w=0,e=0,r=0,t=0,mul=1;
int a[]= new int[1000];
int b[]= new int[7];
BigInteger rem[]= new BigInteger[4];
BigInteger num[]= new BigInteger[4];
for(i=0;i<4;i++)
num[i]=big; // intialised num[1 to 4][0] with big
String s="1",g="0";
for(i=0;i<999;i++)
s = s.concat(g);
BigInteger divi[]= new BigInteger[4];
for(i=0;i<5;i++)
{
divi[i]=new BigInteger(s);
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
divi[i]=divi[i].divide(zz);
}
for(i=0;i<996;i++) // 5 consecative numbers.
{
for(int k=0;k<5;k++)
{
rem[k] = num[k].mod(divi[k]);
b[k]=rem[k].intValue();
mul= mul*b[k];
/*int z = (int)Math.pow((double)10,(double)(k+1));
String zz = "z";
BigInteger zzz = new BigInteger(zz);
num[k]=num[k].divide(zzz); */
}
a[i]=mul;
for(int p=0;p<5;p++)
{
BigInteger qq = new BigInteger("10");
num[p]=num[p].divide(qq);
}
}
return a;
}
public int bigestEleA(int u[])
{
int big=0;
for(int i=0;i<u.length;i++)
if(big<u[i])
big=u[i];
return big;
}
public static void main(String args[])
{
int con5[]= new int[1000];
int punCon;
BigInteger bigest = new BigInteger("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450");
BigConCheck bcc = new BigConCheck();
con5=bcc.conCheck(bigest);
punCon=bcc.bigestEleA(con5);
System.out.println(punCon);
}
}
please point out whats goes wrong # runtime and why
thanks in advance...
This is the line causing you grief:
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
While BigInteger does work with String's, those String's must be parsable into numbers.
EDIT**
Try this:
Integer z = (Integer)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(z.toString());
new BigInteger("z"); is not meaningful. You can only pass numbers in constructor.
This is pretty obvious, so the next time you get an exception go the the exact line in your code shown in the exception stacktrace and you will most likely spot the problem.
BigInteger Javadoc states for BigInteger(String value)
Translates the decimal String
representation of a BigInteger into a
BigInteger. The String representation
consists of an optional minus sign
followed by a sequence of one or more
decimal digits. The character-to-digit
mapping is provided by
Character.digit. The String may not
contain any extraneous characters
(whitespace, for example).
So your code:
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
is totally incorrect, but this is correct:
BigInteger zz = new BigInteger("5566");
EDIT: Based on your comment, this would be simpler by using the String.valueOf() method:
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(String.valueOf(z));
BigInteger zz = new BigInteger("z");
you are passing non-numerical string thats the reason.
EDIT:
It takes string but it expects the string to be a numerical value. "z" does not have any numerical meaning.
Could it be that you want this instead?
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(z);
Note the missing quotes here. (Of course, this will only work for i < 10.)
A common mistake is writing
new BigInteger("",num)
instead of
new BigInteger(""+num)
For those interested in generating longs with characters without hashing, it is possible to transform characters to long via BigInteger simply by using the constructor with a radix: BigInteger(String value, int radix)
There is a catch thought, the int which defines the log base, must scale not with the length of the String, but instead with the number of characters that make out the collection of characters that will be used in the creation of the String.
As far as I'm aware, for an alpha numeric collection, the int is 36 (26 + 10), this may be wrong thought.
There is also a limitation, I believe there are symbols that simply cannot be parsed, like "-" or " " or "_" (I've tried adding to the int base radix and nothing) which means the String must be transformed before parsing and it cannot be returned back to String after it being parsed via BigInteger.
Why is it useful?? I don't know haha, I have use it to autogenerate id's from Strings ,instead of using hashes, I remember somhwere this is kinda better than hashcode since a hash from String does not ensure uniqueness, an also this method as opposed to base Encoding gives extricity a long value, which may be useful for many api's that require a long id.