Строковая ошибка в базовом алгоритме для римских цифр (с использованием std :: map) - PullRequest
0 голосов
/ 31 декабря 2018

Я самообучаюсь себе, используя структуры данных Малика «Структуры данных и алгоритм разработки с использованием c ++».Первое упражнение состоит в том, чтобы создать объект типа numeralType и включить в него все необходимые операции, чтобы получить в строке возвращаемое ей значение в системе римских цифр.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ 1: Предположим, что существуетпроверка данных и все сделано, кроме функции, которая преобразует строку в ее значение в системе римских цифр.Кроме того, я использую VS17.

Я не буду публиковать оригинальную функцию "преобразования".Вместо этого я опубликую обобщенную версию алгоритма, используемого в функции.

здесь:

#include <iostream>
#include <string>
#include<map>


int main()
{
int result = 0;
std::map<char, int> charMap = { {'f',1},{'h',2},{'x',3},{'b',4},{'l',5} };
std::string testString = "lbxhf";
for (unsigned int i = 0; i < testString.length(); i++)
    {
        if (charMap.at(testString.at(i)) >= charMap.at(testString.at(i + 1)))
            result = charMap.at(testString.at(i)) + 
charMap.at(testString.at(i + 1));
    }
system("pause");
return 0;
}

Этот код автоматически вызывает abort(), но компилируется нормально.

Используя отладчик VS, я выделил, что причина в строке, но я не знаю точно, почему.

Используя блок try / catch, я получаю ошибку invalid string position.Вот версия try / catch:

int main()
{
    int result = 0;
    std::map<char, int> charMap = { {'f',1},{'h',2},{'x',3},{'b',4},{'l',5} };
    std::string testString = "lbxhf";

    try
    {

        for (unsigned int i = 0; i < testString.length(); i++)
        {
            if (charMap.at(testString.at(i)) >= charMap.at(testString.at(i + 1)))
                result = charMap.at(testString.at(i)) + charMap.at(testString.at(i + 1));
        }
    }
    catch(const std::out_of_range& e) 
    {
        std::cout << e.what() << std::endl;
    }

    system("pause");
    return 0;
}

Я целый день ломал голову над этим и хотел бы дать несколько советов, как решить эту проблему.

Снова, это общая версия алгоритма, который принимает строку римских цифр и возвращает ее значение в виде целого числа.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ 2: Этот алгоритм подразумевает только сложение, основанное на правилах сложения / вычитанияримская система счисления.ДИСКАЛИМЕР 3: для меня важно, чтобы я использовал std :: map, я знаю, что это можно сделать с использованием массива / векторного типа, но я также хочу попрактиковаться в использовании контейнеров stl.

Заранее спасибо (не надо быть ужасно подлыми парнями !!)

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Вот что я придумал, чтобы решить проблему и достичь своей цели:

#include<iostream>
#include<string>
#include<map>


int main()
{

    int result = 0;
    std::map<char, int> charMap = { {'f',1},{'h',2},{'x',3},{'b',4},{'l',5} };
    std::string testString("lbxhf");
    char lastChar = testString.back();
    for (unsigned int i = 0; i+1 < testString.length(); i++)
    {
        if(charMap.at(testString.at(i)) >= charMap.at(testString.at(i+1)))
            result += charMap.at(testString.at(i));
    }
    result += charMap.at(lastChar);
    printf("%i\n", result);
    system("pause");
    return 0;
}
0 голосов
/ 31 декабря 2018

Вы получаете доступ к testString.at(i + 1), но i может быть до testString.length()-1 из-за условия цикла

for (unsigned int i = 0; i < testString.length(); i++)

Это является причиной исключения за пределами допустимого диапазона.(testString.length()-1 является последним индексом testString, и повышение на один будет за пределами допустимого.)

Не уверен в своих намерениях, но, возможно, вы хотите, чтобы условие цикла было

for (unsigned int i = 0; i+1 < testString.length(); i++)

для сравнения только соседних элементов строки.

...