繁体   English   中英

Haskell中的2d数组排序

[英]2d Array Sort in Haskell

我正在尝试自学Haskell(来自OOP语言)。 难以掌握不变变量的东西。 我正在尝试在专业行中排序2d数组。

在Java中,例如(pseudo):

int array[3][3] = **initialize array here

for(i = 0; i<3; i++)
   for(j = 0; j<3; j++)
      if(array[i][j] < current_low)
         current_low = array[i][j]

我该如何在Haskell中实现这种事情? 如果我创建一个临时数组以在每次迭代后向其添加低值,我将无法对其进行添加,因为它是不可变的,对吗? 而且,Haskell没有循环,对吗?

这是我在Haskell中了解的一些有用的信息:

main = do
let a = [[10,4],[6,10],[5,2]] --assign random numbers
print (a !! 0 !! 1) --will print a[0][1] in java notation
--How can we loop through the values?

首先,Java代码拣东西。 它只是找到最小的元素。 而且,嗯,有一种显而易见的Haskell解决方案...猜怎么着,该函数称为minimum 让我们看看它的作用:

GHCi>:t最小值
最小:: Ord a => [a]-> a

好的,因此它获取一个可以比较的值列表(因此Ord ),并输出一个值,即最小值。 我们如何将其应用于“ 2D列表”(嵌套列表)? 好吧,基本上,我们需要所有子列表中的最小值。 因此,我们首先将列表列表替换为最小值列表

allMinima = map minimum a

...然后使用minimum allMinima

紧凑地写:

main :: IO ()
main = do
   let a = [[10,4],[6,10],[5,2]]   -- don't forget the indentation
   print (minimum $ map minimum a)

就这样!


确实,“通过价值循环”是一个非常不起作用的概念。 我们通常不想谈论需要采取的单个步骤 ,而是想想我们想要的结果的属性 ,然后让编译器找出如何做。 因此,如果不允许我们使用预定义的minimum ,请考虑以下方法:

  • 如果我们有一个列表并查看单个值...在什么情况下是正确的结果? 好吧, 如果它小于所有其他值 其他值中最小的是什么? 恰好是其中的最小值。

     minimum' :: Ord a => [a] -> a minimum' (x:xs) | x < minimum' xs = x 
  • 如果不小于,那么我们仅使用其他值中的最小值

     minimum' (x:xs) | x < minxs = x | otherwise = minxs where minxs = minimum' xs 
  • 还有一件事:如果我们以此方式遍历列表,则在某个时候将没有第一个要与之比较的元素。 为了防止这种情况,我们首先需要单元素列表的特殊情况:

     minimum' :: Ord a => [a] -> a minimum' [x] = x -- obviously smallest, since there's no other element. minimum' (x:xs) | x < minxs = x | otherwise = minxs where minxs = minimum' xs 

好吧,我要刺一口。 Zach,此答案旨在使您思考递归和折痕。 递归,折叠和映射是在功能样式中替换循环的基本方法。 试着相信现实中,嵌套循环的问题很少在函数式编程中自然产生。 在实际需要执行此操作时,通常会输入一个特殊的代码部分,称为monad,您可以在其中执行命令式破坏性写操作。 这是一个例子 但是,由于您在突破循环思维方面寻求帮助,因此我将重点放在答案的这一部分。 @leftaroundabout的答案也非常好,您可以在此处填写他的minimum定义。

flatten :: [[a]] -> [a]
flatten [] = []
flatten xs = foldr (++) [] xs

squarize :: Int -> [a] -> [[a]]
squarize _ [] = []
squarize len xs = (take len xs) : (squarize len $ drop len xs)

crappySort :: Ord a => [a] -> [a]
crappySort [] = []
crappySort xs =
    let smallest = minimum xs
        rest = filter (smallest /=) xs
        count = (length xs) - (length rest)
    in
        replicate count smallest ++ crappySort rest

sortByThrees xs = squarize 3 $ crappySort $ flatten xs

暂无
暂无

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

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