将大整数与数字相乘。我的代码有什么问题?

时间:2019-01-15 16:56:34

标签: c++ c++14

我正在尝试在SPOJ中解决FCTRL2。该程序应该能够计算最多100个数字的阶乘。

为了解决这个问题,我应该能够将大数相乘。为此,我将数字写为字符串,并应用了年级乘法。我的代码中有一个帮助函数,称为multiple1,该函数将大量数字与数字相乘。这是代码:

#include <iostream>
#include <string>
using namespace std;
string multiply1(string sx, string sy)
{
    string res(sx.size() + 1, 'x');
    int rem = 0;

    for (int i = sx.size() - 1; i >= 1; i--)
    {
     int ix = sx[i] - '0';
     res[i + 1] = ((ix*(sy[0] - '0') + rem) % 10);
     res.replace(i + 1, i + 2, to_string((ix*(sy[0] - '0') + rem) % 10));
     rem = (ix - (ix % 10)) / 10;

    }
    int ix = sx[0] - '0';
    string last = to_string(ix*(sy[0] - '0') + rem);
    if (last.size() == 1)
    {
        res[1] = last[0]; string res2; 
        for (int i = 1; i < res.size(); i++) 
        { 
            res2[i - 1] = res[i]; 
        }
        return res2; 
    }
    else 
    { 
        res[1] = last[1]; 
        res[0] = last[0]; 
        return res; 
    }
    return res;

}

int main() 
{

    cout << multiply1("155557452", "3");
    return 0;
}

但是我一直收到此错误:

Debug Assertion Failed!

Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\xstring
Line: 2944

Expression: string subscript out of range

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

“调试断言失败”是什么意思,如何解决此错误?

1 个答案:

答案 0 :(得分:3)

当您使用Microsoft Visual Studio调试在“调试模式”下编译的程序时,您的代码中添加了许多检查以阻止未定义的代码或在程序中设置不正确的代码。 “调试断言失败”是在检测到调试运行时库明确测试的这些常见错误之一时收到的通用消息。

您需要关心的实际消息在错误中出现了几行:

Expression: string subscript out of range

告诉您您正在尝试访问字符串范围之外的内容。

我最好的猜测是可疑行是这段代码:

if (last.size() == 1)
{
    res[1] = last[0]; string res2; 
    for (int i = 1; i < res.size(); i++) 
    { 
        res2[i - 1] = res[i]; 
    }
    return res2; 
}
声明了

res2,但从未分配或更改其大小。您的代码仅假设字符串具有容量,并尝试在其中分配字符。那是未定义的行为,但是因为您的编译器正在尝试帮助您,所以它将其声明为引发异常的已定义行为,并且不会捕获该异常。

看起来res2的大小应该等于res的大小减去1,所以我的建议是在此代码中手动调整res2的大小:

if (last.size() == 1)
{
    res[1] = last[0]; string res2; 
    res2.resize(res.size() - 1);
    for (int i = 1; i < res.size(); i++) 
    { 
        res2[i - 1] = res[i]; 
    }
    return res2; 
}

这应该修复不良行为的特定情况。

我还建议您扫描其余代码,以查找类似的错误。


另一件事。似乎您正在编写自己的任意精度整数算法。如果这是学校任务的一部分(或者只是您要教自己的事情),请继续使用我在此处提供的建议进行研究。

但是,如果这是针对爱好项目或专业项目的,我建议您改用完善的任意精度算术库,而不要尝试重新发明轮子。我建议根据您作为开发人员的需要使用boost.multiprecision或GMP。