将罗马数字转换为小数c ++

时间:2017-09-16 22:08:08

标签: c++

我试图将罗马数字转换为c ++中的小数。

所以我的代码应该将罗马字节转换为小数,但它并不完全正常。

例如,VI为4,IV为6 MCMXLVI应该会产生1946年,但如果我从左到右,我会得到-998,如果我从右到左,我会得到0。

我主要想知道我的思维过程是否正确。

伪代码:

total = 0
    max_value_so_far = 0
    for each character in the input string, going from right to left:
        if character converted to decimal >= max_value_so_far
            add character converted to decimal to total
            update max_value_so_far
        otherwise subtract character converted to decimal from total 

代码:

#include "std_lib_facilities_5.h"

string convert_string( string input){

    for(int i=0; i < input.length(); i++){
        input[i] = toupper(input[i]);
    }

    return input;
}

int roman_to_int(string RomanChars){

    RomanChars = convert_string(RomanChars);

    int total = 0;
    int max_value= 0;
    int M,D,C,L,X,V,I;
    M = 1000;
    D = 500;
    C = 100;
    L = 50;
    X = 10;
    V = 5;
    I = 1;

    double StringLength =RomanChars.length();

    for( int i = 0; i < StringLength; i++){

        if(RomanChars[i] == 'M') {
            if (M >= max_value) {
            total += M;
            max_value = M;
            }  else {
            total -= M;
            }
        }
        if(RomanChars[i] == 'D') {
            if (D >= max_value) {
                total += D;
                max_value = D;
            }  else {
                total -= D;
            }
        }
        if(RomanChars[i] == 'C') {
            if (C >= max_value) {
                total += C;
                max_value = C;
            }  else {
                total -= C;
            }
        }
        if(RomanChars[i] == 'L') {
            if (L >= max_value) {
                total += L;
                max_value = L;
            }  else {
                total -= L;
            }
        }
        if(RomanChars[i] == 'X') {
            if (X >= max_value) {
                total += X;
                max_value = X;
            }  else {
                total -= X;
            }
        }
        if(RomanChars[i] == 'V') {
            if (V >= max_value) {
                total += V;
                max_value = V;
            }  else {
                total -= V;
            }
        }
        if(RomanChars[i] == 'I') {
            if (I >= max_value) {
                total += I;
                max_value = I;
            }  else {
                total -= I;
            }
        }
    }
    return total;
}

int main() {

    string character;
    int conversion = 0;

    while(cin >> character){

         conversion = roman_to_int(character);
         cout << conversion <<endl;
    }
    return 0;
}

2 个答案:

答案 0 :(得分:3)

你教授提供的算法是正确的。

一些提示:

for( double i = 0; i < RomanChars.length(); i++){
  • 那个从左到右循环。错误的方向。
  • double?作为循环变量?不要那样做。 (不是问题的原因,但是baaad)

另一个答案已经指出你的别人是错的。如果我是你,我会考虑找到优雅的东西来取代这个副本并粘贴狂欢。

如果您愿意 - 只是为了灵感 - 将您的罗马数字文字值存储在std :: map中,您的转换循环看起来与此类似(我的示例中的std :: map是std::map<char, int> conversion ):

int roman_to_int(std::string RomanChars){

    RomanChars = convert_string(RomanChars);

    int total = 0;
    int max_value= 0;

    for( size_t i = RomanChars.length()-1; i != std::string::npos; --i){ 

        auto val = conversion.find(RomanChars[i]);
        if(val != conversion.end())
        {
            if(val->second >= max_value)
            {
                total += val->second;
                max_value = val->second;
            } else {
                total -= val->second;
            }
        }
    }
    return total;
}

答案 1 :(得分:1)

对于您的每个if测试,由于您认为else块没有被执行,您会收到错误。

        if(RomanChars[i] == 'M' && M >= max_value){
            total += M;
            max_value = M;
        } else {
            total -= M; // this got executed for each character
                        // in the input sequence which is *not* M!
        }

应该是

        if (RomanChars[i] == 'M') {
            if (M >= max_value) {
                total += M;
                max_value = M;
            } else {
                total -= M;
            }
        }

更好的是:

switch (RomanChars[i])
{
case 'M':
    if (M >= max_value) {
        max_value = M;
        total += M;
    } else {
        total -= M;
    }
    break;
// ...

更好的是,用

重构代码
#include<map>
const std::map<char, unsigned> romans_definition = {
    { 'I', 1 },
    { 'V', 5 },
    { 'X', 10 },
    { 'L', 50 },
    // ...
};