Как пофиксить runtime error? c++

В общем. Изучаю С++, решаю задачи (в данный момент, пытался решить задачу 7 на acmp). Вроде все шло хорошо, но появилась проблема Runtime Error.

Задача:

Главный вождь племени Абба не умеет считать. В обмен на одну из его земель вождь другого племени предложил ему выбрать одну из трех куч с золотыми монетами. Но вождю племени Абба хочется получить наибольшее количество золотых монет. Помогите вождю сделать правильный выбор!

В первой строке входного файла INPUT.TXT записаны три натуральных числа через пробел. Каждое из чисел не превышает 10100. Числа записаны без ведущих нулей. Выходные данные В выходной файл OUTPUT.TXT нужно вывести одно целое число — максимальное количество монет, которые может взять вождь. (input.txt и output.txt можно опустить. input.txt - польз. ввод, output.txt - вывод в консоль)

Вот код:

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::cin;

int main() {
    string num1Str, num2Str, num3Str;
    cin >> num1Str >> num2Str >> num3Str; // Ввод чисел в строковом формате

    long long num1 = std::stoll(num1Str);
    long long num2 = std::stoll(num3Str);
    long long num3 = std::stoll(num3Str);


    if (num3 >= num2 && num3 >= num1) {
        cout << num3;
    }
    else if (num2 >= num1 && num2 >= num3) {
        cout << num2;
    }
    else if (num1 >= num2 && num1 >= num3) {
        cout << num1;
    }
    return 0;
}

Пытался решать просто используя string, но нашел проблему: при вводе числа 300, оно автоматически становится самым большим. Как я понял, это получается из-за того, что С++ сравнивает строки не как числа, а по лексикографическому принципу.

Так вот, как тогда правильно сравнить числа? (использую строки, ибо число может быть в диапазоне до 10^100, и никакое из числовых форматов не может быть в таком диапазоне)

новый код:

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::cin;

int main() {
    string num1, num2, num3;
    cin >> num1 >> num2 >> num3; // Ввод чисел в строковом формате

    if (num3.length() > num2.length() && num3.length() >= num1.length()) {
        cout << num3;
    }
    else if (num2.length() >= num1.length() && num2.length() >= num3.length()) {
        if (num2.length() > num3.length() || (num2.length() == num3.length() && num2 >= num3)) {
            cout << num2;
        }
    }
    else if (num1.length() >= num2.length() && num1.length() >= num3.length()) {
        if (num1.length() > num2.length() || (num1.length() == num2.length() && num1 >= num2)) {
            cout << num1;
        }
    }
    else if (num1 == num2 && num1 == num3) {
        cout << num1; // Все числа равны
    }

    return 0;
}

Ответы (3 шт):

Автор решения: maestro

Вы правильно заметили, что ни один из целочисленных типов не может вместить числа в диапазоне до 10100. Поэтому вы приняли правильное решение работать со строками. А строки действительно сравниваются по лексикографическому принципу: строка считается меньше другой, если находится раньше по алфавиту.

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

→ Ссылка
Автор решения: Harry

Ну, вот сравнение двух таких чисел на С++. Проверка, что там только строки из цифр без ведущих нулей, не делается.

int uint_compare(const string& a, const string& b)
{
    if (a.size() < b.size()) return -1;
    if (a.size() > b.size()) return  1;
    return a.compare(b);
}

-1 — a < b
+1 — a > b
0 — a == b

→ Ссылка
Автор решения: Stanislav Volodarskiy

Для примера из комментария 99, 2, 17 ваша программа печатает 17. Ошибка.

Направление верное, только надо разбить задачу на две: выбор максимума из пары чисел-строк и выбор максимума из большего количества чисел.

Сравнить два числа в виде строк можно так:

  • если они разной длины, больше то в котором цифр больше;
  • если они одной длины, больше то, которое больше как строка (порядок чисел и порядок строк в этом случае совпадают).
#include <string>
#include <iostream>

const std::string &n_max(const std::string &n1, const std::string &n2) {
    if (n1.size() < n2.size()) {
        return n2;
    }
    if (n1.size() > n2.size()) {
        return n1;
    }
    if (n1 < n2) {
        return n2;
    }
    return n1;
}

int main() {
    std::string max = "0";
    for (int i = 0; i < 3; ++i) {
        std::string n;
        std::cin >> n;
        max = n_max(max, n);
    }
    std::cout << max << '\n';
}
→ Ссылка