c++ Converting roman numerals to decimals
08:44 18 Jul 2013

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 problem description:

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

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 less than the second, subtract the first from the second, and add the result to the conversion of the string. Without validation this will also convert strings like "IC".

Validate the string argument, and, 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 asking the user to correct; the other may correct it.

  • I, X, C, and M cannot be repeated more than 3 times in succession.
  • D, L, and 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 gotten on it.

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

c++ visual-c++