Supongamos que tengo una expresión matemática en forma de "árbol" en OCaml. Está representado como un tipo algebraica de esta manera:Cómo imprimir rápidamente una estructura de árbol en una cadena en Ocaml?
type expr =
Number of int
|Plus of expr*expr
Pues bien, este es un muy definición simplificada, pero es suficiente para describir el problema.
Quiero convertirlo en una cadena en una notación polaca inversa, de modo que Plus (Number i, Number j)
se convierta en (+ i j)
. Una aplicación sencilla sería
let rec convert = function
Number i -> string_of_int i
|Plus (a,b) -> (let s = convert a in let p = convert b in "(+"^s^" "^p^")")
Pero la cosa es que es increíblemente lento en alguna entrada (que tiene una profundidad de árbol grande). Por ejemplo, esta entrada 5 segundos funciona en mi máquina:
let rec make_pain so_far = function
0 -> so_far |i -> make_pain (Plus (Number 1,so_far)) (i-1)
let pain = make_pain (Number 1) 20000
let converted = convert pain
Parece que x^y
concatenación de cadenas, donde y
es una cadena larga, es el problema de rendimiento. De hecho, si reemplazo la expresión "(+"^s^" "^p^")"
con mera s^p
, se convierte en mucho más más rápido.
El uso de printf
en lugar de concatenación no lo hace más rápido. Convertir a C podría ayudar, ¿pero no hay una solución OCaml?
No sea un Schlemiel :-) http://www.joelonsoftware.com/articles/fog0000000319.html –
@ Chris sí , el problema es tan viejo como C :) –