Roman to Integer
Tags: algorithms, csharp, leetcode, easy
Published: 2022-07-18 01:33:34

_#13.Roman to Integer_

### Problem statement
Roman numerals are represented by seven different symbols: `I`, `V`, `X`, `L`, `C`, `D` and `M`.

```
Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
```

For example, `2` is written as `II` in Roman numeral, just two ones added together. `12` is written as `XII`, which is simply `X + II`. The number `27` is written as `XXVII`, which is `XX + V + II`.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not `IIII`. Instead, the number four is written as `IV`. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as `IX`. There are six instances where subtraction is used:

- `I` can be placed before `V` (5) and `X` (10) to make 4 and 9. 
- `X` can be placed before `L` (50) and `C` (100) to make 40 and 90. 
- `C` can be placed before `D` (500) and `M` (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer.

**Example 1**
```
Input: s = "III"
Output: 3
Explanation: III = 3.
```

**Example 2**
```
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
```

**Example 3**
```
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
```
### Explanation
給定一個羅馬數字將其轉換成阿拉伯數字，羅馬數字通常會從左到右、由大到小來撰寫，但有一特性，數字 `4` 不寫成 `IIII` 而是 `IV`，因為 `4` 在 `5` 之前，所以用 `V` 減去一個 `I` 得到 `IV` 也就是等於 `4`。

相同原則下也是適用於 `9`，轉換成羅馬數字為 `IX`，題目也提供了六種使用這種減法的案例。

### Solution
- 先過濾特定條件，判斷字串 `s` 是否為空字串或是 `null`，如果成立則返回 `0`
- 接著將羅馬符號對應的數字分別裝進 `Dictionary` 供後續轉換使用
- 建立一個 `counter` 變數儲存加總，並先 assign `s` 第 `0` 個索引轉換後的值
- 迴圈走訪字串內的從所有字符（除了第一個字），用一個 `If Statements` 來判斷是加法還是減法，正常原則是由大到小，所以條件可設為這次的羅馬符號大於上次則為減法
 - 條件成立：加總這次轉換的數值
 - 條件不成立：邏輯是減去上次加總的，再加上這次的數值減去上次的數值
- 最後返回結果 counter

```cs
public int RomanToInt(string s)
{
    if (s == null || s == String.Empty)
        return 0;

    IDictionary dic = new Dictionary<char, int>
    {
        { 'I', 1 },
        { 'V', 5 },
        { 'X', 10 },
        { 'L', 50 },
        { 'C', 100 },
        { 'D', 500 },
        { 'M', 1000 }
    };

    int counter = (int)dic[s[0]];

    for (int i = 0; i < s.Length; i++)
    {
        if ((int)dic[s[i - 1]] >= (int)dic[s[i]])
            counter += (int)dic[s[i]];
        else
            counter += (int)dic[s[i]] - (int)dic[s[i - 1]] * 2;
    }

    return counter;
}
```

---

### Reference
[LeetCode Solution](https://leetcode.com/problems/roman-to-integer/discuss/1326096/C-Solution)

[GitHub Repository](https://github.com/FakeStandard/LeetCode-CSharp/tree/main/Solution/0013.Roman-to-integer)

---

Thanks for reading the article :tulip: :sunflower: :blossom:

If you like it, please don't hesitate to click heart button :heart:
or click like on my Leetcode solution
or follow my [GitHub](https://github.com/FakeStandard) :star:
or buy me a coffee :arrow_down: I'd appreciate it.

[![Buy-me-a-coffee][1]][2]

[1]: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h077sxd0vx1hix4t7lw8.png
[2]: https://www.buymeacoffee.com/FakeStandard

---