c++ Converting roman numerals to decimals

c++, visual-c++

Solution

This is the code that I use to convert Roman (smaller than 3999) to Integer. You may check if it works for larger numbers.

int romanToInt(string s) {
    map<char, int> roman;
    roman['M'] = 1000;
    roman['D'] = 500;
    roman['C'] = 100;
    roman['L'] = 50;
    roman['X'] = 10;
    roman['V'] = 5;
    roman['I'] = 1;

    int res = 0;
    for (int i = 0; i < s.size() - 1; ++i)
    {
        if (roman[s[i]] < roman[s[i+1]])
            res -= roman[s[i]];
        else
            res += roman[s[i]];
    }
    res += roman[s[s.size()-1]];
    return res;
}

Hope this could help you.

Problem

This program is a part of an exam I just took, that I had to write. I only got this far and couldn't get anywhere. Here is the prompt:"Write a Test Function toDecimal() that converts a roman numeral such as MMLXVII to it's decimal number representation. Use Main() to test the function. The toDecimal() function should have 2 arguments, the string array of roman numerals and a helper function. This helper function will return the numeric value of each of the letters used in roman numbers. Then convert the string arguments as so: Look at the first two characters,if the first is larger, convert the first and add it to the summation, then call the conversion function again with the second value and add both. IF the first character is lesser than the second subtract the first from the second, and add the result to the conversion of the string. without validation it will also convert strings like "IC". VAlidate the string arguement, if there is an error, call the error processing function. Provide at least two error processing functions and test toDecimal() with each. One could be adking the user to correct, the other may correct it." I,X,C,M cannot be repeated more than 3 times in succession, D,L,V, can never be repeated in succession.I can only be subtracted from V and X,X can only be subtracted from L and C, C can only be subtracted from D and M. V, L, and D can never be subtracted. I've lost about 2 days worth of sleep on this, tried writing it hundreds of different ways using and breaking the rules. This is the closest I've got on it. ``` #include <iostream> #include <string> #include <map> #include <algorithm> #include <cstring> using namespace std; bool checker(string roman); // Adds each value of the roman numeral together int toDecimal(string, bool* (*function)(string)); int convert(string roman, int i); int main(){ string roman; cout << "This program takes a roman numeral the user enters then converts it to decimal notation." << endl; cout << "Enter a roman numeral: "; cin >> roman; transform(roman.begin(), roman.end(), roman.begin(), toupper); cout << roman << " is equal to " << toDecimal(roman, *checker(roman)) << endl; } bool checker(string roman){ int length = roman.length(); for (int count = 0; count < length; count++){ string sub = roman.substr(count, count); if(sub != "I" || sub != "V" || sub != "X" || sub != "L" || sub != "C" || sub != "D" || sub != "M"){ cout << "Error. Try Again"<< endl; return false; } else if(convert(roman, count) == convert(roman, count-1) && convert(roman, count) == convert(roman, count+1)){ if (convert(roman,count) == 1 || convert(roman,count) == 10 || convert(roman,count) == 100 || convert(roman,count) == 1000) if(convert(roman, count-1) == convert(roman, count-2) || convert(roman, count+1) == convert(roman, count+2)){ cout << "Error Try again" << endl; return false; } else if (convert(roman,count) == 5 || convert(roman,count) == 50 || convert(roman,count) == 500){ cout << "Error Try again" << endl; return false; } else return true; } } return true; } int toDecimal(string s, bool*(checker) (string roman)){ /**map<char, int> roman; roman['M'] = 1000; roman['D'] = 500; roman['C'] = 100; roman['L'] = 50; roman['X'] = 10; roman['V'] = 5; roman['I'] = 1;*/ checker(s); int res = 0; for (int i = 0; i < s.length() - 1; ++i){ int num = convert(s,i); res += num; /**if (roman[s[i]] < roman[s[i+1]]) res -= roman[s[i]]; else res += roman[s[i]]; } res += roman[s[s.size()-1]];*/} return res; } int convert(string roman, int i){ enum romans {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}; int num = 0; char c = roman[0]; switch(c){ case 'M': num = M; break; case 'D': if(i + 1 != roman.size() && roman[i+1] == 'M'){ num = M - D;break; } else num = D; break; case 'C': if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D'){ if(roman[i+1] == 'M') num = M - C; break; if(roman[i+1] == 'D') num = D - C; break; } else num = C; break; case 'L': if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'){ if(roman[i+1] == 'M') num = M - L; break; if(roman[i+1] == 'D') num = D - L; break; if(roman[i+1] == 'C') num = C - L; break; } else num = L; break; case 'X': if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L'){ if(roman[i+1] == 'M') num = M - X; break; if(roman[i+1] == 'D') num = D - X; break; if(roman[i+1] == 'C') num = C - X; break; if(roman[i+1] == 'L') num = C - X; break; } num = X; break; case 'V': if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L' || roman[i+1] == 'X'){ if(roman[i+1] == 'M') num = M - V; break; if(roman[i+1] == 'D') num = D - V; break; if(roman[i+1] == 'C') num = C - V; break; if(roman[i+1] == 'L') num = L - V; break; if(roman[i+1] == 'X') num = X - V; break; } num = V; break; case 'I': if ( i + 1 != roman.size() && roman[i + 1] != 'I'){ if(roman[i+1] == 'M') num = M - I; break; if(roman[i+1] == 'D') num = D - I; break; if(roman[i+1] == 'C') num = C - I; break; if(roman[i+1] == 'L') num = L - I; break; if(roman[i+1] == 'X') num = X - I; break; } num =1; break; } return num; } ``` ** I have added the help of people on here. This is an edit to show an progress/congress.

Original source