在for循环中计算N个数字的阶乘

9
我正在解决来自CodeChef的问题,需要计算n个数字的阶乘。
用户输入一个数字,确定要对多少个整数执行阶乘计算,然后输入要计算的数字。
我的问题在于乘法本身。例如,如果我有一个int == 5,则结果将为20(它只会计算最后一个阶乘的n,而不是所有阶乘的n)。
这就是问题所在:
for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index
    for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
         _result[x] = _numbersToProcess[x] * y;// Multiply x by y then add to array
    }
}

外层循环定义要执行多少次计算。

内层循环通过迭代_numberToProcess的每个索引并将其乘以小于要计算的数字的每个数字来计算阶乘。

问题是阶乘计算会互相覆盖,例如:

5的阶乘结果为:20,但应该是120(它会一直覆盖自己,直到达到最后一个乘数)

所以我尝试了以下方法:

_result[x] = _numbersToProcess[x] *= y;

这显然与_numbersToProcess[x] = _numbersToProcess[x] * y;相同。
但这会产生完全不同的结果:
如果我们再次输入5,那么输出将是-1899959296。
我知道我可以轻松地从其他提交中复制和粘贴,但我想知道为什么我的方法不能产生正确的输出。
以下是整个方法:
int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
        int[] _numbersToProcess = new int[_numbers];// Array of inputs
        int[] _result = new int[_numbers];
        int i = 0;

        while(i < _numbersToProcess.Length) {
            _numbersToProcess[i] = int.Parse(Console.ReadLine());
            i++;
        }

        for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index
            for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
                _result[x] = _numbersToProcess[x] *= y;// Multiply x by y then add to array
            }
        }

        for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
            Console.WriteLine(_result[n]);// Write to console
        }

        Console.ReadLine();

7
从解决一个更简单的问题开始。 你能正确计算一个数字的阶乘吗? 如果不能做到这一点,那么就无法计算多个数字的阶乘。删除所有内容,重新开始;编写一个执行简单操作的程序,然后进行彻底的测试,直到你有信心它是正确的。一旦你拥有了一个可靠的正确代码基础,将正确的代码用作实现更复杂问题解决方案的工具。 这就是我们构建复杂程序的方法:通过构建可靠的小程序。 - Eric Lippert
5个回答

3
int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
    int[] _numbersToProcess = new int[_numbers];// Array of inputs
    int[] _result = new int[_numbers];
    int i = 0;

    while(i < _numbersToProcess.Length) {
        _numbersToProcess[i] = int.Parse(Console.ReadLine());
        i++;
    }

    for (int x = 0; x < _numbersToProcess.Length; x++)
        {// Loop throuigh Array by index
            int fact = 1;
            for (int y = 1; y <= _numbersToProcess[x]; y++)
            {// Y is equal to less than index x
                fact = fact*y;
            }
            _result[x] = fact;
        }


    for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
        Console.WriteLine(_result[n]);// Write to console
    }

    Console.ReadLine();

问题出在你的内部for循环上。在这里,你总是覆盖result数组。

例如当y=5时; 内部for循环会执行5次。

iteration -1 : 
  y=1,
  _numbersToProcess[5]=5
  _result[x]=5

  iteration -2 : 
  y=2,
  _numbersToProcess[5]=10
  _result[x]=10

iteration -3 : 
  y=3,
  _numbersToProcess[5]=30
  _result[x]=30

.
.
.
.
.

因此,它会进行12个迭代,因为您的_numbertoprocess[5]正在更改,并且一旦达到小于0即-1899959296就停止。

iteration 12:
  _numbertoprocess[5] = -1899959296.

即,您在内部for循环中每次更改numbertoprocess。 您可以通过添加代码进行验证。
Console.WriteLine(y);
Console.WriteLine(_numbersToProcess[x]);
Console.WriteLine(_result[x]);

在您的内部循环中。

那很好,谢谢你,但我想知道我做错了什么,而不是盲目地复制和粘贴。 - AnonDCX

1
for (int y = 1; y < _numbersToProcess[x]; y++) {// Y is equal to less than index x
    _result[x] = _numbersToProcess[x] *= y;// Multiply x by y then add to array
}

在循环条件中,y < _numberToProcess[x]。它比较y_numberToProcess[x]数组的值。
我认为你应该将循环条件编辑为y < x
祝好运。

0

这里我正在使用递归函数阶乘

      /* Factorial function*/
            int factorial (int n)
            {
            return (n*factorial(n-1))
            }

          int _numbers = int.Parse(Console.ReadLine());// Get number of ints to calculate
                    int[] _numbersToProcess = new int[_numbers];// Array of inputs
                    int[] _result = new int[_numbers];
                    int i = 0;

                    while(i < _numbersToProcess.Length) {
                        _numbersToProcess[i] = int.Parse(Console.ReadLine());
                        i++;
                    }

                    for(int x = 0; x < _numbersToProcess.Length; x++) {// Loop throuigh Array by index

                            _result[x] = factorial(_result[x])// Multiply x by y then add to array
                        }
                    }

                    for (int n = 0; n < _result.Length; n++) {// Y is equal to less than index x
                        Console.WriteLine(_result[n]);// Write to console
                    }

                    Console.ReadLine();

-1
#include <stdio.h>

int main()
{
  int c, n, fact = 1;

  printf("Enter a number to calculate it's factorial\n");
  scanf("%d", &n);

  for (c = 1; c <= n; c++)
    fact = fact * c;

  printf("Factorial of %d = %d\n", n, fact);

  return 0;
}

1
因为“我知道我可以轻松地复制和粘贴,但我想知道为什么我的方法没有产生正确的输出”,所以被踩了。 - miradulo

-2

看看这个,也许会有帮助...

#include <stdio.h>
#include <stdlib.h>

long f(int n) {
    if (n==0) return 1;
    else return n * f(n-1);
}

int main(int argc, char *argv[]) {
    long *factorials;
    int *inputs;
        int n;

    printf("Enter number n = ");
    scanf("%d", &n);

    factorials = (long *) malloc(n*sizeof(long));
    inputs = (int *) malloc(n*sizeof(int));

    for (int i = 0; i < n; i++) {
        long k;
        printf("Enter %d number = ", i + 1);
        scanf("%ld", &k);
        inputs[i] = k;
        factorials[i] = f(k);
    }

    for (int i = 0; i < n; i++) {
        printf("Factorial for %d = %ld\n", inputs[i], factorials[i]);
    }

    return 0;
}

因为“我知道我可以轻松地复制和粘贴,但我想知道为什么我的方法没有产生正确的输出”,所以被踩了。 - miradulo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接