УсловиС Π·Π°Π΄Π°Ρ‡ΠΈ

РимскиС Ρ†ΠΈΡ„Ρ€Ρ‹ прСдставлСны сСмью Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ символами:

Π‘ΠΈΠΌΠ²ΠΎΠ»Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
I1
V5
X10
L50
C100
D500
M1000

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:

  • 2 записываСтся ΠΊΠ°ΠΊ II (Π΄Π²Π° Ρ€Π°Π·Π° ΠΏΠΎ 1).
  • 12 записываСтся ΠΊΠ°ΠΊ XII (X + II).
  • 27 записываСтся ΠΊΠ°ΠΊ XXVII (XX + V + II).

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ римскиС Ρ†ΠΈΡ„Ρ€Ρ‹ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ большСго ΠΊ ΠΌΠ΅Π½ΡŒΡˆΠ΅ΠΌΡƒ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ. Однако Π΅ΡΡ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, связанныС с Π²Ρ‹Ρ‡ΠΈΡ‚Π°Π½ΠΈΠ΅ΠΌ:

  • 4 записываСтся ΠΊΠ°ΠΊ IV, Π° Π½Π΅ IIII (I ΠΏΠ΅Ρ€Π΅Π΄ V Π·Π½Π°Ρ‡ΠΈΡ‚ 5 βˆ’ 1).
  • 9 записываСтся ΠΊΠ°ΠΊ IX.

Π‘Π»ΡƒΡ‡Π°ΠΈ использования вычитания:

  • I ΠΏΠ΅Ρ€Π΅Π΄ V (5) ΠΈ X (10) β†’ 4 ΠΈ 9
  • X ΠΏΠ΅Ρ€Π΅Π΄ L (50) ΠΈ C (100) β†’ 40 ΠΈ 90
  • C ΠΏΠ΅Ρ€Π΅Π΄ D (500) ΠΈ M (1000) β†’ 400 ΠΈ 900

Π€ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π·Π°Π΄Π°Ρ‡Π° Π·Π²ΡƒΡ‡ΠΈΡ‚ Ρ‚Π°ΠΊ:

Π”Π°Π½ римский символ (строка). ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠΉΡ‚Π΅ Π΅Π³ΠΎ Π² Ρ†Π΅Π»ΠΎΠ΅ число.

РСшСниС: ΠΏΡ€ΠΎΡ…ΠΎΠ΄ ΠΏΠΎ строкС с ΡƒΡ‡Ρ‘Ρ‚ΠΎΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ символа

ИдСя

Алгоритм ΠΈΠ΄Ρ‘Ρ‚ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ ΠΏΠΎ строкС. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ символа:

  • Π‘Π΅Ρ€Ρ‘ΠΌ Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
  • Π‘ΠΌΠΎΡ‚Ρ€ΠΈΠΌ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ (Ссли ΠΎΠ½ Π΅ΡΡ‚ΡŒ).
  • Если ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ большС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ β€” Π·Π½Π°Ρ‡ΠΈΡ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ вычитания: добавляСм Ρ€Π°Π·Π½ΠΈΡ†Ρƒ ΠΈ пропускаСм ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ.
  • Π˜Π½Π°Ρ‡Π΅ просто добавляСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π·Π° ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ ΠΏΠΎ строкС ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΈΡ‚ΠΎΠ³ΠΎΠ²ΠΎΠ΅ число.

var romanIntDict = map[byte]int{
    'I': 1,
    'V': 5,
    'X': 10,
    'L': 50,
    'C': 100,
    'D': 500,
    'M': 1000,
}
 
func romanToInt(s string) int {
    res := 0
    for i := 0; i < len(s); i++ {
        c := romanIntDict[s[i]]
        n := 0
        if i != len(s) - 1 {
            n = romanIntDict[s[i + 1]]
        }
        if n > c {
            res += n - c
            i++
            continue
        }
        res += c
    }
    return res
}

РСшСниС: ΠΏΡ€ΠΎΡ…ΠΎΠ΄ справа Π½Π°Π»Π΅Π²ΠΎ

ИдСя

ИдСя: римскиС числа ΡΠΊΠ»Π°Π΄Ρ‹Π²Π°ΡŽΡ‚ΡΡ справа Π½Π°Π»Π΅Π²ΠΎ.

  • Если Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ символ мСньшС ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ (сосСда справа) β†’ Π²Ρ‹Ρ‡ΠΈΡ‚Π°Π΅ΠΌ.
  • Π˜Π½Π°Ρ‡Π΅ β†’ прибавляСм.
var romanIntDict = map[byte]int{
    'I': 1,
    'V': 5,
    'X': 10,
    'L': 50,
    'C': 100,
    'D': 500,
    'M': 1000,
}
 
func romanToInt(s string) int {
    res := 0
    prev := 0
    for i := len(s) - 1; i >= 0; i-- {
        cur := romanIntDict[s[i]]
        if cur < prev {
            res -= cur
        } else {
            res += cur
        }
        prev = cur
    }
    return res
}

Плюс: Π½Π΅Ρ‚ нСобходимости ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ.
ΠœΠΈΠ½ΡƒΡ: Ρ‡ΡƒΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ ΠΈΠ½Ρ‚ΡƒΠΈΡ‚ΠΈΠ²Π½ΠΎ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ.

РСшСниС: ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ со ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠΈ

ИдСя

ВмСсто Π»ΠΎΠ³ΠΈΠΊΠΈ β€œΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ”, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Ρ€Π°Π½Π΅Π΅ завСсти ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ с комбинациями Π²Ρ‹Ρ‡ΠΈΡ‚Π°Π½ΠΈΠΉ (IV, IX, XL, …).
Π’ΠΎΠ³Π΄Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΈΠ΄Ρ‘Ρ‚ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ:

  • Ссли встрСчаСм Π΄Π²ΡƒΡ…ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½ΡƒΡŽ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡŽ β†’ Π±Π΅Ρ€Ρ‘ΠΌ Π΅Ρ‘ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ двигаСмся Π½Π° 2 шага;
  • ΠΈΠ½Π°Ρ‡Π΅ Π±Π΅Ρ€Ρ‘ΠΌ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ символ.
var romanIntDict = map[string]int{
    "I": 1, "V": 5, "X": 10, "L": 50,
    "C": 100, "D": 500, "M": 1000,
    "IV": 4, "IX": 9, "XL": 40, "XC": 90,
    "CD": 400, "CM": 900,
}
 
func romanToInt(s string) int {
    res := 0
    for i := 0; i < len(s); {
        if i+1 < len(s) {
            if val, ok := romanIntDict[s[i:i+2]]; ok {
                res += val
                i += 2
                continue
            }
        }
        res += romanIntDict[string(s[i])]
        i++
    }
    return res
}

Плюс: явная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π²Ρ‹Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… случаСв.
ΠœΠΈΠ½ΡƒΡ: большС Π΄Π°Π½Π½Ρ‹Ρ… Π² словарС.