2024年生日罗马文转换器

生日罗马文转换器Roman to Integer 题目要求 给定一个罗马数字 将其转换为整数 输入确保在 1 到 3999 范围内 罗马数字定义 罗马数字共有七个 即 I 1 V 5 X 10 L 50 C 100 D 500 M 1000

Roman to Integer

题目要求:
给定一个罗马数字,将其转换为整数。
输入确保在1到3999范围内。

罗马数字定义:

  • 罗马数字共有七个,即I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。按照下面的规则可以表示任意正整数。
  • 重复数次:一个罗马数字重复几次,就表示这个数的几倍。
  • 右加左减:
    在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。
    在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。
    但是,左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。
  • 加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的倍。
  • 单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。

组合规则:
(1) 基本数字 Ⅰ、X 、C 中的任何一个,自身连用构成数目,或者放在大数的右边连用构成数目,都不能超过三个;放在大数的左边只能用一个。
(2) 不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目,只能使用一个。
(3) V 和 X 左边的小数字只能用 Ⅰ。
(4)L 和 C 左边的小数字只能用 ×。
(5)D 和 M 左 边的小数字只能用 C 。

还有一点需要格外注意
MCM是1900
MCMXCVI是1996
按照逻辑 遍历到C 的处理,MC先M+C,但是遍历到第二个M的时候,顺序是CM,这个时候要减去这个C以及之前多加的C,也就是减去两个C。
例子:XCIX 是 99 遍历到第二个X时,+10-2*1

代码实现:

//转化罗马数字为整数 #include <iostream> #include<string> #include<stdlib.h> using namespace std; class Solution { 
    public: //116ms  int romanToInt(string s) { 
   //从左往右 if (s.length() <= 1) return charToInt(s[0]); int res = charToInt(s[0]); for (int i = 1; i<s.length(); i++){ 
    if (charToInt(s[i])>charToInt(s[i - 1])) res = res + charToInt(s[i]) - 2 * charToInt(s[i - 1]); else res += charToInt(s[i]); } return res; } int charToInt(char s){ 
    switch (s) { 
    case 'I': return 1; case 'V': return 5; case 'X': return 10; case 'L': return 50; case 'C': return 100; case 'D': return 500; case 'M': return 1000; default: return 0; } } }; int main() { 
    Solution a; string s; cin >> s; cout << a.romanToInt(s) << endl; system("pause"); return 0; }

试着将罗马数字从右往左进行转化

//89ms int romanToInt1(string s) { 
   //从右往左  if(s.length()<=1) return charToInt(s[0]); int res = 0; char maxChar = 'I'; for(int i=s.size()-1; i>=0; --i){ 
    if(charToInt(s[i])>=charToInt(maxChar)){ 
    maxChar = s[i]; res += charToInt(s[i]); } else res -= charToInt(s[i]); } return res; }

效率更高的方法

  • 当利用了罗马数字两个数字前后顺序的关系,也就是说如果是I在V前面,也就是IV,它代表4,反之代表6。再搭配C++的unordered_map,可以巧妙的通过数组来进行判断而达到对ret或加或减的目的。
//52ms #include <unordered_map>  int romanToInt2(string s){ 
    unordered_map<char, int> map = { 
   { 
   'I', 1}, { 
   'V', 5}, { 
   'X', 10}, { 
   'L', 50}, { 
   'C', 100}, { 
   'D', 500}, { 
   'M', 1000}}; int res = 0; for (int i = 0; i < s.size(); ++i) { 
    if ((i < s.size()-1) && (map[s[i]] < map[s[i+1]])) { 
    res -= map[s[i]]; } else { 
    res += map[s[i]]; } } return res; }

Integer to Roman

整数转化为罗马数字

代码实现:

#include <iostream>  using namespace std; class Solution { 
    public: string intToRoman(int num) { 
   //整数转化为罗马数字 string M[] = { 
   "", "M", "MM", "MMM"}; //1000 - 3000 string C[] = { 
   "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; //100 - 900 string X[] = { 
   "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; //10 - 90 string I[] = { 
   "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; //0 - 9 return M[num/1000] + C[(num/100)%10] + X[(num/10)%10] + I[num%10]; } }; int main(){ 
    Solution a; int num; cin >> num; cout << a.intToRoman(num) << endl; return 0; }
知秋君
上一篇 2024-11-10 19:12
下一篇 2024-11-12 12:55

相关推荐