求和大量非常大数的算法(C ++)

时间:2017-06-25 06:52:22

标签: c++ algorithm

我正在尝试解决Problem 13 @ Project Euler,我正在寻找一个好的算法来做添加并输出非常大的数字的答案。首先,我将数字的数字转换为矩阵的元素(100 x 50)。这是我提出的算法:

unsigned long long int sum=0, carry_over=0;
for(int j=49; j>=0; j--)
{
    for(int i=0; i<100; i++)
        sum+=num[i][j];
    sum+=carry_over;
    carry_over=sum/10;
    cout<<sum%10;
    sum=0;
}
cout<<carry_over;  

现在,输出将有反转的数字,从单位放置数字开始,最后是总和的第一个数字。这很容易手动逆转。

我想知道这是一个好的算法,考虑准确性和速度。请建议更正以改善它。

1 个答案:

答案 0 :(得分:0)

您的算法已经是最优的。

您的算法的时间复杂度为O(m*n),其中m是每个数字中的位数(50),n是数字的数量(100),以及#39; s输入中的数字位数。很容易看出你必须从输入中读取所有数字才能输出正确的答案,所以你必须至少阅读m*n位数,给出时间复杂度O(m*n) 只是用于读取输入。因此,算法的时间复杂度不能低于此值,因此您的O(m*n)算法是最佳的。

如果不知何故,你已经在RAM中(并以合适的格式)输入数据,你可以考虑其他一些优化。

考虑地址大小:

现代计算机的地址大小为32或64位,这意味着它们可以在一次操作中对32位或64位进行加法。 64位是大约18个十进制数字,因此存储每个整数所需的3个64位整数,因此加法的时间复杂度将从m=50减少到m=3,从而得到求和快一个数量级。

考虑并行处理:

现代计算机可以并行运行多个线程。这个问题的解决方案很容易并行化。如果您的机器能够同时运行2个线程,您可以使用第一个线程对前50个数字求和,使用第二个线程对第二个50进行求和。在两个总和完成之后(如果在一个线程上计算所有内容,大约需要一半的时间),您只需将两个子结果相加。