[英]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.