12.Integer to Roman
给定一个 1 ~ 3999 的整数,求得其罗马数字的表示形式。
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
Input: 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
思路:
一、暴力解决,分开讨论,模板:当余数为 1-3,4,5-8,9时,讨论这4中情况。而对谁取余,比如 99 ,先考虑个位数,对 a1 =1,a2 = 5,a3 =10 取余数,得到 0,4,9,这个时候,对a3取余得到的9就是真实的尾数,运用模板,然后减掉个位数。然后考虑十位数 90,同理对a1, a2, a3扩大10倍 ,对10,50,100取余,得到 0,40,90,因为对a3取余得到的90是他的真实数字,用这个数除以a1,90/a1 = 9,又可以用我们的模板了,然后减掉十位数。因为在不断地减掉个位、十位、百位、千位上的数,最后 num 会减为0,跳出循环。
string intToRoman(int num) { string res = ""; unordered_map<int, string> in_Ro = { {1,"I"},{5,"V"},{10,"X"},{50,"L"},{100,"C"},{500,"D"},{1000,"M"} }; int a1 = 1, a2 = 5, a3 = 10;//衡量尺度 for (int i = 0; i < 4; i++) { if (num/a1 || num/a2 || num/a3) { int tmp1 = num % a1, tmp2 = num % a2, tmp3 = num % a3 , n = tmp3 / a1;//对尺度取余 string tmp = ""; if (n <= 3) while (n--) tmp += in_Ro[a1];//模板1-3 else if (n == 4) tmp = in_Ro[a1] + in_Ro[a2];//模板4 else if (n <= 8) {//模板5-8 tmp = in_Ro[a2]; n = n - 5; while (n--) tmp += in_Ro[a1]; } else tmp = in_Ro[a1] + in_Ro[a3];//模板9 res = tmp + res;//更新结果 num -= tmp3; a1 *= 10; a2 *= 10; a3 *= 10;//减掉尾数,扩大尺度 } else break; } return res; }
二、因为只有 1 ~ 3999,将其全排列出来。
string intToRoman(int num) { string res = ""; string a1[] = {"","I","II","III","IV","V","VI","VII","VIII","IX"}; string a2[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" }; string a3[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" }; string a4[] = { "","M","MM","MMM"}; res = a4[num / 1000] + a3[(num % 1000) / 100] + a2[(num % 100) / 10] + a1[num % 10]; return res; }