将罗马数字转换为整数

时间:2014-01-30 05:29:40

标签: matlab

对于计算机科学作业,我的目标是将字符串(罗马数字)转换为整数。我要在Matlab中编写一个函数来完成这个。我的代码如下所示。

function [x] = roman2decimal(s)
s1 = substr1(s,1);
s2 = substr2(s,2,2);
s = substr2(s, 3, numel(s));
sum = 0;
if (s1~='')
%Case I - if any of these conditions are true
if (s1=='C' && s2=='M')
    sum = sum + 900;
end
if (s1=='C' && s2=='D')
    sum = sum + 400;
end
if (s1=='X' && s2=='C')
    sum = sum + 90;
end
if (s1=='X' && s2=='L')
    sum = sum + 40;
end
if (s1=='I' && s2=='X')
    sum = sum + 9;
end
if (s1=='I' && s2=='V')
    sum = sum + 4;
end
s=s1
s2=substr2(s, 3, numel(s))

end

% case 2 - no case 1 conditions were true
if(s1=='M')
    sum = sum + 1000;
end

if(s1=='D')
    sum = sum + 500;
end

if(s1=='C')
    sum = sum + 100;
end

if(s1=='L')
    sum = sum + 50;
end

if(s1=='X')
    sum = sum + 10;
end

if(s1=='V')
    sum = sum + 5;
end

if(s1=='I')
    sum = sum + 1;
end
s1=s2
s=s2
sum
end


function [c]=substr1(s,pos)
if(pos >= 1 && numel(s) >= pos) c=s(pos);
else c='';
end
end % substr1

function [c]=substr2(s,pos1,pos2)
if(pos1 >=1 && pos2 >= pos1 && pos2 <= numel(s)) c=s(pos1:pos2);
else c='';
end
end % substr2

我遇到的问题是当我为函数调用长度超过2个字符的字符串时,s1总是计算字符串中的第二个字符,例如对于'CM's1 = M,s2 = M。

如果我在此函数之外调用substr1函数,它可以正常工作(例如,返回字符串中的第一个字符)。

我想知道我的算法/语法是否有问题以及你是否可以提供帮助?

非常感谢。

2 个答案:

答案 0 :(得分:7)

这是@Robert启发的答案,但却完全不同:

myStr = 'MCMLXXXVIII';

key = 'MDCLXVI';
values = [1000, 500,100,50,10,5,1];

% Calculate the 'weight' of each letter
[~, loc]=ismember(myStr,key)    
relevantValues = values(loc);

% Determine whether we should substract or add
s = [-sign(diff(relevantValues)), 1];
%% To avoid zeros in s    
while ~all(s)
   f = find(s == 0);
   s(f) = s(f+1);
end

s*relevantValues'

这种向量化方法可以最大限度地减少字符串操作的数量,并避免使用eval语句。

答案 1 :(得分:1)

This solution is in C and has passed all the 3999 test cases in LeetCode

int romanToInt(char* s) {

    int i = 0, value = 0;

    for (int i =0; s[i] != '\0'; i++)
    {
        switch(s[i]) {
            case 'I':
            if(s[i+1] != '\0' ){
            if(s[i+1] == 'V' ||s[i+1] == 'X' )
            value = value -1;
            else 
            value = value+1;
            }else {
            value = value+1;
            }

            break;

            case 'V':
            value = value + 5;
            break;

            case 'X':
            if(s[i+1] != '\0' ){
            if(s[i+1] == 'L' ||s[i+1] == 'C' )
            value = value -10;
            else 
            value = value+10;
            }else {
            value = value+10;
            }
            break;

            case 'L':
            value = value + 50;
            break;

            case 'C':
            if(s[i+1] != '\0' ){
            if(s[i+1] == 'D' ||s[i+1] == 'M' )
            value = value -100;
            else 
            value = value+100;
            }else {
            value = value+100;
            }
            break;

            case 'D':
            value = value + 500;
            break;

            case 'M':
            value = value + 1000;
            break;



        }


    }
    return value;


}