12. 整数转罗马数字
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
示例 1:
输入: 3
输出: "III"
示例 2:
输入: 4
输出: "IV"
示例 3:
输入: 9
输出: "IX"
示例 4:
输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.
示例 5:
输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题
将1——1000可以直接表达的字符列表;
罗马数字 阿拉伯数字
M 1000
CM 900
D 500
CD 400
C 100
XC 90
L 50
XL 40
X 10
IX 9
V 5
IV 4
I 1
贪心策略:先取最大的,再取次大的——直到可以表达这个数字;
class Solution {
public:
string intToRoman(int num) {
int n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
string rome[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
//贪心算法,从大往小除,得到组合
string res="";
for(int i=0;i<13;i++)
{
while(num>=n[i]){
res+=rome[i];
num-=n[i];
}
}
return res;
}
};
273. 整数转换英文表示
将非负整数转换为其对应的英文表示。可以保证给定输入小于 231 - 1 。
示例 1:
输入: 123
输出: "One Hundred Twenty Three"
示例 2:
输入: 12345
输出: "Twelve Thousand Three Hundred Forty Five"
示例 3:
输入: 1234567
输出: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
示例 4:
输入: 1234567891
输出: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One"
解题
给定数字,用英文表示;
以下为贪心算法代码,注意Billion,Million,Thousand,Hundred前面都要加个数;
class Solution {
public:
string numberToWords(int num) {
string Eng[]={"Billion","Million","Thousand","Hundred","Ninety","Eighty","Seventy","Sixty","Fifty","Forty","Thirty","Twenty","Nineteen","Eighteen","Seventeen","Sixteen","Fifteen","Fourteen","Thirteen","Twelve","Eleven","Ten","Nine","Eight","Seven","Six","Five","Four","Three","Two","One"};
int n[]={1000000000,1000000,1000,100,90,80,70,60,50,40,30,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
vector<string> aloc{"One","Two","Three","Four","Five","Six","Seven","Eight","Nine"};
if(num==0) return "Zero";
string res="";
string index;
int cnt;
bool flag=1;
for(int i=0;i<31;i++)
{
cnt=0;
while(num>=n[i])
{
cnt++;
num-=n[i];
}
if(cnt>0) {
if(i<4) {
index="";
for(int i=3;i<31;i++)
while(cnt>=n[i])
{
if(i==3){
int t=cnt/n[i];
index+=aloc[t-1]+" "+"Hundred"+" ";
cnt%=n[i];
}
else{
cnt-=n[i];
index+=Eng[i]+" ";
}
}
res+=index;
}
res+=Eng[i];
res+=" ";
}
}
res.erase(res.size()-1); //去掉最后的空格
return res;
}
private:
};
因为数字不超过2^31次,即9位,故判断到billion的10以内次数即可,因为要在大数前面加前缀,故贪心算法过于繁琐;
分治算法
三个位数为一组,每个单位差10^3倍,
python
class Solution:
def numberToWords(self, num: int) -> str:
to19 = 'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve ' \
'Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen'.split()
tens = 'Twenty Thirty Forty Fifty Sixty Seventy Eighty Ninety'.split()
def helper(num):
if num < 20:
return to19[num - 1:num]
if num < 100:
return [tens[num // 10 - 2]] + helper(num % 10)
if num < 1000:
return [to19[num // 100 - 1]] + ["Hundred"] + helper(num % 100)
for p, w in enumerate(["Thousand", "Million", "Billion"], 1):
if num < 1000 ** (p + 1):
return helper(num // 1000 ** p) + [w] + helper(num % 1000 ** p)
return " ".join(helper(num)) or "Zero"
作者:powcai
链接:https://leetcode-cn.com/problems/integer-to-english-words/solution/zheng-shu-zhuan-huan-ying-wen-biao-shi-by-powcai/
代码2
class Solution:
def numberToWords(self, num):
"""
:type num: int
:rtype: str
"""
def one(num):
switcher = {
1: 'One',
2: 'Two',
3: 'Three',
4: 'Four',
5: 'Five',
6: 'Six',
7: 'Seven',
8: 'Eight',
9: 'Nine'
}
return switcher.get(num)
def two_less_20(num):
switcher = {
10: 'Ten',
11: 'Eleven',
12: 'Twelve',
13: 'Thirteen',
14: 'Fourteen',
15: 'Fifteen',
16: 'Sixteen',
17: 'Seventeen',
18: 'Eighteen',
19: 'Nineteen'
}
return switcher.get(num)
def ten(num):
switcher = {
2: 'Twenty',
3: 'Thirty',
4: 'Forty',
5: 'Fifty',
6: 'Sixty',
7: 'Seventy',
8: 'Eighty',
9: 'Ninety'
}
return switcher.get(num)
def two(num):
if not num:
return ''
elif num < 10:
return one(num)
elif num < 20:
return two_less_20(num)
else:
tenner = num // 10
rest = num - tenner * 10
return ten(tenner) + ' ' + one(rest) if rest else ten(tenner)
def three(num):
hundred = num // 100
rest = num - hundred * 100
if hundred and rest:
return one(hundred) + ' Hundred ' + two(rest)
elif not hundred and rest:
return two(rest)
elif hundred and not rest:
return one(hundred) + ' Hundred'
billion = num // 1000000000
million = (num - billion * 1000000000) // 1000000
thousand = (num - billion * 1000000000 - million * 1000000) // 1000
rest = num - billion * 1000000000 - million * 1000000 - thousand * 1000
if not num:
return 'Zero'
result = ''
if billion:
result = three(billion) + ' Billion'
if million:
result += ' ' if result else ''
result += three(million) + ' Million'
if thousand:
result += ' ' if result else ''
result += three(thousand) + ' Thousand'
if rest:
result += ' ' if result else ''
result += three(rest)
return result
作者:LeetCode
链接:https://leetcode-cn.com/problems/integer-to-english-words/solution/zheng-shu-zhuan-huan-ying-wen-biao-shi-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这篇博客介绍了如何使用贪心策略将整数转换为罗马数字,详细解释了1到3999范围内罗马数字的表示规则,并给出了示例。同时,还探讨了将整数转换为英文表示的方法,同样采用了贪心策略,并提供了相应的代码实现。文章最后提到了使用分治算法的思考。

被折叠的 条评论
为什么被折叠?



