计数数尾随零源于阶乘(Counting trailing zeros of numbers resu

2019-06-26 16:16发布

我试图计算所导致的阶乘(这意味着该号码来获得相当大的)数尾随零。 下面的代码需要花费数,计算数的阶乘,数尾随零。 然而,当数量大约是一样大的25 !,的numZeros不起作用。

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;
}

我不担心这个代码的效率,而且我知道,有多种方法,使这个代码更好的效率。 我试图找出就是为什么计数后是大于25的数字零! 不管用。

有任何想法吗?

Answer 1:

你的任务是不计算阶乘,但零的数目。 一个好的解决方案采用从公式http://en.wikipedia.org/wiki/Trailing_zeros (你可以试着证明)

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

希望你能翻译这为Java。 这只是计算[N / 5] + [N / 25] + [N / 125] + [N / 625] + ...和当除数变得大于n停止。

切勿使用BigIntegers。 这是一个bozosort。 这种解决方案需要的时间秒大数。



Answer 2:

你只有真正需要知道有多少2S和5S有在产品中。 如果您计算尾随零,那么你实际上计算“多少次10分这个数字?”。 如果你代表N! 为q *(2 ^α)*(5 ^ b)在q不为被2整除或5.然后,只需采取的最小和b在第二表达会给你多少次10将数。 实际上做乘法是矫枉过正。

编辑:计算三三两两也矫枉过正,所以你只有真正需要的五岁以下儿童。

而对于一些蟒蛇,我认为这应该工作:

def countFives(n):
    fives = 0   
    m = 5
    while m <= n:
        fives = fives + (n/m)
        m = m*5
    return fives


Answer 3:

double类型具有有限的精度,因此,如果您正在使用的数字受到太大的双重将只是一个近似值。 要解决这一点,你可以使用类似的BigInteger,使其任意大整数的工作。



Answer 4:

您可以使用一个DecimalFormat格式化大的数字。 如果格式化你的电话号码这样你得到的数字科学记数法 ,然后每一个数字会像1.4567E7这将使您的工作轻松多了。 因为对E后面的数字 - 后面的字符数。 是我想尾随零的数量。

我不知道这是否是需要的精确模式。 你可以看到如何形成的图案在这里

DecimalFormat formater = new DecimalFormat("0.###E0");


Answer 5:

我的2美分:避免,因为它们是容易出错的双重工作。 在这种情况下,更好的数据类型为BigInteger,它是在这里有一个小方法,可以帮助你:

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));
    }
}


Answer 6:

这是我做到了,但更大的> 25阶乘长能力是不够的,应使用类BIGINTEGER,与巫婆我不熟悉尚未:)

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();

 }

}


Answer 7:

与数时间复杂度最好的是以下几点:

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;
}

从耍赖复制http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/



Answer 8:

我有同样的问题在Javascript来解决,我解决了这个问题,如:

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

该解决方案为您提供了尾随零的数量。

 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) 



Answer 9:

Java的双打最大程度的发挥,在一个有点超过9×10 ^ 18,其中25个! 为1.5×10 ^ 25,如果你希望能够有那么高,你可能想使用BigInteger的阶乘(类似于BigDecimal的,但不这样做小数)。



Answer 10:

我写这件事真正的快,我认为它准确地解决您的问题。 我用BigInteger类,以避免双重到整数投,这可能会导致你的问题。 我测试几个大量超过25,例如101,其精确地返回24个零。

该方法背后的想法是,如果你把25! 那么第一个计算是25 * 24 = 600,这样你就可以立即敲两个零点断,然后做6 * 23 = 138。因此,计算阶乘去除零,因为它去。

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;
}

既然你说你不关心运行时间在所有(不,我的第一次是特别有效的,只是稍微等等)这一个只是做阶乘,然后计数零,所以它的cenceptually简单:

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;
    }
}


文章来源: Counting trailing zeros of numbers resulted from factorial