Обращенный номер C ++ с использованием to_string, reverse, stoi combo, дающий ошибку во время выполнения Instance Out of Range - PullRequest
0 голосов
/ 05 ноября 2019

Зависание при попытке устранить ошибку времени выполнения из-за исключения экземпляра вне диапазона. Я беру int в строку, обращаю строку и возвращаю ее в int, используя stoi. Простые тестовые числа полностью изменяются, но большие числа находятся вне диапазона. Не уверен, где в коде настроить исключение вне диапазона. Супер застрял, пожалуйста, помогите.

int reverse(int x) {

    bool negFlag = false;
    if(x < 0)
    {
        negFlag = true;
    }

    string xString = std::to_string(abs(x));
    std::reverse(xString.begin(), xString.end());
    int xNum = std::stoi(xString);

    return (negFlag == true)? -xNum: xNum;
}

Вот возвращенная ошибка:

terminate called after throwing an instance of 'std::out_of_range'
what():  stoi
Last executed input:  1534236469

Меньшее число хорошо работает.

Your input: 123
Output:     321
Expected:   321

Есть ли \ 0 в конце моей строкито есть скинуть все в конверсии? Новое в этих методах C ++. Спасибо. Очень хотелось бы закрепить эти методы и легко их использовать.

Жизненно важная информация:

Note: Assume we are dealing with an environment which could only store 
integers within the 32-bit signed integer range: 

[- 2 31 to +2 31 -1]

For the purpose of this problem, assume that your function returns 0 when 
the reversed integer overflows.

- >> Не уверен, как сформулировать оператор if, который будет возвращать 0;при превышении 32-битного.

Ответы [ 3 ]

1 голос
/ 05 ноября 2019

Обратное значение 1,534,236,469 равно 9,646,324,351. Максимальное значение, которое может хранить типичный 32-битный int, равно 2,147,483,647, поэтому оно не вписывается в него.

Вам необходимо, чтобы ваша функция возвращала что-то большее, например, long long (что вминимум 64 бита) и используйте для него соответствующую функцию преобразования, например:

long long reverse(int x) {

    //...

    long long xNum = std::stoll(xString);

    //...

}

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


После редактирования:

Вы можете отследить ошибку преобразования и вернуть 0 в этом случае (требуется #include<stdexcept>):

try {
    int xNum = std::stoi(xString);
    // Maybe insert additional range test according to assignment (?)
    return (negFlag == true)? -xNum: xNum;
} catch(const std::out_of_range&) {
    return 0;
}

Предполагая, что int является 32-битным дополнением до двух (что, как я понимаю, назначение пытается предложить с диапазоном значений, который предположительно должен быть [-2**31, 2**31-1]):

Также обратите вниманиечто ваш начальный вызов abs имеет неопределенное поведение, если x == -2**31, потому что 2**31 не может быть представлен в 32-битном int. Поэтому перед тем, как вызвать abs, нужно сначала сделать специальный случай для этого, чтобы избежать неопределенного поведения.

Аналогичным образом вам нужно рассмотреть случай, когда результат функции должен быть -2**31. Но вы можете заметить, что этот случай не имеет значения, потому что его соответствующее входное значение уже выйдет за пределы int.

0 голосов
/ 05 ноября 2019

Преобразование целого числа в строку и обращение к нему, вероятно, не лучший ответ на это назначение, а также, вероятно, «обман» (@ n-местоимение-m). Вместо этого вы можете использовать простой цикл:

int reverse(int x)
{
    bool negFlag = false;
    if (x < 0)
    {
        negFlag = true;
        x = -x;
    }

    int xNum = 0;
    int prevNum = 0;
    while (x != 0)
    {
        int curr_digit = x % 10;

        xNum = (xNum * 10) + curr_digit;

        //Check for integer overflow by checking if
        //reverse of the operation above != prevNum
        if ((xNum - curr_digit) / 10 != prevNum)
        {
            return 0;
        }

        //Store this number for comparing in next iteration
        prevNum = xNum;
        x = x / 10;
    }

    return (negFlag == true) ? -xNum : xNum;
}

Примечание. Я изменил свой ответ после того, как понял, что вам нужно проверить целочисленное переполнение.

0 голосов
/ 05 ноября 2019

Диапазон ввода больше, чем может удержать int. Измените его на long long, и оно должно работать.

long long reverse(long long x) {

bool negFlag = false;
if(x < 0)
{
    negFlag = true;
}

string xString = std::to_string(abs(x));
std::reverse(xString.begin(), xString.end());
long long xNum = std::stoll(xString);

return (negFlag == true)? -xNum: xNum;
}

Обратите внимание, что тип возвращаемого значения также необходимо изменить.

...