I want to use a big integer value in my while loop condition but this is not working.
import java.util.Scanner;
import java.util.StringTokenizer;
public class NiceProbelm2 {
public static void main(String[]args){
Scanner input = new Scanner(System.in);
String number = input.nextLine();
StringTokenizer st = new StringTokenizer(number);
BigInteger base = null;
int power=0;
while (st.hasMoreTokens()) {
String token1 = st.nextToken();
String token2 = st.nextToken();
base = new BigInteger(token1);
power = Integer.parseInt(token2);
}
BigInteger result = base.pow(power);
//long fresult = (long)result;
BigInteger div = new BigInteger("10");
System.out.println(result);
BigInteger sum=null;
//NOt working while(result.compareTo(new BigInteger("0")) > 10 )
{
BigInteger digit = result.mod(div);
result = result.divide(div);
sum = sum.add(digit);
}
System.out.println(sum);
}
}
You should never compare the return value of compareTo() to anything other than 0. (BigInteger.compareTo() is a bit more specific, but the same rule still applies)
You can check if it's greater than 0, less than 0 or equal to 0. Only those 3 pieces of information are actually relevant. The actual value (if it returns 1 or 10 or 100) doesn't matter.
I think you problem with the previous solutions were you had a null pointer that was being thrown because your accumulator was not initialized. The following code produces the result you are looking for:
BigInteger result = base.pow(power);
BigInteger div = new BigInteger("10");
System.out.println(result);
//The following line is different, initialize the sum before using it.
BigInteger sum = BigInteger.ZERO;
while(!BigInteger.ZERO.equals(result)) {
BigInteger digit = result.mod(div);
result = result.divide(div);
sum = sum.add(digit);
}
System.out.println(sum);
I also wanted to point out that BigInteger has a method that provides both the quotient and remainder from a single division, which is more efficient than doing them both separately, and there is a "valueOf" method for BigInteger so you can use a numeric literal instead of a string:
BigInteger result = base.pow(power);
BigInteger div = BigInteger.valueOf(10);
System.out.println(result);
//Initialize the sum to zero
BigInteger sum = BigInteger.ZERO;
//While the result has a non-zero decimal digit
while(!BigInteger.ZERO.equals(result)) {
//this divides by ten (first element),
//and calculates the remainder (second element)
BigInteger[] lastDigit = result.divideAndRemainder(div);
result = lastDigit[0];
sum = sum.add(lastDigit[1]);
}
System.out.println(sum);
You have to use this condition:
result.compareTo(BigInteger.ZERO) > 0
It looks like you want to do while (result != 0) which you would write like
while (result.compareTo(BigInteger.ZERO) != 0)
Also, you need to initialize sum to BigInteger.ZERO.
Related
I am trying to multiply n digit number using karatsuba multiplication.
I am getting output for single digit number (Example 4 and 5 = 20).
But, when I multiply 1234 and 5678 I am getting error and no output result.
I have updated the code and error message. Please check.
The error is Click here
import java.math.BigInteger;
class karatsubamultiplication{
public static BigInteger karat(BigInteger number1, BigInteger number2){
if(number1.bitLength() < 4 && number2.bitLength() < 4)
return number1.multiply(number2);
//Finding maximum length of two
//int m = Math.max(number1, number2);
String first = number1.toString();
String second = number2.toString();
BigInteger a = new BigInteger(first.substring(0, first.length()/2));
BigInteger b = new BigInteger(first.substring(first.length() - first.length()/2, first.length()));
BigInteger c = new BigInteger(second.substring(0, second.length()/2));
BigInteger d = new BigInteger(second.substring(second.length() - second.length()/2, second.length()));
BigInteger ac = karat(a, c);
BigInteger bd = karat(b, d);
BigInteger abcd = karat(a.add(b), c.add(d));
BigInteger z = abcd.subtract(ac.add(bd));
int m = String.valueOf(number1).length();
BigInteger len = new BigInteger(String.valueOf(Math.pow(10, m)));
return (ac.multiply(len)).add(z.multiply(len.divide(BigInteger.valueOf(2)))).add(bd);
}
public static void main(String[] args){
BigInteger result = new BigInteger("0");
BigInteger x = new BigInteger("1234");
BigInteger y = new BigInteger("5678");
result = karat(x, y);
System.out.println(result);
}
}
Please correct the code. I have not checked whether two numbers are equal or not and length is odd or even.
Thank you.
I am trying to calculate the square root of all the integers below 100 with A precision of up to 10000 digits. I already tried it using Newton's method with Big Decimal, where it eats a lot of time.
So now am using Jarvis method for finding the square root using BigInteger.(I think this method involves less number of calculations and gets rid of the maintenance of decimal digits). Even then my code takes a lot of time.The following piece of code depicts the calculations.
public class SquareRootHackerRankJarvis {
static BigInteger limit;
static BigInteger a;
static BigInteger b;
private static BigInteger squareroot(int n, int digits, BigInteger ten,
BigInteger hundred, BigInteger five) {
limit = ten.pow(digits + 1);
a = BigInteger.valueOf(n * 5);
b = BigInteger.valueOf(5);
while (b.compareTo(limit) == -1) {
if (a.compareTo(b) != -1) {
a = a.subtract(b);
b = b.add(ten);
} else {
a = a.multiply(hundred);
b = (b.divide(ten)).multiply(hundred).add(five);
}
}
return b.divide(hundred);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int P = scanner.nextInt();
int sum = 0;
int p = 1;
BigInteger ten = BigInteger.valueOf(10);
BigInteger hundred = BigInteger.valueOf(100);
BigInteger five = BigInteger.valueOf(5);
for (int i = 1; i <= N; i++) {
if (p * p == i) {
p++;
continue;
}
BigInteger x = squareroot(i, P, ten, hundred, five);
char[] digits = x.toString().toCharArray();
for (int j = 0; j <= P - 1; j++) {
sum += Character.getNumericValue(digits[j]);
}
}
System.out.println(sum);
scanner.close();
}}
Can anyone provided or suggestions about the proper usage of BigInteger for optimum performance?
Comments on improvement of the above algorithm are also welcomed.
BigInteger ten = BigInteger.valueOf(10);
BigInteger hundred = BigInteger.valueOf(100);
BigInteger five = BigInteger.valueOf(5);
Should be moved outside of the function squareroot so they are not created and initialized every time function is called. Make sure they are still accessible in this function.
BigInteger num;
BigInteger limit;
BigInteger a;
BigInteger b;
Should be created outside of the function and should be only initialized on every fucntion call.
Also following line
b = (b.divide(ten)).multiply(hundred).add(five);
can be optimized to
b = b.multiply(ten).add(five);
One observation beyond fast computation of numerous digits of roots of non-squares is that there are just 25 non-compound numbers from 2 to 100.
Next, in addition to introducing constants like Maciej suggested, reduce the "introduction of 0 before the trailing 5" to two operations:
static final BigInteger
ten = BigInteger.TEN,
oneHundred = BigInteger.valueOf(100),
five = BigInteger.valueOf( 5),
fourtyFive = BigInteger.valueOf( 45);
/** Computes <code>digits</code> decimal digits of <code>n</code>
* <em>ignoring</em> (decimal) scaling. */
private static BigInteger sqrtDigitsJarvis(int n, int digits) {
BigInteger
limit = ten.pow(digits + 1), // might be an instance data member
a = BigInteger.valueOf(n*5L), // la*100),
b = five; // BigInteger.valueOf(ib*10 - 45);
// flawed for limit < sqrt(5n)
while (b.compareTo(limit) < 0) {
if (0 <= a.compareTo(b)) { // each branch can be parallelised
a = a.subtract(b);
b = b.add(ten);
} else {
a = a.multiply(oneHundred);
b = b.multiply(ten).subtract(fourtyFive);
}
}
return b.divide(oneHundred);
}
I am trying to create a program that will tell if a number given to it is a "Happy Number" or not. Finding a happy number requires each digit in the number to be squared, and the result of each digit's square to be added together.
In Python, you could use something like this:
SQUARE[d] for d in str(n)
But I can't find how to iterate through each digit in a number in Java. As you can tell, I am new to it, and can't find an answer in the Java docs.
You can use a modulo 10 operation to get the rightmost number and then divide the number by 10 to get the next number.
long addSquaresOfDigits(int number) {
long result = 0;
int tmp = 0;
while(number > 0) {
tmp = number % 10;
result += tmp * tmp;
number /= 10;
}
return result;
}
You could also put it in a string and turn that into a char array and iterate through it doing something like Math.pow(charArray[i] - '0', 2.0);
Assuming the number is an integer to begin with:
int num = 56;
String strNum = "" + num;
int strLength = strNum.length();
int sum = 0;
for (int i = 0; i < strLength; ++i) {
int digit = Integer.parseInt(strNum.charAt(i));
sum += (digit * digit);
}
I wondered which method would be quickest to split up a positive number into its digits in Java, String vs modulo
public static ArrayList<Integer> splitViaString(long number) {
ArrayList<Integer> result = new ArrayList<>();
String s = Long.toString(number);
for (int i = 0; i < s.length(); i++) {
result.add(s.charAt(i) - '0');
}
return result; // MSD at start of list
}
vs
public static ArrayList<Integer> splitViaModulo(long number) {
ArrayList<Integer> result = new ArrayList<>();
while (number > 0) {
int digit = (int) (number % 10);
result.add(digit);
number /= 10;
}
return result; // LSD at start of list
}
Testing each method by passing Long.MAX_VALUE 10,000,000 times, the string version took 2.090 seconds and the modulo version 2.334 seconds. (Oracle Java 8 on 64bit Ubuntu running in Eclipse Neon)
So not a lot in it really, but I was a bit surprised that String was faster
In the above example we can use:
int digit = Character.getNumericValue(strNum.charAt(i));
instead of
int digit = Integer.parseInt(strNum.charAt(i));
You can turn the integer into a string and iterate through each char in the string. As you do that turn that char into an integer
This code returns the first number (after 1) that fits your description.
public static void main(String[] args) {
int i=2;
// starting the search at 2, since 1 is also a happy number
while(true) {
int sum=0;
for(char ch:(i+"").toCharArray()) { // casting to string and looping through the characters.
int j=Character.getNumericValue(ch);
// getting the numeric value of the current char.
sum+=Math.pow(j, j);
// adding the current digit raised to the power of itself to the sum.
}
if(sum==i) {
// if the sum is equal to the initial number
// we have found a number that fits and exit.
System.out.println("found: "+i);
break;
}
// otherwise we keep on searching
i++;
}
}
I need to generate arbitrarily large random integers in the range 0 (inclusive) to n (exclusive). My initial thought was to call nextDouble and multiply by n, but once n gets to be larger than 253, the results would no longer be uniformly distributed.
BigInteger has the following constructor available:
public BigInteger(int numBits, Random rnd)
Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2numBits - 1), inclusive.
How can this be used to get a random value in the range 0 - n, where n is not a power of 2?
Use a loop:
BigInteger randomNumber;
do {
randomNumber = new BigInteger(upperLimit.bitLength(), randomSource);
} while (randomNumber.compareTo(upperLimit) >= 0);
on average, this will require less than two iterations, and the selection will be uniform.
Edit: If your RNG is expensive, you can limit the number of iterations the following way:
int nlen = upperLimit.bitLength();
BigInteger nm1 = upperLimit.subtract(BigInteger.ONE);
BigInteger randomNumber, temp;
do {
temp = new BigInteger(nlen + 100, randomSource);
randomNumber = temp.mod(upperLimit);
} while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);
// result is in 'randomNumber'
With this version, it is highly improbable that the loop is taken more than once (less than one chance in 2^100, i.e. much less than the probability that the host machine spontaneously catches fire in the next following second). On the other hand, the mod() operation is computationally expensive, so this version is probably slower than the previous, unless the randomSource instance is exceptionally slow.
The following method uses the BigInteger(int numBits, Random rnd) constructor and rejects the result if it's bigger than the specified n.
public BigInteger nextRandomBigInteger(BigInteger n) {
Random rand = new Random();
BigInteger result = new BigInteger(n.bitLength(), rand);
while( result.compareTo(n) >= 0 ) {
result = new BigInteger(n.bitLength(), rand);
}
return result;
}
The drawback to this is that the constructor is called an unspecified number of times, but in the worst case (n is just slightly greater than a power of 2) the expected number of calls to the constructor should be only about 2 times.
The simplest approach (by quite a long way) would be to use the specified constructor to generate a random number with the right number of bits (floor(log2 n) + 1), and then throw it away if it's greater than n. In the worst possible case (e.g. a number in the range [0, 2n + 1) you'll throw away just under half the values you create, on average.
Why not constructing a random BigInteger, then building a BigDecimal from it ?
There is a constructor in BigDecimal : public BigDecimal(BigInteger unscaledVal, int scale) that seems relevant here, no ? Give it a random BigInteger and a random scale int, and you'll have a random BigDecimal. No ?
Here is how I do it in a class called Generic_BigInteger available via:
Andy Turner's Generic Source Code Web Page
/**
* There are methods to get large random numbers. Indeed, there is a
* constructor for BigDecimal that allows for this, but only for uniform
* distributions over a binary power range.
* #param a_Random
* #param upperLimit
* #return a random integer as a BigInteger between 0 and upperLimit
* inclusive
*/
public static BigInteger getRandom(
Generic_Number a_Generic_Number,
BigInteger upperLimit) {
// Special cases
if (upperLimit.compareTo(BigInteger.ZERO) == 0) {
return BigInteger.ZERO;
}
String upperLimit_String = upperLimit.toString();
int upperLimitStringLength = upperLimit_String.length();
Random[] random = a_Generic_Number.get_RandomArrayMinLength(
upperLimitStringLength);
if (upperLimit.compareTo(BigInteger.ONE) == 0) {
if (random[0].nextBoolean()) {
return BigInteger.ONE;
} else {
return BigInteger.ZERO;
}
}
int startIndex = 0;
int endIndex = 1;
String result_String = "";
int digit;
int upperLimitDigit;
int i;
// Take care not to assign any digit that will result in a number larger
// upperLimit
for (i = 0; i < upperLimitStringLength; i ++){
upperLimitDigit = new Integer(
upperLimit_String.substring(startIndex,endIndex));
startIndex ++;
endIndex ++;
digit = random[i].nextInt(upperLimitDigit + 1);
if (digit != upperLimitDigit){
break;
}
result_String += digit;
}
// Once something smaller than upperLimit guaranteed, assign any digit
// between zero and nine inclusive
for (i = i + 1; i < upperLimitStringLength; i ++) {
digit = random[i].nextInt(10);
result_String += digit;
}
// Tidy values starting with zero(s)
while (result_String.startsWith("0")) {
if (result_String.length() > 1) {
result_String = result_String.substring(1);
} else {
break;
}
}
BigInteger result = new BigInteger(result_String);
return result;
}
For those who are still asking this question and are looking for a way to generate arbitrarily large random BigIntegers within a positive integer range, this is what I came up with. This random generator works without trying bunch of numbers until one fits the range. Instead it will generate a random number directly that will fit the given range.
private static BigInteger RandomBigInteger(BigInteger rangeStart, BigInteger rangeEnd){
Random rand = new Random();
int scale = rangeEnd.toString().length();
String generated = "";
for(int i = 0; i < rangeEnd.toString().length(); i++){
generated += rand.nextInt(10);
}
BigDecimal inputRangeStart = new BigDecimal("0").setScale(scale, RoundingMode.FLOOR);
BigDecimal inputRangeEnd = new BigDecimal(String.format("%0" + (rangeEnd.toString().length()) + "d", 0).replace('0', '9')).setScale(scale, RoundingMode.FLOOR);
BigDecimal outputRangeStart = new BigDecimal(rangeStart).setScale(scale, RoundingMode.FLOOR);
BigDecimal outputRangeEnd = new BigDecimal(rangeEnd).add(new BigDecimal("1")).setScale(scale, RoundingMode.FLOOR); //Adds one to the output range to correct rounding
//Calculates: (generated - inputRangeStart) / (inputRangeEnd - inputRangeStart) * (outputRangeEnd - outputRangeStart) + outputRangeStart
BigDecimal bd1 = new BigDecimal(new BigInteger(generated)).setScale(scale, RoundingMode.FLOOR).subtract(inputRangeStart);
BigDecimal bd2 = inputRangeEnd.subtract(inputRangeStart);
BigDecimal bd3 = bd1.divide(bd2, RoundingMode.FLOOR);
BigDecimal bd4 = outputRangeEnd.subtract(outputRangeStart);
BigDecimal bd5 = bd3.multiply(bd4);
BigDecimal bd6 = bd5.add(outputRangeStart);
BigInteger returnInteger = bd6.setScale(0, RoundingMode.FLOOR).toBigInteger();
returnInteger = (returnInteger.compareTo(rangeEnd) > 0 ? rangeEnd : returnInteger); //Converts number to the end of output range if it's over it. This is to correct rounding.
return returnInteger;
}
How does it work?
First it generates a String with random numbers with the same length as the maximum range. For example: with given range of 10-1000 it will generate some number between 0000 and 9999 as a String.
Then it creates BigDecimals to represent the maximum possible value (9999 in previous example) and minimum value (0) and converts the range parameter BigIntegers to BigDecimals. Also in this step to the given range maximum value is added 1 in order to correct rounding errors in the next step.
Then using this formula the generated random number is mapped to the given range:
(generated - inputRangeStart) / (inputRangeEnd - inputRangeStart) * (outputRangeEnd - outputRangeStart) + outputRangeStart
After that it will do a last check whether or not the mapped number fits the given range and sets it to the given range maximum if it doesn't. This is done in order to correct rounding errors.
Just use modular reduction
new BigInteger(n.bitLength(), new SecureRandom()).mod(n)
Compile this F# code into a DLL and you can also reference it in your C# / VB.NET programs
type BigIntegerRandom() =
static let internalRandom = new Random()
/// Returns a BigInteger random number of the specified number of bytes.
static member RandomBigInteger(numBytes:int, rand:Random) =
let r = if rand=null then internalRandom else rand
let bytes : byte[] = Array.zeroCreate (numBytes+1)
r.NextBytes(bytes)
bytes.[numBytes] <- 0uy
bigint bytes
/// Returns a BigInteger random number from 0 (inclusive) to max (exclusive).
static member RandomBigInteger(max:bigint, rand:Random) =
let rec getNumBytesInRange num bytes = if max < num then bytes else getNumBytesInRange (num * 256I) bytes+1
let bytesNeeded = getNumBytesInRange 256I 1
BigIntegerRandom.RandomBigInteger(bytesNeeded, rand) % max
/// Returns a BigInteger random number from min (inclusive) to max (exclusive).
static member RandomBigInteger(min:bigint, max:bigint, rand:Random) =
BigIntegerRandom.RandomBigInteger(max - min, rand) + min
I'm trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the factorial of the number, and count the trailing zeros. However, when the number is about as large as 25!, numZeros don't work.
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double fact;
int answer;
try {
int number = Integer.parseInt(br.readLine());
fact = factorial(number);
answer = numZeros(fact);
}
catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static double factorial (int num) {
double total = 1;
for (int i = 1; i <= num; i++) {
total *= i;
}
return total;
}
public static int numZeros (double num) {
int count = 0;
int last = 0;
while (last == 0) {
last = (int) (num % 10);
num = num / 10;
count++;
}
return count-1;
}
I am not worrying about the efficiency of this code, and I know that there are multiple ways to make the efficiency of this code BETTER. What I'm trying to figure out is why the counting trailing zeros of numbers that are greater than 25! is not working.
Any ideas?
Your task is not to compute the factorial but the number of zeroes. A good solution uses the formula from http://en.wikipedia.org/wiki/Trailing_zeros (which you can try to prove)
def zeroes(n):
i = 1
result = 0
while n >= i:
i *= 5
result += n/i # (taking floor, just like Python or Java does)
return result
Hope you can translate this to Java. This simply computes [n / 5] + [n / 25] + [n / 125] + [n / 625] + ... and stops when the divisor gets larger than n.
DON'T use BigIntegers. This is a bozosort. Such solutions require seconds of time for large numbers.
You only really need to know how many 2s and 5s there are in the product. If you're counting trailing zeroes, then you're actually counting "How many times does ten divide this number?". if you represent n! as q*(2^a)*(5^b) where q is not divisible by 2 or 5. Then just taking the minimum of a and b in the second expression will give you how many times 10 divides the number. Actually doing the multiplication is overkill.
Edit: Counting the twos is also overkill, so you only really need the fives.
And for some python, I think this should work:
def countFives(n):
fives = 0
m = 5
while m <= n:
fives = fives + (n/m)
m = m*5
return fives
The double type has limited precision, so if the numbers you are working with get too big the double will be only an approximation. To work around this you can use something like BigInteger to make it work for arbitrarily large integers.
You can use a DecimalFormat to format big numbers. If you format your number this way you get the number in scientific notation then every number will be like 1.4567E7 this will make your work much easier. Because the number after the E - the number of characters behind the . are the number of trailing zeros I think.
I don't know if this is the exact pattern needed. You can see how to form the patterns here
DecimalFormat formater = new DecimalFormat("0.###E0");
My 2 cents: avoid to work with double since they are error-prone. A better datatype in this case is BigInteger, and here there is a small method that will help you:
public class CountTrailingZeroes {
public int countTrailingZeroes(double number) {
return countTrailingZeroes(String.format("%.0f", number));
}
public int countTrailingZeroes(String number) {
int c = 0;
int i = number.length() - 1;
while (number.charAt(i) == '0') {
i--;
c++;
}
return c;
}
#Test
public void $128() {
assertEquals(0, countTrailingZeroes("128"));
}
#Test
public void $120() {
assertEquals(1, countTrailingZeroes("120"));
}
#Test
public void $1200() {
assertEquals(2, countTrailingZeroes("1200"));
}
#Test
public void $12000() {
assertEquals(3, countTrailingZeroes("12000"));
}
#Test
public void $120000() {
assertEquals(4, countTrailingZeroes("120000"));
}
#Test
public void $102350000() {
assertEquals(4, countTrailingZeroes("102350000"));
}
#Test
public void $1023500000() {
assertEquals(5, countTrailingZeroes(1023500000.0));
}
}
This is how I made it, but with bigger > 25 factorial the long capacity is not enough and should be used the class Biginteger, with witch I am not familiar yet:)
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number : ");
long number = in.nextLong();
long numFactorial = 1;
for(long i = 1; i <= number; i++) {
numFactorial *= i;
}
long result = 0;
int divider = 5;
for( divider =5; (numFactorial % divider) == 0; divider*=5) {
result += 1;
}
System.out.println("Factorial of n is: " + numFactorial);
System.out.println("The number contains " + result + " zeroes at its end.");
in.close();
}
}
The best with logarithmic time complexity is the following:
public int trailingZeroes(int n) {
if (n < 0)
return -1;
int count = 0;
for (long i = 5; n / i >= 1; i *= 5) {
count += n / i;
}
return count;
}
shamelessly copied from http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/
I had the same issue to solve in Javascript, and I solved it like:
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count) // console shows 4
This solution gives you the number of trailing zeros.
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count)
Java's doubles max out at a bit over 9 * 10 ^ 18 where as 25! is 1.5 * 10 ^ 25. If you want to be able to have factorials that high you might want to use BigInteger (similar to BigDecimal but doesn't do decimals).
I wrote this up real quick, I think it solves your problem accurately. I used the BigInteger class to avoid that cast from double to integer, which could be causing you problems. I tested it on several large numbers over 25, such as 101, which accurately returned 24 zeros.
The idea behind the method is that if you take 25! then the first calculation is 25 * 24 = 600, so you can knock two zeros off immediately and then do 6 * 23 = 138. So it calculates the factorial removing zeros as it goes.
public static int count(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
int zeroCount = 0;
BigInteger mult = new BigInteger("1");
while (number > 0) {
mult = mult.multiply(new BigInteger(Integer.toString(number)));
while (mult.mod(ten).compareTo(zero) == 0){
mult = mult.divide(ten);
zeroCount += 1;
}
number -= 1;
}
return zeroCount;
}
Since you said you don't care about run time at all (not that my first was particularly efficient, just slightly more so) this one just does the factorial and then counts the zeros, so it's cenceptually simpler:
public static BigInteger factorial(int number) {
BigInteger ans = new BigInteger("1");
while (number > 0) {
ans = ans.multiply(new BigInteger(Integer.toString(number)));
number -= 1;
}
return ans;
}
public static int countZeros(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
BigInteger fact = factorial(number);
int zeroCount = 0;
while (fact.mod(ten).compareTo(zero) == 0){
fact = fact.divide(ten);
zeroCount += 1;
}
}