1

我正在解决一个问题,其中任务是在用户提到的给定行输出帕斯卡三角形的结果。

https://leetcode.com/problems/pascals-triangle-ii/

我编写了我的解决方案,该解决方案在存储大量阶乘结果时存在问题。

vector<int> getRow(int rowIndex) {

             vector<int> v;

             int C = 1; 
             v.push_back(1);

                for (int i = 1; i <= rowIndex; i++)  
                {
                  printf("%d ", C);  
                  C = C * (rowIndex +1 - i) / i;
                  v.push_back(C);
                }

  return v;
}

在经历这些问题时,

整数类型可以在 C++ 中存储的值范围是多少

unsigned long long 有多少字节?

并通过其他一些来源,我进行了以下更改,这给了我所需的结果。

    C = (unsigned long long)C * (rowIndex +1 - i) / i;

由于“C”是int类型并且我的向量 v 存储int,我想知道为什么强制转换unsigned long long仍然会给我有效的结果。

4

2 回答 2

3

子表达式C * (rowIndex +1 - i)可以在除法之前溢出。通过转换C为更大的数据类型,整个表达式将变为该类型,因此乘法不会溢出。然后在除法之后i将结果再次转换为 an int,但由于除法,它在 an 的范围内int

请注意,这仅适用于您当前拥有的值。如果您继续使用更高的值,那么迟早您将出现无法通过这种强制转换修复的溢出。

于 2016-11-21T07:42:48.770 回答
1

当你说

(unsigned long long)C

您没有将实际变量 C 设为 unsigned long long。你只是说这样做的时候

C * (rowIndex +1 - i) / i;

将 C(在右侧)视为 unsigned long long。也就是说,只有临时空间存放 C,然后存放它与 (rowIndex +1 - i) 的乘法,然后它与 i 的除法在那么大的空间完成。如果整个结果大于整数可以具有的值,这也不起作用。

于 2016-11-21T07:51:47.973 回答