4

最近需要比较两组历史数据。由于有时其中一个会丢失一两天,并且我想准确地说,我决定创建一个包含所有可能日期的列表和两个包含日期和属于这两个集合的相应值的元组列表。然后我将后面的列表更改为Maps 以改进日期查找。

这个想法是尝试从两个Mapped 列表中的完整日期列表中查找每个日期,并创建一个“三元组”列表,(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优先于元组列表?
  • Map从 s 的元组创建String的 - 是否可以,或者键是否应该始终为数字以便平衡和查找正常工作?
4

1 回答 1

5

只有大约 2000 个日期,因此我不太关心性能(你可以看到我到处都在使用字符串);那时使用 Data.Map 是不是有点矫枉过正?何时应首选 Data.Map 而不是元组列表?

您应该使用适合您的问题和性能/编程时间限制的数据结构,因此使用 aMap可能是一个好主意。也许在您的情况下,如果您的数据已经订购,您可以完成

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 是从字符串的元组创建的 - 是否可以,或者键是否应该始终为数字以便平衡和查找正常工作?

不,如果您的代码类型检查您Map将正常工作(w/r/t 您定义Ord实例的方式)。但正如 CA McCann 所建议的那样,如果您的键是列表,则特里可能更合适,特别是如果键前缀之间有很多重叠(看看Ord列表上的实例是如何实现的,并想象一下必须发生的操作数将键“abcdx”、“abcdy”和“abcdz”插入到一个Mapvs. 一个 trie 结构中以说服自己)。

于 2012-12-13T19:55:55.983 回答