【算法百题之四十】整数转罗马数字
大家好,我是Lampard~~
很高兴又能和大家见面了,接下来准备系列更新的是算法题,一日一练,早日升仙!
今天的问题是:整数转罗马数字(贪心算法)
思路:这道题主要是用到了贪心算法,从大往小一直把数字输出。什么是贪心算法呢?举个例子:
生活中的经验:
在以前还使用现金购物的时候,找零钱的时候一般商家会尽量选择面值大的纸币(硬币)给顾客,这样才会使得给顾客的纸币(硬币)张数最少,让顾客点钱的时候更方便。
这道题也一样,由于已经定义好了数值范围1~3999,那么我们从千到百这样往下判断,把符合条件的字符串先记录下来然后慢慢拼接即可。此时要注意题目给出的6个特殊情况,若是遇到了4和9那么就可以直接拼接字符串不需要进行判断5和1。首先我们用一个字典存起通用的罗马字符与数字的键值对,然后我们再记录下特殊的6种情况
map<int, string> num2str;
num2str[1] = "I";
num2str[5] = "V";
num2str[10] = "X";
num2str[50] = "L";
num2str[100] = "C";
num2str[500] = "D";
num2str[1000] = "M";
num2str[4] = "IV";
num2str[9] = "IX";
num2str[40] = "XL";
num2str[90] = "XC";
num2str[400] = "CD";
num2str[900] = "CM";
然后我们把curNum记录成1000(从千到百这样往下进行贪心算法),若不存在千位则继续判断百位,若存在千位则判断当前位是不是特殊情况(4或9)?若不是则对该位进行是否比5大进行判断,紧接着再把余下的小于5的部分分成数个1然后根据字典转换字符进行拼接
int curNum = 1000;
string res = "";
while (curNum != 0) {
int tmp = num / curNum;
if (tmp == 0) {
curNum /= 10;
continue;
}
// 先进性特殊情况的判断
if (num2str.count(tmp * curNum) != 0) {
res = res + num2str[tmp * curNum];
num %= curNum;
curNum /= 10;
continue;
}
if (tmp > 5 && num2str.count(5 * curNum) != 0) {
res = res + num2str[5 * curNum];
tmp %= 5;
}
while (tmp > 0) {
tmp -= 1;
res = res + num2str[curNum];
}
num %= curNum;
curNum /= 10;
}
return res;
测试函数以及测试结果: