6

El Dragon Book incluye un ejercicio de conversión de números enteros a números romanos mediante un esquema de traducción dirigido por la sintaxis.¿Convierte números enteros a números romanos usando un esquema de traducción dirigido por la sintaxis?

¿Cómo se puede completar esto?

+1

parece una pregunta de tarea, huele a pregunta de tarea ...;-) –

+0

Sí, lo sé ... Desearía poder demostrar que no estoy haciendo trampa. EN REALIDAD, es una pregunta para los alumnos de CS ... Simplemente, no para mí, solo estoy leyendo el libro yo solo, y no tengo un maestro (o un amigo lo suficientemente informado) para preguntar. –

Respuesta

2

Consideraría el análisis de derecha a izquierda.

primer lugar, me Mapa columna de las unidades:

0 -> '' 
1 -> 'I' 
2 -> 'II' 
3 -> 'III' 
4 -> 'IV' 
... 
9 -> 'IX' 

Entonces, si había una segunda columna (por ejemplo, segunda desde la columna de la derecha = decenas), me gustaría utilizar que para asignar a

0 -> '' 
1 -> 'X' 
2 -> 'XX' 
... 
9 -> 'XC' 

Eso tendría que ser antepuesto a la salida inicial.

Repita para las columnas siguientes (cientos, miles) hasta que se quede sin letras.

Compruebe dos veces que el número no sea '0' o negativo.

+0

Esto significa que al hacer una gramática libre de contexto que luego me permita convertir usando un esquema de traducción dirigido por syntax, necesito crear 10 reglas para cada "columna". (Entonces, alrededor de 34 reglas para poder llegar a 3999) ¿Estoy en lo correcto? –

+0

Realmente pensé en algo como esto, esperaba que hubiera un método más elegante ... ¿Hay? –

+0

Sí, eso significa 10 reglas por columna. Supongo que puede escribir una sola función que funcione para cada una de las columnas, y toma las letras como parámetros ... Entonces, para 219, obtendría f (2, 'C', 'D', 'M') + f (1. 'X', 'L', 'C') + f (9, 'I', 'V', 'X') No se 'siente' libre de contexto . – Oddthinking

2

Otra forma es almacenar en matriz bidimensional los números romanos para 1, 5, 10, 50, 100, 500, 1000 y así sucesivamente. Ejemplo (en PHP array):

$roman = array(
    [0] = array(1=>"I", 5=>"V", 10=>"X"), 
    [1] = array(1=>"X", 5=>"L", 10=>"C"), 
    [2] = array(1=>"C", 5=>"D", 10=>"M"), 
    [3] = array(1=>"M", 5=>"^V", 10=>"^X"), 
); 

Luego tome cada dígito de derecha a izquierda y aplique la siguiente traducción. Establecimiento de un nivel variable $ = 0 y aumentar su valor en 1 después de cada dígito procesado: ('' en PHP un concats dos cadenas)

1 => $roman[$level][1] 
2 => $roman[$level][1].$roman[$level][1] 
3 => $roman[$level][1].$roman[$level][1].$roman[$level][1] 
4 => $roman[$level][1].$roman[$level][5] 
5 => $roman[$level][5] 
6 => $roman[$level][5].$roman[$level][1] 
7 => $roman[$level][5].$roman[$level][1].$roman[$level][1] 
8 => $roman[$level][5].$roman[$level][1].$roman[$level][1].$roman[$level][1] 
9 => $roman[$level][1].$roman[$level][10] 

Ejemplo: 1945

5 => $roman[0][5] = "V" 
4 => $roman[1][1].$roman[1][5] = "XL" 
9 => $roman[2][1].$roman[2][10] = "CM" 
1 => $roman[3][1] = "M" 

Por lo tanto, el número traducido es "MCMXLV"

Lo siento, esto podría no responder completamente a su pregunta, pero espero que ayude de alguna manera ..

2

La siguiente es la gramática para representar la traducción sintaxis dirigida desde el número en formato 1xxx a números romanos.

número = OneThousand digit3 digit2 digit1 | nzdigit3 digit2 digit1 | nzdigit2 digit1 | nzdigit1

OneThousand -> 1 {print ('M')}

digit3 -> 0 digit3 -> nzdigit3

nzdigit3 -> 1 de impresión ('C') nzdigit3 -> 2 imprimir ('CC') nzdigit3 -> 3 imprimir ('CCC') nzdigit3 -> 4 imprimir ('CCCC') nzdigit3 -> 5 imprimir ('D') nzdigit3 -> 6 imprimir ('DC') nzdigit3 - > 7 imprimir ('DCC') nzdigit3 -> 8 imprimir ('DCCC') nzdigit3 -> 9 imprimir ('DCCCc')

De manera similar escriba definición para dígitos en posición 2 y 1 y tendrá traducción necesaria.

Cuestiones relacionadas