C ++ Abort () был вызван, когда я вводил очень длинную строку, чтобы получить подстроку - PullRequest
0 голосов
/ 28 марта 2020

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 ...

1012 * он не имеет никаких проблем, пока около 327 повторений (т.е. размера newlyAddedSubstring составляет около 327), но он получил вопрос о
long d = std::fmod(std::stod(j), modulo);

Любые комментарии или отзывы будут с благодарностью!

1 Ответ

3 голосов
/ 28 марта 2020

std::stod выдает исключение std::out_of_range, если значение, которое оно проанализировало из строки, выходит за пределы диапазона значений, которые может содержать double.

Наибольшее значение, которое типичная реализация double может содержать около 300 цифр. Ваш номер больше этого.

Поэтому выдается исключение, и потому что вы его не перехватываете, вызывается std::terminate, который по умолчанию вызывает std::abort, завершая программу.

Вы не можете хранить такое большое число в double. Вместо этого вы можете попробовать std::stold, который попытается проанализировать число как long double, которое может быть больше double, а может удерживать ваше значение.

Кроме того, в общем случае значения с плавающей точкой не могут представлять целые числа точно . Поэтому бессмысленно делать операцию по модулю double или long double, как вы делаете. Он не даст точного результата, а для очень больших значений по существу сгенерирует случайные значения.

Если вы хотите сделать точное значение по модулю для такого большого целого числа, вам нужна целочисленная библиотека произвольного размера или вы должны реализовать Операция по модулю самостоятельно.

...