4

うーん... F#を使用して、この問題 ( https://www.spoj.pl/problems/INTEST/ )で受け入れられるのに十分な速さでデータを読み書きする方法を見つけるのはちょっと難しいです。

私のコード(http://paste.ubuntu.com/548748/)はTLEを取得します...

データの読み取りを高速化する方法はありますか?

4

3 に答える 3

5

私のこのバージョンは時間制限を通過します(ただし、それでも非常に遅く、〜14秒です):

open System
open System.IO

// need to change standard buffer, not to add an additional one
let stream = new StreamReader(Console.OpenStandardInput(4096))

let stdin = Seq.unfold (fun s -> if s = null then None else Some (s,stream.ReadLine())) <| stream.ReadLine()

let inline s2i (s : string) = Array.fold (fun a d -> a*10u + (uint32 d - uint32 '0') ) 0u <| s.ToCharArray()

let calc = 
    let fl = Seq.head stdin
    let [|_;ks|] = fl.Split(' ')
    let k = uint32 ks
    Seq.fold (fun a s -> if (s2i s) % k = 0u then a+1 else a) 0 <| Seq.skip 1 stdin

printf "%A" calc

このバージョンのボトルネックは実際にはstring -> uint32変換ですが (文字列からの標準の uint32 キャストはさらに遅いです)、サンプル入力 (約 100M ファイル) で読み取り自体に約 2 秒かかります (合計時間の 6 秒)。結果。命令型スタイルに書き直すと、合計実行時間をspojs2iで 10 秒に短縮できます。

let inline s2i (s : string) =
    let mutable a = 0u
    for i in 0..s.Length-1 do a <- a*10u + uint32 (s.Chars(i)) - uint32 '0'
    a
于 2011-01-01T02:07:48.087 に答える
2

実際にはわかりませんが、一度に文字を読み取るのは悪いことだと思います。たとえば、一度に4kをバッファーに読み取ってから、バッファーを処理する必要があります。

于 2010-12-30T13:08:09.540 に答える
1
let buf =
    let raw = System.Console.OpenStandardInput()
    let bytebuf = new System.IO.BufferedStream(raw)
    new System.IO.StreamReader(bytebuf)

buf.Read()     // retrieves a single character as an int from the buffer
buf.ReadLine() // retrieves a whole line from the buffer
于 2010-12-30T14:19:15.363 に答える