使用列表元素和指数一起 [英] Using list elements and indices together

查看:128
本文介绍了使用列表元素和指数一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直觉得很别扭有一个函数或前pression需要使用的值,以及指数列表中哈斯克尔(或阵列,采用一样的)。

I've always found it awkward to have a function or expression that requires use of the values, as well as indices, of a list (or array, applies just the same) in Haskell.

我写了 validQueens 之下,而与N皇后问题的这里 ...

I wrote validQueens below while experimenting with the N-queens problem here ...

validQueens x = 
     and [abs (x!!i - x!!j) /= j-i | i<-[0..length x - 2], j<-[i+1..length x - 1]]

我并不关心使用索引,所有的加和短处,等感觉马虎。我想出了以下内容:

I didn't care for the use of indexing, all the plus and minuses, etc. It feels sloppy. I came up with the following:

enumerate x = zip [0..length x - 1] x

validQueens' :: [Int] -> Bool
validQueens' x = and [abs (snd j - snd i) /= fst j - fst i | i<-l, j<-l, fst j > fst i]
                   where l = enumerate x 

由Python的启发枚举(而不是借贷势在必行概念必然是一个伟大的想法)。似乎在概念上较好,但 SND FST 所有的地方还挺吮吸。这也是,至少在乍看之下,无论是在时间和空间上更昂贵。我不知道我是否不喜欢它任何好转。

being inspired by Python's enumerate (not that borrowing imperative concepts is necessarily a great idea). Seems better in concept, but snd and fst all over the place kinda sucks. It's also, at least at first glance, costlier both in time and space. I'm not sure whether or not I like it any better.

因此​​,在短期,我不是很满意或者

So in short, I am not really satisfied with either


  1. 直通迭代由长度,甚至更糟糕界指数的off-by-三三两两

  2. 索引元元组

有没有人发现,他们找到比上述任一更优雅的模式?如果没有,是否有任何令人信服的理由,上述的方法之一是优越?

Has anyone found a pattern they find more elegant than either of the above? If not, is there any compelling reason one of the above methods is superior?

推荐答案

借款枚举是罚款和鼓励。但是,它可以通过拒绝来计算其参数的长度进行了一下懒:

Borrowing enumerate is fine and encouraged. However, it can be made a bit lazier by refusing to calculate the length of its argument:

enumerate = zip [0..]

(事实上,它通常只使用拉链[0 ..] 没有将其命名为枚举)。为什么你认为你的第二个例子应该是时间或空间昂贵这不是我清楚。记住:分度为O(n),其中n是指数。 FST 和 SND 是有道理的,并且可以与模式匹配来弥补的臃肿投诉>

(In fact, it's common to just use zip [0..] without naming it enumerate.) It's not clear to me why you think your second example should be costlier in either time or space. Remember: indexing is O(n), where n is the index. Your complaint about the unwieldiness of fst and snd is justified, and can be remedied with pattern-matching:

validQueens' xs = and [abs (y - x) /= j - i | (i, x) <- l, (j, y) <- l, i < j]
    where l = zip [0..] xs

现在,你可能会有点担心这双循环的效率,因为该条款(J,Y)&LT; - 1 将被向下运行升整个脊柱的时候,确实我们只是希望它的开始,我们用不放过(I,X)LT; - 1 。所以,让我们编写一个实现这种想法的函数:

Now, you might be a bit concerned about the efficiency of this double loop, since the clause (j, y) <- l is going to be running down the entire spine of l, when really we just want it to start where we left off with (i, x) <- l. So, let's write a function that implements that idea:

pairs :: [a] -> [(a, a)]
pairs xs = [(x, y) | x:ys <- tails xs, y <- ys]

完成这样的功能,你的函数是不是太难以适应。拔出predicate到它自己的功能,我们可以使用所有而不是

validSingleQueen ((i, x), (j, y)) = abs (y - x) /= j - i
validQueens' xs = all validSingleQueen (pairs (zip [0..] xs))

或者,如果你preFER免费点符号:

Or, if you prefer point-free notation:

validQueens' = all validSingleQueen . pairs . zip [0..]

这篇关于使用列表元素和指数一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆