[Uma pergunta por dia] algarismos romanos em números inteiros

https://leetcode-cn.com/problems/roman-to-integer/Números romanos em números
inteiros
Os números romanos contêm os sete caracteres a seguir: I, V, X, L, C, D e M.

Valor do caractere
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
Por exemplo, o número romano 2 é escrito como II, que é dois paralelos 1. 12 é escrito como XII, que é X + II. 27 Escreva XXVII, que é XX + V + II.

Normalmente, o pequeno número em algarismos romanos fica à direita do grande número. Mas há casos especiais, por exemplo, 4 não está escrito como IIII, mas IV. O número 1 está à esquerda do número 5 e o número representado é igual ao número 4 obtido pela redução do número 1 pelo número 5. Da mesma forma, o número 9 é representado como IX. Esta regra especial se aplica apenas às seis situações a seguir:

Eu posso ser posicionado à esquerda de V (5) e X (10) para representar 4 e 9.
X pode ser colocado à esquerda de L (50) e C (100) para indicar 40 e 90.
C pode ser colocado à esquerda de D (500) e M (1000) para indicar 400 e 900.
Dado um número romano, converta-o para um número inteiro. A entrada deve estar no intervalo de 1 a 3999.

Exemplo 1:

Entrada: "III"
Saída: 3
Exemplo 2:

Entrada: "IV"
Saída: 4
Exemplo 3:

Entrada: "IX"
Saída: 9
Exemplo 4:

Entrada: "LVIII"
Saída: 58
Explicação: L = 50, V = 5, III = 3.
Exemplo 5:

Entrada: "MCMXCIV"
Saída: 1994
Explicação: M = 1000, CM = 900, XC = 90, IV = 4.


Solução 1

Use o mapa.
A chave é uma única letra de algarismos romanos e val é o valor correspondente.
Necessidades para determinar a tecla correspondente ao que é agora val não é menos do que a próxima tecla val correspondente, como IVquatro em vez de seis.
40ms 9.1mb, leva tempo para construir o mapa, a seguinte complexidade de tempo de operação é O (n).

class Solution {
public:
    int romanToInt(string s) {
        map<char, int> m = {
        	{'I', 1},
        	{'V', 5},
        	{'X', 10},
        	{'L', 50},
        	{'C', 100},
        	{'D', 500},
        	{'M', 1000},
        };

        int ret = 0;
        for (int i = 0; i < s.size(); ++i) {
        	if (m[s[i]] < m[s[i + 1]]) {
        		ret = ret - m[s[i]];
        	} else {
        		ret = ret + m[s[i]];
        	}
        }

        return ret;
    }
};

Solução 2

A solução dos internautas é 4ms 5.6mb,

#define nI 1  //直接用define I 1,好像会有歧义
#define nV 5 
#define nX 10
#define nL 50
#define nC 100
#define nD 500
#define nM 1000

int romanToInt(char* s) 
{ 
    int num = 0, flag = 0;   /*立一个flag,是因为之前我在后面会用三个if,一个else,其实我的初衷是三个if有其中任何一个满足都不要再执行else了
	                         但是如果没有flag的话,意思是第三个if如果不成立便会跳去else,比如IV,第一个if满足,然后第三个if不满足,else这时候
							 就会出来执行,很不爽*/
    while(*s != NULL)
    {
        if(*s == 'I' && (*(s + 1) == 'V' || *(s + 1) == 'X'))     //接下来的这三个if都有特殊含义,所以flag=1,普通情况属于flag=0
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'V':num += (nV - nI); s+=2; break;
                case 'X':num += (nX - nI); s+=2; break;
            }
        }
        if(*s == 'X' && (*(s + 1) == 'L' || *(s + 1) == 'C'))
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'L':num += (nL - nX); s+=2; break;
                case 'C':num += (nC - nX); s+=2; break;
            }
        }
        if(*s == 'C' && (*(s + 1) == 'D' || *(s + 1) == 'M'))
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'D':num += (nD - nC); s+=2; break;
                case 'M':num += (nM - nC); s+=2; break;
            }
        }
        if(flag == 0)   //本来这里是else的,改为if(flag == 0)
        {
            switch(*s)
            {
                case 'I':num += nI; s += 1; break;
                case 'V':num += nV; s += 1; break;
                case 'X':num += nX; s += 1; break;
                case 'L':num += nL; s += 1; break;
                case 'C':num += nC; s += 1; break;
                case 'D':num += nD; s += 1; break;
                case 'M':num += nM; s += 1; break;
            }
        }
		flag = 0;  //最后置回普通状态
    }
    return num;
}

EOF

98 artigos originais foram publicados · 91 elogios · mais de 40.000 visualizações

Acho que você gosta

Origin blog.csdn.net/Hanoi_ahoj/article/details/105299608
Recomendado
Clasificación