我想在功能上代表一种队列数据结构,但我还没有真正得到任何结论。我看过拉链,但它们似乎不是正确的结构。
具体来说,我试图表示一系列延迟线(用于回音或混响等音频效果),因此所需的功能如下:
对于我的特殊用途,这两个操作将结合使用以保持队列的大小恒定,但这种约束不是基本的。我可以使用一个列表,但我认为必须有一些更清洁的东西。表示此类型的最佳方式是什么?
我正在使用F#,但欢迎使用任何语言。
答案 0 :(得分:11)
通过功能我假设你的意思是一个不可变的队列?
如果您使用F#和.NET,例如:
如果您想了解如何实现功能性队列,我建议Chris Okasaki使用Purely Functional Data Structures。
Okasaki实现功能队列的第一种方法之一是使用两个List<>
,一个是你弹出的,一个是你推送的。当弹出列表为空时,推送队列被反转并成为弹出列表。
请记住,这在很多方面都是一个相当低效的队列,但它也很简单:
type Queue<'T> = 'T list*'T list
let empty<'T> : Queue<'T> = [], []
let isEmpty ((f, r) : Queue<'T>) : bool =
match f, r with
| [] , [] -> true
| _ , _ -> false
let headAndTail ((f, r) : Queue<'T>) : 'T*Queue<'T> =
match f, r with
| [] , [] -> failwith "Queue is empty"
| v::vs , r -> v, (vs, r)
| _ , r -> let v::vs = List.rev r in v, (vs, [])
let snoc ((f, r) : Queue<'T>) (v : 'T) : Queue<'T> = (f, v::r)
let fold (f : 'S -> 'T -> 'S) (s : 'S) (q : Queue<'T>) : 'S =
let rec loop ss qq =
if isEmpty qq then ss
else
let hh, tt = headAndTail qq
loop (f ss hh) tt
loop s q
let ofArray (vs : 'T []) : Queue<'T> = vs |> Array.fold snoc empty
[<EntryPoint>]
let main argv =
let q = [| 1..20 |] |> ofArray
fold (fun _ v -> printfn "%A" v) () q
0