homeSoftwaredesign Softwaredesign: Vereinfachtes Datenmodell Prof. Dr. Uwe Schmidt FH Wedel

Vereinfachtes Datenmodell


weiter

Radixsuche
Die vereinfachte, aber nicht weniger effiziente Variante.

weiter

Die Datenstruktur, das Suchen und das Einfügen und die Invariante

   1module RadixTree2
   2where
   3
   4import           Data.Char
   5import           Data.Maybe
   6
   7import           Data.Map(Map)
   8import qualified Data.Map as M
   9
  10import           Data.Set(Set)
  11import qualified Data.Set as S
  12
  13-- ------------------------------------------------------------
  14--
  15
  16type Key        = String
  17type Attr       = Set Int
  18
  19data Table      = Entry Table  Attr
  20                | Switch        ( Map Char Table )
  21                  deriving (Show)
  22
  23-- ------------------------------------------------------------
  24
  25emptyTable      :: Table
  26emptyTable      = Switch M.empty
  27
  28-- ------------------------------------------------------------
  29--
  30-- 5 cases      (completeness, correctness !!!)
  31
  32search          :: String -> Table -> Maybe Attr
  33
  34search "" (Entry table attr)    = Just attr
  35
  36search "" (Switch sw)           = Nothing
  37
  38search k  (Entry table attr)    = search k table
  39
  40search k  (Switch sw)           = switch (M.lookup (head k) sw)
  41    where
  42    switch Nothing      = Nothing
  43    switch (Just tab)   = search (tail k) tab
  44
  45-- ------------------------------------------------------------
  46--
  47-- 4 cases, very fast
  48
  49searchPrefix    :: String -> Table -> Table
  50
  51searchPrefix "" tab                     = tab
  52
  53searchPrefix k (Entry tab' a')          = searchPrefix k tab'
  54
  55searchPrefix (c:rest) (Switch sw')
  56    | M.member c sw'                    = searchPrefix rest
  57                                          (fromJust $ M.lookup c sw')
  58    | otherwise                         = emptyTable
  59
  60-- ------------------------------------------------------------
  61--
  62-- 5 cases      (completeness, correctness !!!)
  63
  64insert  :: String -> Attr -> Table -> Table
  65
  66
  67insert ""       a (Entry tab' a')       = Entry tab' (a' `S.uniona)
  68
  69insert ""       a tab                   = Entry tab a
  70
  71insert k        a (Entry tab' a')       = Entry (insert k a tab') a'
  72
  73insert (c:rest) a (Switch sw')
  74    | M.member c sw'                    = Switch (M.adjust (insert rest a) c sw')
  75    | otherwise                         = Switch (M.insert c (insert rest a emptyTable) sw')
  76
  77-- ------------------------------------------------------------
  78
  79keys    :: Table -> [String]
  80
  81keys (Entry tab a)      = "" : keys tab
  82keys (Switch sw)        = [ c : w | c <- M.keys sw
  83                                  , w <- keys (fromJust $ M.lookup c sw)
  84                          ]
  85
  86-- ------------------------------------------------------------
  87--
  88-- invariant:
  89--
  90-- no nested Entry constructors
  91--
  92-- no subtable of a switch is empty
  93
  94invTable        :: Table -> Bool
  95invTable (Entry tab attr)
  96    = case tab of
  97      Entry _ _  -> False
  98      Switch _   -> invTable tab
  99
 100invTable (Switch sw)
 101    = all invTable' (M.elems sw)
 102      where
 103      invTable' t'              = not (isEmptyTable t')
 104                                &&
 105                                invTable t'
 106
 107      isEmptyTable (Entry _ _)  = False
 108      isEmptyTable (Switch sw)  = M.null sw
 109
 110-- ------------------------------------------------------------
 111
 112tableSpace              :: Table -> Int
 113tableSpace (Entry t a)
 114    = 2 + tableSpace t          -- 1 (constructor) + 1 (Table) + 0 (Attr not counted)
 115
 116tableSpace (Switch m)
 117    = 2 + 2 * M.size m          -- 1 (constructor) + 1 (Map) +  per Entry (Char, Table)
 118      + (sum . map tableSpace . M.elems) m
 119
 120tableSize               :: Table -> (Int, Int)
 121tableSize t
 122    = (length ks, sum . map length $ ks)
 123    where
 124    ks = keys t
 125
 126-- ------------------------------------------------------------
weiter

weiter

Alle Wörter, die mit "Fra" beginnen:

ghc -e alleWoerterMitFra RadixTreeExample2 Index RadixTree2 Zitate
weiter

weiter

Speicherplatz-Statistik:

ghc -e platz RadixTreeExample2 Index RadixTree Zitate
weiter

Letzte Änderung: 11.07.2012
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel