lasciare che quei tipi di dati rappresentano numeri naturali unarie e binari rispettivamente:Esiste un modo efficace per convertire un numero unario in un numero binario?
data UNat = Succ UNat | Zero
data BNat = One BNat | Zero BNat | End
u0 = Zero
u1 = Succ Zero
u2 = Succ (Succ Zero)
u3 = Succ (Succ (Succ Zero))
u4 = Succ (Succ (Succ (Succ Zero)))
b0 = End // 0
b1 = One End // 1
b2 = One (Zero End) // 10
b3 = One (One End) // 11
b4 = One (Zero (Zero End)) // 100
(Alternatively, one could use `Zero End` as b1, `One End` as b2, `Zero (Zero End)` as b3...)
La mia domanda è: esiste un modo per implementare la funzione:
toBNat :: UNat -> BNat
che opera nel O(N)
, facendo una sola passata attraverso UNat?
La conversione da unario a qualsiasi altra base è complicata dal fatto che nessuna delle cifre di destinazione può essere determinata senza prima leggere l'intero numero. – biziclop
Per rendere la domanda accessibile ai non Haskellers, aggiungerei questo problema equivalente. Se abbiamo una lista collegata molto lunga, possiamo calcolare la sua lunghezza 'N' nel tempo' O (N) '? Si noti che l'addizione non è considerata un'operazione di tempo costante qui, quindi l'approccio banale fornirebbe solo "O (N log N)". (Quest'ultima parte è cruciale per il problema, IMHO.) – chi
L'incremento di 1 ha la complessità O (1) ammortizzata, non è vero? (Ogni incremento cambia in media di 2 cifre.) Quindi, solo ripetendo l'incremento di ingig. Ing. Per ogni cifra unaria dovrebbe avere la complessità ammortizzata O (N). – augustss