简体   繁体   English

对Haskell中的一些元素进行二分查找

[英]Doing a binary search on some elements in Haskell

I'm trying to complete the last part of my Haskell homework and I'm stuck, my code so far: 我正在尝试完成我的Haskell作业的最后一部分而且我被卡住了,我的代码到目前为止:

data Entry = Entry (String, String)

class Lexico a where
    (<!), (=!), (>!) :: a -> a -> Bool

instance Lexico Entry where
    Entry (a,_) <! Entry (b,_) = a <  b
    Entry (a,_) =! Entry (b,_) = a == b
    Entry (a,_) >! Entry (b,_) = a >  b

entries :: [(String, String)]
entries =  [("saves", "en vaut"), ("time", "temps"), ("in", "<`a>"),
              ("{", "{"), ("A", "Un"), ("}", "}"), ("stitch", "point"),
              ("nine.", "cent."), ("Zazie", "Zazie")]

build :: (String, String) -> Entry
build (a, b) = Entry (a, b)

diction :: [Entry]
diction = quiksrt (map build entries)

size :: [a] -> Integer
size [] = 0
size (x:xs) = 1+ size xs

quiksrt :: Lexico a => [a] -> [a]
quiksrt [] = []
quiksrt (x:xs)
    |(size [y|y <- xs, y =! x]) > 0 = error "Duplicates not allowed."
    |otherwise = quiksrt [y|y <- xs, y <! x]++ [x] ++ quiksrt [y|y <- xs, y >! x] 


english :: String
english = "A stitch in time save nine."

show :: Entry -> String
show (Entry (a, b)) = "(" ++ Prelude.show a ++ ", " ++ Prelude.show b ++ ")"

showAll :: [Entry] -> String
showAll [] = []
showAll (x:xs) = Main.show x ++ "\n" ++ showAll xs

main :: IO ()
main = do putStr (showAll ( diction ))

The question asks: 问题是:

Write a Haskell programs that takes the English sentence 'english', looks up each word in the English-French dictionary using binary search, performs word-for-word substitution, assembles the French translation, and prints it out. 编写一个Haskell程序,它使用英语句子“english”,使用二进制搜索查找英语 - 法语词典中的每个单词,执行逐字替换,汇编法语翻译并打印出来。

The function 'quicksort' rejects duplicate entries (with 'error'/abort) so that there is precisely one French definition for any English word. 函数'quicksort'拒绝重复的条目('error'/ abort),这样任何英文单词都有一个法语定义。 Test 'quicksort' with both the original 'raw_data' and after having added '("saves", "sauve")' to 'raw_data'. 使用原始'raw_data'和将'(“save”,“sauve”)'添加到'raw_data'之后测试'quicksort'。

Here is a von Neumann late-stopping version of binary search. 这是冯·诺伊曼最后的二元搜索版本。 Make a literal transliteration into Haskell. 对Haskell进行字面音译。 Immediately upon entry, the Haskell version must verify the recursive "loop invariant", terminating with 'error'/abort if it fails to hold. 在进入时,Haskell版本必须立即验证递归“循环不变”,如果无法保持,则以'error'/ abort结束。 It also terminates in the same fashion if the English word is not found. 如果找不到英文单词,它也会以相同的方式终止。

 function binsearch (x : integer) : integer local j, k, h : integer j,k := 1,n do j+1 <> k ---> h := (j+k) div 2 {a[j] <= x < a[k]} // loop invariant if x < a[h] ---> k := h | x >= a[h] ---> j := h fi od {a[j] <= x < a[j+1]} // termination assertion found := x = a[j] if found ---> return j | not found ---> return 0 fi 

In the Haskell version 在Haskell版本中

 binsearch :: String -> Integer -> Integer -> Entry 

as the constant dictionary 'a' of type '[Entry]' is globally visible. 因为'[Entry]'类型的常量字典'a'是全局可见的。 Hint: Make your string (English word) into an 'Entry' immediately upon entering 'binsearch'. 提示:输入'binsearch'后立即将您的字符串(英文单词)变成'Entry'。

The programming value of the high-level data type 'Entry' is that, if you can design these two functions over the integers, it is trivial to lift them to to operate over Entry's. 高级数据类型“Entry”的编程值是,如果你可以在整数上设计这两个函数,那么将它们提升到Entry的操作是微不足道的。

Anybody know how I'm supposed to go about my binarysearch function? 有谁知道我应该怎么做我的二元搜索功能?

The instructor asks for a "literal transliteration", so use the same variable names, in the same order. 教师要求“文字音译”,因此使用相同的变量名称,顺序相同。 But note some differences: 但请注意一些差异:

  • the given version takes only 1 parameter, the signature he gives requires 3. Hmmm, 给定的版本只需要1个参数,他给出的签名需要3.嗯,
  • the given version is not recursive, but he asks for a recursive version. 给定的版本不是递归的,但他要求递归版本。

Another answer says to convert to an Array, but for such a small exercise (this is homework after all), I felt we could pretend that lists are direct access. 另一个答案是转换为阵列,但是对于这么小的练习(毕竟这是家庭作业),我觉得我们可以假装列表是直接访问。 I just took your diction::[Entry] and indexed into that. 我刚刚接受了你的用词:: [Entry]并将其编入索引。 I did have to convert between Int and Integer in a few places. 我确实需要在几个地方转换Int和Integer。

Minor nit: You've got a typo in your english value (bs is a shortcut to binSearch I made): Minor nit:你的英文价值有误(bs是我做的binSearch的捷径):

  *Main> map bs (words english)
[Entry ("A","Un"),Entry ("stitch","point"),Entry ("in","<`a>"),Entry ("time","te
mps"),*** Exception: Not found
*Main> map bs (words englishFixed)
[Entry ("A","Un"),Entry ("stitch","point"),Entry ("in","<`a>"),Entry ("time","te
mps"),Entry ("saves","en vaut"),Entry ("nine.","cent.")]
*Main>

A binary search needs random access, which is not possible on a list. 二进制搜索需要随机访问,这在列表中是不可能的。 So, the first thing to do would probably be to convert the list to an Array (with listArray ), and do the search on it. 因此,要做的第一件事可能是将列表转换为Array (使用listArray ),然后对其进行搜索。

here's my code for just the English part of the question (I tested it and it works perfectly) : 这是我的代码只是问题的英文部分(我测试了它,它完美地工作):

module Main where

class Lex a where
    (<!), (=!), (>!) :: a -> a -> Bool

data Entry = Entry String String

instance Lex Entry where
    (Entry a _) <!  (Entry b _) = a <  b
    (Entry a _) =!  (Entry b _) = a == b
    (Entry a _) >!  (Entry b _) = a >  b
  -- at this point, three binary (infix) operators on values of type 'Entry'
  -- have been defined

type Raw = (String, String)

raw_data :: [Raw]
raw_data  =  [("than a", "qu'un"), ("saves", "en vaut"), ("time", "temps"),
                ("in", "<`a>"), ("worse", "pire"), ("{", "{"), ("A", "Un"),
                ("}", "}"), ("stitch", "point"), ("crime;", "crime,"),
                ("a", "une"), ("nine.", "cent."), ("It's", "C'est"),
                ("Zazie", "Zazie"), ("cat", "chat"), ("it's", "c'est"),
                ("raisin", "raisin sec"), ("mistake.", "faute."),
                ("blueberry", "myrtille"), ("luck", "chance"),
                ("bad", "mauvais")]

cook :: Raw -> Entry
cook (x, y) = Entry x y

a :: [Entry]
a = map cook raw_data

quicksort :: Lex a => [a] -> [a]
quicksort []     = []
quicksort (x:xs) = quicksort (filter (<! x) xs) ++ [x] ++ quicksort (filter (=! x) xs) ++ quicksort (filter (>! x) xs) 

getfirst :: Entry -> String
getfirst (Entry x y) = x

getsecond :: Entry -> String
getsecond (Entry x y) = y

binarysearch :: String -> [Entry] -> Int -> Int -> String
binarysearch s e low high 
    | low > high = " NOT fOUND "
    | getfirst ((e)!!(mid)) > s = binarysearch s (e) low (mid-1)
    | getfirst ((e)!!(mid)) < s = binarysearch s (e) (mid+1) high
    | otherwise = getsecond ((e)!!(mid))
        where mid = (div (low+high) 2)

translator :: [String] -> [Entry] -> [String]
translator [] y = []
translator (x:xs) y = (binarysearch x y 0 ((length y)-1):translator xs y)

english :: String
english = "A stitch in time saves nine."

compute :: String -> [Entry] -> String
compute x y = unwords(translator (words (x)) y)

main = do
    putStr (compute english (quicksort a))

An important Prelude operator is: 一个重要的Prelude运算符是:

(!!) :: [a] -> Integer -> a
-- xs!!n returns the nth element of xs, starting at the left and
-- counting from 0.

Thus, [14,7,3]!!1 ~~> 7. 因此, [14,7,3]!!1 ~~> 7。

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

相关问题 Haskell中的二叉搜索树中的元素? - Elements in Binary search tree in Haskell? 简单的二进制搜索算法由于某种原因不起作用 - simple binary search algorithm not working for some reason 在二进制印章搜索方面需要一些帮助 - Need some help with binary chop search 尝试实现 Haskell 二叉树搜索的路径记录 - Trying to implement path record for Haskell binary tree search Solr在进行分布式搜索时隐藏了一些facet.fields - Solr hides some facet.fields when doing a distributed search Python 中的二进制搜索无法正常工作,仅显示列表中的某些项目 - Binary search in Python not working properly, only displaying some items in list 使用二分搜索在排序数组中查找元素集合? - Finding a collection of elements in a sorted array using Binary Search? 10个元素的二进制搜索复杂度为0(log 10)= 1,但所需的比较为4 - Binary search complexity for 10 elements is 0(log 10) = 1 , but the comparision required are 4 Haskell 中最坏情况下 O(2d) 的二叉搜索树搜索算法 - Binary Search Tree Searching Algorithm that is O(2d) in Worst Case in Haskell 我在 C 二进制搜索代码中做错了什么? (迭代和递归) - What am I doing wrong in my C binary search code? (iterative & recursive)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM