题目:

思路:

罗马数字小的放在大的左边是减,右边是加

以 CMLIV 为例,首先找出字符串中代表数字最大的字母,将字符串分段,即:C、M、LIV。

所以 CMLIV = M - C + LIV。

继续拆,LIV 中 L 最大,所以 LIV = L + IV,即 CMLIV = M - C + ( L + IV )。

IV 可以继续拆为 V - I,所以 CMLIV = M - C + ( L + ( V - I ) )。

将它们代表的数字代入,CMLIV = 1000 - 100 + ( 50 + ( 5 - 1 ) ) = 954。

#include <stdio.h>
#include <string.h>
#define N 7

char digits[N] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
int  values[N] = { 1 ,  5 ,  10,  50, 100, 500, 1000};

int digitsToValues (char ch) {
    for (int i=0; i<N; i++) {
        if (digits[i] == ch) {
            return values[i];
        }
    }
    return 0;
}

int findMaxIndex(char* str, int Left, int Right) {
    int max = digitsToValues(str[Left]);
    int num, maxIndex = Left;
    for (int i=Left; i<=Right; i++) {
        num = digitsToValues(str[i]);
        if (num > max) {
            max = num;
            maxIndex = i;
        }
    }
    return maxIndex;
}

int romanToNumber(char* str, int Left, int Right) {
    if (Left == Right) {
        return digitsToValues(str[Left]);
    }
    else if (Left > Right) {
        return 0;
    }
    else {
        int maxIndex = findMaxIndex(str, Left, Right);
        int max = digitsToValues(str[maxIndex]);
        int L = romanToNumber(str, Left, maxIndex-1);
        int R = romanToNumber(str, maxIndex+1, Right);
        return max - L + R;
    }
}

int romanToInteger(char* str) {
    int Left = 0, Right = strlen(str) - 1;
    return romanToNumber(str, Left, Right);
}

int main()
{
    char str[] = "MMXIX";
    int result = romanToInteger(str);
    printf("result = %d\n", result);
    return 0;
}

结果:


参考:【一起玩算法】罗马数字转阿拉伯数字

推荐一位干货up主:正月点灯笼