简体   繁体   English

haskell二进制搜索树

[英]haskell binary search tree

module Main where

import Data.List
import Data.Function

type Raw = (String, String)

icards =  [("the", "le"),("savage", "violent"),("work", "travail"),
           ("wild", "sauvage"),("chance", "occasion"),("than a", "qu'un")]

data Entry = Entry {wrd, def :: String, len :: Int, phr :: Bool}
             deriving Show

-- French-to-English, search-tree section

entries' :: [Entry]
entries' = map (\(x, y) -> Entry y x (length y) (' ' `elem` y)) icards

data Tree a = Empty | Tree a (Tree a) (Tree a)

tree :: Tree Entry
tree = build entries'

build :: [Entry] -> Tree Entry
build []     = Empty
build (e:es) = ins e (build es)

ins :: Entry -> Tree Entry -> Tree Entry

...

find :: Tree Entry -> Word -> String

...

translate' :: String -> String
translate' = unwords . (map (find tree)) . words

so i'm trying to design function ins and find but i am not sure where to start.any ideas? 所以我正在尝试设计功能ins并找到,但我不确定从哪里开始。有什么想法吗?

I have no idea by which criteria the tree should be sorted, so I use just wrd . 我不知道应该按照什么标准对树进行排序,所以我只使用wrd Then it would look like: 然后看起来像:

ins :: Entry -> Tree Entry -> Tree Entry
ins entry Empty = Tree entry Empty Empty
ins entry@(Entry w _ _ _) (Tree current@(Entry w1 _ _ _) left right) 
   | w == w1 = error "duplicate entry"
   | w < w1 = Tree current (ins entry left) right
   | otherwise = Tree current left (ins entry right)  

How to get there? 如何到那?

As always when using recursion, you need a base case. 与使用递归一样,您通常需要一个基本案例。 Here it is very simple: If the tree is empty, just replace it by a node containing your data. 这很简单:如果树为空,只需将其替换为包含数据的节点即可。 There are no children for the new node, so we use Empty . 新节点没有子节点,因此我们使用Empty

The case if you have a full node looks more difficult, but this is just due to pattern matching, the idea is very simple: If the entry is "smaller" you need to replace the left child with a version that contains the entry, if it is "bigger" you need to replace the right child. 如果您拥有一个完整的节点,看起来会更困难,但这仅是由于模式匹配所致,其思想非常简单:如果条目“较小”,则需要用包含该条目的版本替换左子节点,如果您需要更换合适的孩子,这是“更大”的事情。

If both node and entry have the same "size" you have three options: keep the old node, replace it by the new one (keeping the children) or throw an error (which seems the cleanest solution, so I did it here). 如果节点和入口都具有相同的“大小”,则有三个选择:保留旧节点,将其替换为新节点(保留子节点)或抛出错误(这似乎是最干净的解决方案,所以我在这里做了)。

A simple generalization of Landei's answer: Landei答案的简单概括:

ins :: Ord a => a -> Tree a -> Tree a
ins x Empty = Tree x Empty Empty
ins x (Tree x' l r) = case compare x x' of
  EQ -> undefined
  LT -> Tree x' (ins x l) r
  GT -> Tree x' l (ins x r)

For this to work on Tree Entry , you will need to define an instance of Ord for Entry . 为了使它在Tree Entry上起作用,您将需要定义Ord for Entry的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM