4

最近、2セットの履歴データを比較する必要がありました。そのうちの1つで1日か2日が欠落していることがあり、正確にしたかったので、すべての可能な日付のリストと、両方のセットに属する日付と対応する値を含むタプルの2つのリストを作成することにしました。Map次に、日付の検索を改善するために、後者のリストをsに変更しました。

アイデアは、両方のpedリストの完全な日付リストからすべての日付を見つけて、両方のデータセットに日付と値が含まれる日付のみを含むMap「トリプル」のリストを作成することでした。(date, value1, value2)次に、それらをファイルに書き込んで、適切に比較することができます。

コードを気にしないでください、それは良い測定のためだけに含まれています

コードは次のとおりです(これはまったく最適ではありませんが、その小さなタスクではうまく機能しました):

import qualified Data.Map as M
import Data.List (transpose)
import Data.Maybe (fromJust)

main = do
    dts     <- readFile "dates.txt"
    cts1    <- readFile "eu.txt"
    cts2    <- readFile "usa.txt"
    let
        dates  = lines dts
        cols1  = transpose $ map words $ lines cts1
        cols2  = transpose $ map words $ lines cts2
        prs1   = zip (head cols1) (last cols1)
        prs2   = zip (head cols2) (last cols2)
        map1   = M.fromList prs1
        map2   = M.fromList prs2
        trips  = map fromJust (filter (/=Nothing) (map (\date -> getTrips date map1 map2) dates))
        cols3  = map (\(a,b,c) -> [a,b,c]) trips
        result = unlines $ map unwords $ cols3
    writeFile "trips.txt" result

getTrips :: String -> M.Map String String -> M.Map String String -> Maybe (String, String, String)
getTrips date map1 map2
    | is1 /= Nothing && is2 /= Nothing    = Just (date, fromJust is1, fromJust is2)
    | otherwise                           = Nothing
    where
        is1 = M.lookup date map1
        is2 = M.lookup date map2

TL; DR:コードは機能しましたが(私はいくつかの意見/アドバイスを喜んで聞きますが)、いくつか質問があります:

  • 日付は2000前後しかなかったので、パフォーマンスについてはあまり気にしませんでした(Stringどこでもsを使用していたことがわかります)。Data.Mapその時、やり過ぎを使っていましたか?タプルのリストよりもいつ優先されるべきですか?Data.Map
  • sのタプルから作成されました-バランシングMapルックアップが正しく機能するために、キーは常に数値である必要がありますか?String
4

1 に答える 1

5

日付は約2000しかなかったので、パフォーマンスについてはあまり気にしませんでした(どこでも文字列を使用していたことがわかります)。Data.Mapを使用していたのはやり過ぎでしたか?タプルのリストよりもData.Mapを優先する必要があるのはいつですか?

問題とパフォーマンス/プログラミング時間の制約に適合するデータ構造を使用する必要があるため、を使用することMapはおそらく良い考えでした。たぶんあなたの場合、あなたのデータがすでに注文されていれば、あなたはそれをすることができたでしょう

union [] _ = []
union _ [] = []
union xss@((dx,vx):xs) yss@((dy,vy):ys) = 
    case compare dx dy of
         EQ -> (dx, vx, vy) : union xs ys
         GT -> union xss ys
         LT -> union xs yss

マップは文字列のタプルから作成されました-バランス調整とルックアップが正しく機能するために、キーは常に数値である必要がありますか?

いいえ、コードタイプチェックがあれば、Map正しく機能します(Ordインスタンスを定義した方法で)。しかし、CA McCannが示唆しているように、キーがリストである場合、特にキープレフィックス間に多くの重複がある場合は、トライがより適切な場合があります(リスト上のインスタンスがどのようにOrd実装されているかを確認し、キー「abcdx」、「abcdy」、および「abcdz」をMap対トライ構造に挿入して、自分を納得させます。

于 2012-12-13T19:55:55.983 に答える