📌  相关文章
📜  将罗马数字转换为介于1到3999之间的十进制

📅  最后修改于: 2021-05-04 15:54:28             🧑  作者: Mango

给定一个罗马数字,任务是找到其对应的十进制值。

例子 :

Input: IX
Output: 9
IX is a Roman symbol which represents 9 

Input: XL
Output: 40
XL is a Roman symbol which represents 40

Input: MCMIV
Output: 1904
M is a thousand, 
CM is nine hundred and 
IV is four

罗马数字基于以下符号。

SYMBOL       VALUE
  I            1
  IV           4
  V            5
  IX           9
  X            10
  XL           40
  L            50
  XC           90
  C            100
  CD           400
  D            500
  CM           900 
  M            1000

方法:罗马数字中的数字是字符串按降序排列的符号(例如,M的第一个,然后是D的等等)。但是,在某些特定情况下,为避免连续重复四个字符(例如IIII或XXXX),通常使用减法表示法,如下所示:

  • VX之前表示少一,所以四个是IV (小于5的一个),而9是IX(小于10的一个)。
  • LC前面的X表示少十,因此XL为四十(小于50十), XC为90(十小于一百)。
  • DM前面的C表示少100,因此CD等于400(小于500),而CM等于900(小于1000)。

将罗马数字转换为整数的算法:

  1. 将罗马数字字符串拆分为罗马符号(字符)。
  2. 将罗马数字的每个符号转换为其表示的值。
  3. 从索引0开始,一一取符号:
    1. 如果符号的当前值大于或等于下一个符号的值,则将该值添加到运行总计中。
    2. 否则,通过将下一个符号的值加到运行总计中来减去该值。

以下是上述算法的实现:

C++
// Program to convert Roman
// Numerals to Numbers
#include 
using namespace std;
 
// This function returns value
// of a Roman symbol
int value(char r)
{
    if (r == 'I')
        return 1;
    if (r == 'V')
        return 5;
    if (r == 'X')
        return 10;
    if (r == 'L')
        return 50;
    if (r == 'C')
        return 100;
    if (r == 'D')
        return 500;
    if (r == 'M')
        return 1000;
 
    return -1;
}
 
// Returns decimal value of
// roman numaral
int romanToDecimal(string& str)
{
    // Initialize result
    int res = 0;
 
    // Traverse given input
    for (int i = 0; i < str.length(); i++)
    {
        // Getting value of symbol s[i]
        int s1 = value(str[i]);
 
        if (i + 1 < str.length())
        {
            // Getting value of symbol s[i+1]
            int s2 = value(str[i + 1]);
 
            // Comparing both values
            if (s1 >= s2)
            {
                // Value of current symbol
                // is greater or equal to
                // the next symbol
                res = res + s1;
            }
            else
            {
                // Value of current symbol is
                // less than the next symbol
                res = res + s2 - s1;
                i++;
            }
        }
        else {
            res = res + s1;
        }
    }
    return res;
}
 
// Driver Code
int main()
{
    // Considering inputs given are valid
    string str = "MCMIV";
    cout << "Integer form of Roman Numeral is "
        << romanToDecimal(str) << endl;
 
    return 0;
}


Java
// Program to convert Roman
// Numerals to Numbers
import java.util.*;
 
public class RomanToNumber
{
    // This function returns
    // value of a Roman symbol
    int value(char r)
    {
        if (r == 'I')
            return 1;
        if (r == 'V')
            return 5;
        if (r == 'X')
            return 10;
        if (r == 'L')
            return 50;
        if (r == 'C')
            return 100;
        if (r == 'D')
            return 500;
        if (r == 'M')
            return 1000;
        return -1;
    }
 
    // Finds decimal value of a
    // given romal numeral
    int romanToDecimal(String str)
    {
        // Initialize result
        int res = 0;
 
        for (int i = 0; i < str.length(); i++)
        {
            // Getting value of symbol s[i]
            int s1 = value(str.charAt(i));
 
            // Getting value of symbol s[i+1]
            if (i + 1 < str.length())
            {
                int s2 = value(str.charAt(i + 1));
 
                // Comparing both values
                if (s1 >= s2)
                {
                    // Value of current symbol
                    // is greater or equalto
                    // the next symbol
                    res = res + s1;
                }
                else
                {
                    // Value of current symbol is
                    // less than the next symbol
                    res = res + s2 - s1;
                    i++;
                }
            }
            else {
                res = res + s1;
            }
        }
 
        return res;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        RomanToNumber ob = new RomanToNumber();
 
        // Considering inputs given are valid
        String str = "MCMIV";
        System.out.println("Integer form of Roman Numeral"
                           + " is "
                           + ob.romanToDecimal(str));
    }
}


Python
# Python program to convert Roman Numerals
# to Numbers
 
# This function returns value of each Roman symbol
 
 
def value(r):
    if (r == 'I'):
        return 1
    if (r == 'V'):
        return 5
    if (r == 'X'):
        return 10
    if (r == 'L'):
        return 50
    if (r == 'C'):
        return 100
    if (r == 'D'):
        return 500
    if (r == 'M'):
        return 1000
    return -1
 
 
def romanToDecimal(str):
    res = 0
    i = 0
 
    while (i < len(str)):
 
        # Getting value of symbol s[i]
        s1 = value(str[i])
 
        if (i + 1 < len(str)):
 
            # Getting value of symbol s[i + 1]
            s2 = value(str[i + 1])
 
            # Comparing both values
            if (s1 >= s2):
 
                # Value of current symbol is greater
                # or equal to the next symbol
                res = res + s1
                i = i + 1
            else:
 
                # Value of current symbol is greater
                # or equal to the next symbol
                res = res + s2 - s1
                i = i + 2
        else:
            res = res + s1
            i = i + 1
 
    return res
 
 
# Driver code
print("Integer form of Roman Numeral is"),
print(romanToDecimal("MCMIV"))


C#
// C# Program to convert Roman
// Numerals to Numbers
using System;
 
class GFG {
    // This function returns value
    // of a Roman symbol
    public virtual int value(char r)
    {
        if (r == 'I')
            return 1;
        if (r == 'V')
            return 5;
        if (r == 'X')
            return 10;
        if (r == 'L')
            return 50;
        if (r == 'C')
            return 100;
        if (r == 'D')
            return 500;
        if (r == 'M')
            return 1000;
        return -1;
    }
 
    // Finds decimal value of a
    // given romal numeral
    public virtual int romanToDecimal(string str)
    {
        // Initialize result
        int res = 0;
 
        for (int i = 0; i < str.Length; i++)
        {
            // Getting value of symbol s[i]
            int s1 = value(str[i]);
 
            // Getting value of symbol s[i+1]
            if (i + 1 < str.Length)
            {
                int s2 = value(str[i + 1]);
 
                // Comparing both values
                if (s1 >= s2)
                {
                    // Value of current symbol is greater
                    // or equalto the next symbol
                    res = res + s1;
                }
                else
                {
                    res = res + s2 - s1;
                    i++; // Value of current symbol is
                    // less than the next symbol
                }
            }
            else {
                res = res + s1;
                i++;
            }
        }
 
        return res;
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        GFG ob = new GFG();
 
        // Considering inputs given are valid
        string str = "MCMIV";
        Console.WriteLine("Integer form of Roman Numeral"
                          + " is "
                          + ob.romanToDecimal(str));
    }
}
 
// This code is contributed by Shrikant13


PHP
= $s2)
            {
                // Value of current symbol
                // is greater or equal to
                // the next symbol
                $res = $res + $s1;
            }
            else
            {
                $res = $res + $s2 - $s1;
                $i++; // Value of current symbol is
                      // less than the next symbol
            }
        }
        else
        {
            $res = $res + $s1;
            $i++;
        }
    }
    return $res;
}
 
// Driver Code
 
// Considering inputs
// given are valid
$str ="MCMIV";
echo "Integer form of Roman Numeral is ",
              romanToDecimal($str), "\n";
 
// This code is contributed by ajit
?>


Python3
def romanToInt(rom):
    value = {
        'M': 1000,
        'D': 500,
        'C': 100,
        'L': 50,
        'X': 10,
        'V': 5,
        'I': 1
    }
 
    # Initialize previous character and answer
    p = 0
    ans = 0
 
    # Traverse through all characters
    n = len(rom)
    for i in range(n-1, -1, -1):
 
        # If greater than or equal to previous,
        # add to answer
        if value[rom[i]] >= p:
            ans += value[rom[i]]
 
        # If smaller than previous
        else:
            ans -= value[rom[i]]
 
        # Update previous
        p = value[rom[i]]
 
    print(ans)
 
 
romanToInt('MCMIV')


C++
// Program to convert Roman
// Numerals to Numbers
#include 
using namespace std;
 
// This function returns value
// of a Roman symbol
int romanToDecimal(string& str)
{
    map m;
    m.insert({ 'I', 1 });
    m.insert({ 'V', 5 });
    m.insert({ 'X', 10 });
    m.insert({ 'L', 50 });
    m.insert({ 'C', 100 });
    m.insert({ 'D', 500 });
    m.insert({ 'M', 1000 });
    int sum = 0;
    for (int i = 0; i < str.length(); i++)
    {
        /*If present value is less than next value,
          subtract present from next value and add the
          resultant to the sum variable.*/
        if (m[str[i]] < m[str[i + 1]])
        {
            sum+=m[str[i+1]]-m[str
            i++;
            continue;
        }
        sum += m[str[i]];
    }
    return sum;
}
 
// Driver Code
int main()
{
    // Considering inputs given are valid
    string str = "MCMIV";
    cout << "Integer form of Roman Numeral is "
         << romanToDecimal(str) << endl;
 
    return 0;
}


Java
// Program to convert Roman
// Numerals to Numbers
import java.util.Map;
import java.util.HashMap;
 
class GFG{
     
private static final Map roman = new HashMap()
{{
    put('I', 1);
    put('V', 5);
    put('X', 10);
    put('L', 50);
    put('C', 100);
    put('D', 500);
    put('M', 1000);
}};
 
// This function returns value
// of a Roman symbol
private static int romanToInt(String s)
{
    int sum = 0;
    int n = s.length();
     
    for(int i = 0; i < n; i++)
    {
         
        // If present value is less than next value,
        // subtract present from next value and add the
        // resultant to the sum variable.
        if (i != n - 1 && roman.get(s.charAt(i)) <
                          roman.get(s.charAt(i + 1)))
        {
            sum += roman.get(s.charAt(i + 1)) -
                   roman.get(s.charAt(i));
            i++;
        }
        else
        {
            sum += roman.get(s.charAt(i));
        }
    }
    return sum;
}
 
// Driver Code
public static void main(String[] args)
{
     
      // Considering inputs given are valid
    String input = "MCMIV";
     
    System.out.print("Integer form of Roman Numeral is " +
                     romanToInt(input));
}
}
 
// This code is contributed by rahuldevgarg


输出
Integer form of Roman Numeral is 1904

复杂度分析:

  • 时间复杂度: O(n),其中n是字符串的长度。
    只需对字符串一次遍历。
  • 空间复杂度: O(1)。
    由于不需要额外的空间。

另一个解决方案–

C++

// Program to convert Roman
// Numerals to Numbers
#include 
using namespace std;
 
// This function returns value
// of a Roman symbol
int romanToDecimal(string& str)
{
    map m;
    m.insert({ 'I', 1 });
    m.insert({ 'V', 5 });
    m.insert({ 'X', 10 });
    m.insert({ 'L', 50 });
    m.insert({ 'C', 100 });
    m.insert({ 'D', 500 });
    m.insert({ 'M', 1000 });
    int sum = 0;
    for (int i = 0; i < str.length(); i++)
    {
        /*If present value is less than next value,
          subtract present from next value and add the
          resultant to the sum variable.*/
        if (m[str[i]] < m[str[i + 1]])
        {
            sum+=m[str[i+1]]-m[str
            i++;
            continue;
        }
        sum += m[str[i]];
    }
    return sum;
}
 
// Driver Code
int main()
{
    // Considering inputs given are valid
    string str = "MCMIV";
    cout << "Integer form of Roman Numeral is "
         << romanToDecimal(str) << endl;
 
    return 0;
}

Java

// Program to convert Roman
// Numerals to Numbers
import java.util.Map;
import java.util.HashMap;
 
class GFG{
     
private static final Map roman = new HashMap()
{{
    put('I', 1);
    put('V', 5);
    put('X', 10);
    put('L', 50);
    put('C', 100);
    put('D', 500);
    put('M', 1000);
}};
 
// This function returns value
// of a Roman symbol
private static int romanToInt(String s)
{
    int sum = 0;
    int n = s.length();
     
    for(int i = 0; i < n; i++)
    {
         
        // If present value is less than next value,
        // subtract present from next value and add the
        // resultant to the sum variable.
        if (i != n - 1 && roman.get(s.charAt(i)) <
                          roman.get(s.charAt(i + 1)))
        {
            sum += roman.get(s.charAt(i + 1)) -
                   roman.get(s.charAt(i));
            i++;
        }
        else
        {
            sum += roman.get(s.charAt(i));
        }
    }
    return sum;
}
 
// Driver Code
public static void main(String[] args)
{
     
      // Considering inputs given are valid
    String input = "MCMIV";
     
    System.out.print("Integer form of Roman Numeral is " +
                     romanToInt(input));
}
}
 
// This code is contributed by rahuldevgarg
输出
Integer form of Roman Numeral is 1904

时间复杂度– O(N)
辅助空间– O(1)