Roman to Integer
题目:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
解题:
首先我们先观察罗马数字的规律
罗马数字共有七个,即I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。按照下面的规则可以表示任意正整数。
重复数次:一个罗马数字重复几次,就表示这个数的几倍。
右加左减:在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。但是,左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。
加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000倍。
单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。
MMMCMXCIX,3999
知道了这些,接下来就可以解题了
#include <iostream>
using namespace std;
class Solution {
public:
int romanToInt(string s) {
int a[7] = {1,5,10,50,100,500,1000};
string p[7] = {"I","V","X","L","C","D","M"};
if(s=="")return 0;
for(int i=0;i<7;i++){
if(s==p[i]){
return a[i];
}
}
char r[7] = {'I','V','X','L','C','D','M'};
//I(1),V(5),X(10),L(50),C(100),D(500),M(1000)
int final=0,start=0;
int result = 0;
//截取字符串s2 = s1.substr(0,3);起始位置和截取的长度
int i;
for(i = 7;i>=0;i--){
int flag = 0;
for(int j=0;j<s.length();j++){
if(s.at(j)==r[i]&&flag == 0)//比较自负相等
{
final = j-1;//注意final可能为负数
flag = 1;//跟踪
}
if(flag==1){
if(s.at(j)!=r[i]) break;
start = j+1;//start 可能超出范围
}
}
if(start!=final)
break;
}
unsigned long aLength=0,bLength=0;
aLength = final<0 ? 0:final+1;
bLength = start>s.length()-1 ? 0:s.length()-start;
result = -romanToInt(s.substr(0,aLength))+romanToInt(s.substr(start,bLength))+(start-final-1)*a[i];
return result;
}
};
int main(int argc, const char * argv[]) {
Solution a;
cout<<a.romanToInt("MMMCMXCIX")<<endl;
return 0;
}
最后accepted
哈哈