当n适合谓词时,移除Haskell列表中位置n和n-1的元素 [英] Remove elements at positions n and n-1 in a Haskell list, when n fits a predicate

查看:110
本文介绍了当n适合谓词时,移除Haskell列表中位置n和n-1的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个从 2 20 的所有整数列表。

  [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, 18,19,20] 

我还有一个函数 fx ,它返回 True False 。当我将这个函数应用于位置 n 的元素,它等于 True 时,我想删除它和它的先验元素(它是位置 n-1 的元素)。我希望继续这样做,直到列表中的元素的功能等于 True 以及它们的前面元素为空。



示例:
假设位于 11 的元素,它等于 13 ,符合谓词。然后,我想要移除位置 10 ,也等于 12 的元素。之后,我的最终名单将是:

  [2,3,4,5,6,7,8,9,10 ,11,14,15,16,17,18,19,20] 

我们还可以这么说位置 4 8 以及 15 是唯一符合谓词的元素(除了位置 13 的元素之外)。删除它们及其前面的元素后,我的最终列表将如下所示:

  [2,3,4,7,8,11 ,14,15,18,19,20] 

我是一个没有经验的Haskell程序员,只是玩乐。我想过使用某种lambda函数作为过滤器的谓词,或者创建一个像 listRemove xs ys 这样的函数来删除 xs 也是 ys 的一个元素,但是我对两者都感到失落。



任何帮助将不胜感激!



编辑:我想要做的是解决欧拉计划问题,即#179 。谓词 f x 用于检查 x 是否为素数。因此,我可以肯定地说没有角落案例存在 - 例如不存在如 [x,x,t,t] 的情况,其中 t 是一个谓词因为不存在两个连续的整数,除了 2 3 之外,这两个整数都是主要的,我可以轻松处理在我的解决方案。相反,您可以得到的最接近的是 [x,t,x,t] ,在这种情况下,我想删除所有这些元素。

解决方案

假设您有:

 禁止:: Int  - > bool 
- 与示例
不匹配的函数x = elem x [6,10,13,17]

你想要的只是

  import Data.List(tails)

地图头。过滤器(不是任何不允许的。拿2)。过滤器(非空)。尾巴$ [2..20]

如果您想给它一个名字:

  filterWithTails ::([a]  - > Bool) - > [a]  - > [a] 
filterWithTails f =地图头。过滤器f。过滤器(非空)。尾巴

filterWithTails(不是任何不允许的。take 2)[2..20]

(不是。任何不允许的。take 2)是过滤时如何过滤列表以考虑列表的其余部分。很难给出一个比构成它的功能组合更好的名字。


Say I have a list of all the integers from 2 to 20.

[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

I also have a function f x that returns either True or False. When I apply this function to the element at position n and it equals to True, I want to remove it and its precedent element (which is the element at position n-1). I want to keep doing this until the list is empty of elements for which the function equals to True, as well as their preceding elements.

Example: Let's say that the element at position 11, which equals to 13, fits the predicate. I then want to remove the element at position 10, which equals to 12, as well. After that my final list would be:

[2,3,4,5,6,7,8,9,10,11,14,15,16,17,18,19,20]

Let's also say that the elements at position 4, 8 as well as 15 are the only elements (apart from the element at position 13) that fit the predicate. After removing them and their preceding elements my final list would look like:

[2,3,4,7,8,11,14,15,18,19,20]

I'm an inexperienced Haskell programmer, and just playing around for fun. I thought of using some kind of lambda function as predicate to a filter, or creating a function like listRemove xs ys that removes all elements of xs that are also an element of ys, but I feel kind of lost on both.

Any help would be appreciated!

EDIT: what I am trying to do is to solve a Project Euler problem, namely #179. The predicate f x is to check whether x is a prime number or not. Therefore I can surely say that no corner cases exists – e.g. there are no cases such as [x, x, t, t] where t is a number for which the predicate holds, since there exists no two consecutive integers that are both prime except for 2 and 3, which I can easily handle in my solution. Instead, the closest you can get is [x, t, x, t], and in that case I want to remove all of those elements.

解决方案

Assuming you have:

disallowed :: Int -> bool
-- A function that matches your example
disallowed x = elem x [6, 10, 13, 17]

What you want is just

import Data.List (tails)

map head . filter (not . any disallowed . take 2) . filter (not . null) . tails $ [2..20]

If you want to give it a name:

filterWithTails :: ([a] -> Bool) -> [a] -> [a]
filterWithTails f = map head . filter f . filter (not . null) . tails

filterWithTails (not . any disallowed . take 2) [2..20]

(not . any disallowed . take 2) is how you want to filter a list considering the remainder of the list when filtering. It'd be hard to give a better name than the composition of the functions that make it up.

这篇关于当n适合谓词时,移除Haskell列表中位置n和n-1的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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