2012-12-13 3 views
4

최근 두 세트의 기록 데이터를 비교해야했습니다. 그 중 하나에서 하루나 이틀이 누락되어 정확하기를 원했기 때문에 가능한 모든 날짜 목록과 날짜가 들어있는 튜플 목록과 두 세트에 속하는 해당 값을 작성하기로했습니다. 그런 다음 날짜 조회를 향상시키기 위해 후자의 목록을 Map으로 변경했습니다.Haskell의 Data.Map은 튜플 목록을 위해 언제 사용해야합니까?

Map 족제비 목록의 전체 날짜 목록에서 모든 날짜를 찾고 두 데이터 세트에 날짜와 값이있는 날짜 만 포함하는 (date, value1, value2)의 "트리플"목록을 만들려고했습니다. 그런 다음 파일에 기록하고 적절하게 비교할 수 있습니다.

코드를 신경 쓰지 마, IT는 ONLY 좋은 측정 여기

위한 포함 된 사항은 (전혀없는 최적이지만, 그 작은 작업에 대해 멋지게 그 일을했다) 코드입니다 :

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은 : (나는 기꺼이 몇 가지 의견/조언을들을 수 있지만) 코드는 작동했지만 나는 몇 가지 질문이 있습니다 단지 약 2,000 날짜가 있었다

  • , theref 광석 나는 성능 (당신은 내가 String 사방을 사용하고 있었다는 것을 알 수있다)에 대해별로 신경 쓰지 않았다. 그 다음은 과도기 Data.Map을 사용하고 있었습니까? 튜플 목록보다 Data.Map을 언제 선택해야합니까?
  • String의 튜플에서 생성되었습니다. 조정 또는 조회가 올바르게 작동하려면 키가 항상 숫자 여야합니다. ?
+1

터플리스트를 키 - 값 맵으로 사용한다면'Data.Map'을 사용하는 것이 더 나을 것입니다. 키는 임의의'Ord' 타입이 될 수 있고 잘 동작 할 것이지만 좀 더 특정한 타입을 위해서는 대신에'trie '의 맛 같은'Data.Map'보다 더 나은 것이있을 것입니다. –

+0

음, 키 - 값 케이스라고 말할 수 있습니다. 일반적인 상황에서 인덱스를 사용하여 값을 검색해야하는 경우 문제가 크지 않더라도 순진 튜플 목록 대신 항상 Map 또는 일부 특수 유형을 사용하는 것이 좋습니다. 또는'Map '이 필요할 때. – ljedrz

+1

* 필요할 때 *는 실제로 프로파일 링 및 프로그램의 특정 요구 사항에 따라 답변 할 수있는 것입니다. 즉, 튜플 목록을 사용하는 유일한 경우는 두 구성 요소 (즉, 양방향 멀티 맵)에서 검색하는 것과 같이 'Data.Map'과 친구들이 지원하지 않는 것입니다. –

답변

5

때문에 내가 훨씬에 대한 성능을 상관하지 않았다 (당신은 내가 사방 문자열을 사용하는 것을 볼 수 있습니다) 만 2,000 날짜 주위에 있었다; Data.Map을 사용하여 과잉 살상 이었습니까? 튜플 목록에 대해 Data.Map을 언제 사용해야합니까? ?

문제 및 성능/프로그래밍 시간 제한에 맞는 데이터 구조를 사용해야하므로 Map을 사용하는 것이 좋습니다. 이 괜찮 또는 키는 항상 균형 및 조회 위해서는 숫자이어야한다 - 어쩌면 귀하의 경우 데이터가 이미

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

지도는 문자열의 튜플에서 생성을 할 수 있었다 주문한 경우 제대로 작동합니까?

아니, 당신의 코드는 Map가 제대로 작동 typechecks 경우 (w/R/당신이 Ord 인스턴스를 정의한 방식 t). 그러나 CA McCann이 제안한 것처럼 trie은 키가 목록 인 경우, 특히 키 접두사 사이에 겹치는 부분이 많은 경우에 더 적합 할 수 있습니다 (목록의 Ord 인스턴스가 어떻게 구현되는지 확인하고 수행해야하는 작업의 수를 상상해보십시오). "abcdx", "abcdy"및 "abcdz"키를 Map 대 trie 구조에 삽입하여 자신을 설득하십시오.

+0

나는 당신의 노조 제안을 좋아합니다 ** 많이 **; 데이터가 이미 정렬 되었기 때문에 나는이 "간단하고 똑똑한"솔루션을 선호합니다. 그리고 이러한 상황에서 트라이를 고려할 때의 조언은 날짜 문자열이 매우 유사하므로 중요합니다. – ljedrz

관련 문제