当我输入极长的字符串以获取子字符串时,已调用 C++ Abort()

Posted

技术标签:

【中文标题】当我输入极长的字符串以获取子字符串时,已调用 C++ Abort()【英文标题】:C++ Abort() has been called when I input extremely long string to get substring 【发布时间】:2020-03-28 05:17:49 【问题描述】:

https://www.hackerrank.com/challenges/sam-and-substrings/problem

这是我正在解决的问题,我遇到了问题。

这是我的代码

#include <string>
#include <iostream>
#include <vector>
double const modulo = 1000000007;

int main()

    std::string n("");
    std::cin >> n;
    long sum(0);
    std::vector<std::string> newlyAddedSubstring;

    for (auto i : n)
    
        for (auto &j : newlyAddedSubstring)
        
            j += i;
            long d = std::fmod(std::stod(j), modulo);
            sum = std::fmod(sum + d, modulo);
        
        newlyAddedSubstring.push_back(std::string(1, i)); 
        newlyAddedSubstring.back();
        sum = std::fmod(sum + (i - '0'), modulo);
    
    std::cout << sum << std::endl;

这是输入的一部分,输入实际上是 1003 大小 630078954945407486971302572117011329116721271139829179349572383637541443562605787816061110360853600744212572072073871985233228681677019488795915592613136558538697419369158961413804139004860949683711756764106408843746324318507090 ... P>

在大约 327 次重复之前没有问题(即 newAddedSubstring 的大小约为 327),但在

上出现问题
long d = std::fmod(std::stod(j), modulo);

任何 cmets 或反馈将不胜感激!!

【问题讨论】:

请自行编译运行程序,你会得到比“abort() 已被调用”更好的错误信息。 【参考方案1】:

如果std::stod 从字符串中解析的值超出double 可以容纳的值范围,则std::out_of_range 抛出异常。

典型的double 实现可以容纳的最大值大约为 300 位。你的数字比那个大。

因此抛出异常,因为您没有捕获它,所以调用std::terminate,默认情况下调用std::abort,终止程序。

您不能在double 中存储如此大的数字。您可以尝试使用std::stold,它会尝试将数字解析为long double可能大于double,并且可能能够保持您的值。

此外,一般来说,浮点值不能准确地表示整数。因此,像您一样对doublelong double 进行模运算是毫无意义的。它不会给出准确的结果,而且对于非常大的值基本上会生成随机值。

如果你想对这么大的整数做精确的模运算,你需要一个任意大小的整数库,或者你需要自己实现模运算。

【讨论】:

以上是关于当我输入极长的字符串以获取子字符串时,已调用 C++ Abort()的主要内容,如果未能解决你的问题,请参考以下文章

c ++在字符串中查找重复的子字符串

G1 GC - 极长的终止时间

极长的“不在”请求

无法从 iOS 中的 UITextView 获取已删除的字符

Azure 存储容器命令运行时间极长

我的 C 程序不断崩溃