【问题标题】:Number of zeroes at the end of factorial阶乘末尾的零个数
【发布时间】:2014-03-08 14:12:58
【问题描述】:

我需要找出阶乘数字末尾的零个数。所以这是我的代码,但它不太工作:/

using System;

class Sum
{
    static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine());
        long factoriel = 1;

        for (int i = 1; i <= n; i++)
        {
            factoriel *= i;
        }

        Console.WriteLine(factoriel);

        int timesZero = 0;

        while(factoriel % 10 != 0)
        {
            timesZero++;
        }
        Console.WriteLine(timesZero);
    }
}

我知道我可以使用 for loop 并除以 5,但我不想这样做。我的代码中的问题在哪里?为什么它不起作用?

【问题讨论】:

  • 试试n=123456789 :) 你应该可以在不计算阶乘的情况下做到这一点。 (如果我是你的教授/老板,至少我会期待)
  • 请不要在问题标题中包含有关所用语言的信息,除非没有它就没有意义。标记用于此目的。

标签: c# math numbers


【解决方案1】:

您的算法存在问题整数溢出。想象一下,你被给予了

  n = 1000

所以n! = 4.0238...e2567;您不应该计算 n!,而是计算其形式为 (5**p)*m 的项,其中 pm 是一些整数:

  5 * m gives you one zero
 25 * m gives you two zeros
625 * m gives you three zeros etc

最简单的代码(在大 n 上很慢)是

  static void Main(string[] args) {
    ...
    int timesZero = 0;
    
    for (int i = 5; i <= n; i += 5) {
      int term = i;
    
      while ((term % 5) == 0) {
        timesZero += 1;
        term /= 5;
      }
    }
    ...
  }

更快的实现是

  static void Main(string[] args) {
    ...
    int timesZero = 0;
    
    for (int power5 = 5; power5 <= n; power5 *= 5) 
      timesZero += n / power5;
    
    ...
  }

【讨论】:

  • for (int i = 5; i
  • @Hovhannes Babayan:谢谢!我懂了。阶乘(与 arrayslists 等不同)不是从零开始的(不是0 * 1 * ... * (n - 1),而是1 * 2 * ... * n
【解决方案2】:

计算阶乘中的尾随零

static int countZerosInFactOf(int n)##
{   
    int result = 0;
    int  start = 1;
    while (n >= start)
    {
        start *= 5;
        result += (int)n/start; 
    }
    return result;
} 

【讨论】:

    【解决方案3】:

    确保添加内置参考System.Numeric

    using System.Text;
    using System.Threading.Tasks;
    using System.Numeric
    
    namespace TrailingZeroFromFact
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Enter a no");
                int no = int.Parse(Console.ReadLine());
                BigInterger fact = 1;
                if (no > 0)
                {
                    for (int i = 1; i <= no; i++)
                    {
                        fact = fact * i;
                    }
                    Console.WriteLine("{0}!={1}", no, fact);
                    string str = fact.ToString();
                    string[] ss = str.Split('0');
                    int count = 0;
                    for (int i = ss.Length - 1; i >= 0; i--)
                    {
                        if (ss[i] == "")
                            count = count + 1;
                        else
                            break;
                    }
                    Console.WriteLine("No of trailing zeroes are = {0}", count);
                }
                else
                {
                    Console.WriteLine("Can't calculate factorial of negative no");
                }
                Console.ReadKey();
            }
        }
    } 
    

    【讨论】:

      【解决方案4】:
      static void Main(string[] args)
              {
                  Console.WriteLine("Enter the number:");
                  int n = int.Parse(Console.ReadLine());
                  int zero = 0;
                  long fac=1;
                  for (int i = 1; i <= n; i++)
                  {
                      fac *= i;
                  }
                  Console.WriteLine("Factorial is:" + fac);
              ab:
      
      
              if (fac % 10 == 0)
              {
                  fac = fac / 10;
                  zero++;
                  goto ab;
              }
              else
              {
                  Console.WriteLine("Zeros are:" + zero);
              }
              Console.ReadLine();
              }
      

      【讨论】:

        【解决方案5】:

        您的代码看起来不错,只是在 while 条件下稍作修正:

                public static int CalculateTrailingZeroes(BigInteger bigNum)
            {
                int zeroesCounter = 0;
        
                while (bigNum % 10 == 0)
                {
                    zeroesCounter++;
                    bigNum /=10;
                }
        
                return zeroesCounter;
            }
        

        这行得通,我刚刚测试过。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          • 2017-10-10
          • 2022-01-18
          相关资源
          最近更新 更多