c ++将罗马数字转换为小数 [英] c++ Converting roman numerals to decimals

查看:30
本文介绍了c ++将罗马数字转换为小数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个程序是我刚刚参加的考试的一部分,我必须写.我只能走到这一步,哪儿也去不了.这是提示:编写一个测试函数 toDecimal() 将罗马数字(例如 MMLXVII)转换为十进制数字表示形式.使用 Main() 测试该函数.toDecimal() 函数应该有 2 个参数,即字符串数组罗马数字和一个辅助函数.这个辅助函数将返回罗马数字中使用的每个字母的数值.然后将字符串参数转换为:查看前两个字符,如果第一个较大,则转换第一个和将其添加到总和中,然后使用第二个值再次调用转换函数并将两者相加.如果第一个字符小于第二个,则从第二个字符中减去第一个,并将结果添加到字符串的转换中.无需验证也会转换像IC"这样的字符串.验证字符串参数,如果有错误,调用错误处理函数.至少提供两个错误处理函数,并用每个函数测试 toDecimal().一个可能是要求用户rect,另一个可能会纠正它."

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 不能连续重复超过 3 次,D,L,V,不能连续重复.I 只能从 V 中减去,X,X 只能从 L 中减去而C、C只能从D和M中减去.V、L、D永远不能相减.

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.

我为此失去了大约 2 天的睡眠,尝试使用和打破规则以数百种不同的方式编写它.这是我最接近它的.

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.

推荐答案

这是我用来将 Roman(小于 3999)转换为 Integer 的代码.您可以检查它是否适用于更大的数字.

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;
}

希望能帮到你.

这篇关于c ++将罗马数字转换为小数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆