先写一下1-10的罗马数字
1 -->> I
2 -->> II
3 -->> V
4 -->> IV (注意,不能写成 IIII)
5 -->> V
6 -->> VI
7 -->> VII
8 -->>VIII (注意,不能写成 IIX)
9 -->>IX
10 -->> X
百度阿拉伯数字的规则我们知道,要将阿拉伯数字转化成罗马数字,先找到一个字符串中最大的数,然后减去左边,再加上右边,
因为左边的比它小,右边的比它大。
第一步就是将单个的字符转化为数字------->>
const int N = 100;
char digits[N] = { 'I','V','X','L','C','D','M' };
int value[N] = { 1,5,10,50,100,500,1000 };
int digitsToValue(char ch) {
int i;
for (i = 0; i < N; i++) {
if (digits[i] == ch) return value[i];
}
//异常处理
return 0;
}
第二步就是在字符串中找到最大的数的位置----->>
int FindMaxPosition(string str, int L, int R)
{
int i;
int _max = -999,MaxPosition=-1;
int getvalue = -1;
for (i = L; i <= R; i++)
{
getvalue = digitsToValue(str.at(i));
if ( getvalue > _max) {
_max = getvalue;
MaxPosition = i;
}
}
return MaxPosition;
}
第三步就是罗马数字转化为阿拉伯数字了----->>
int RomanToNumer(string str, int L, int R)
{
//单个数字的处理
if (L == R) return digitsToValue(str.at(L));
//递归异常处理的结果
else if (L > R) return 0;
int _maxposition = FindMaxPosition(str,L,R);
int a, b,MAX;
MAX = digitsToValue(str.at(_maxposition));
//递归处理左边
a = RomanToNumer(str, L, _maxposition - 1);
//递归处理右边
b = RomanToNumer(str, _maxposition + 1, R);
return MAX - a + b;
}
这样的效率显然太低了,下面改进一下,这里直接给出------->>
其实就是从后往前,先记录最后一个数字,往前走,遇到比他小的就减去,否则就加上。
#include<iostream>
#include<string>
#include<map>
using namespace std;
map<string, int>m;
void Init()
{
m["I"] = 1;
m["V"] = 5;
m["X"] = 10;
m["L"] = 50;
m["C"] = 100;
m["D"] = 500;
m["M"] = 1000;
}
int RomanToNumber(string str)
{
int i;
string key;
string ch = str.substr(str.length() - 1);
int temp = m[ch];
int temp1 = 0,sum=temp;
str.erase(str.end() - 1);
while(str.length())
{
key = str.substr(str.length() - 1, 1);
temp1 = m[key];
if (temp1 >= temp) sum += temp1;
else sum -= temp1;
temp = temp1;
str.erase(str.end() - 1);
}
return sum;
}