English 中文(简体)
限定名单的章节
原标题:Intersection of infinite lists

我从可计算性理论中知道,有可能把两个明确清单的交叉点放在一起,但我无法找到在Haskell表达这一清单的途径。

传统方法一旦第二次清单确定就失败了,因为你在第一个清单中花费了全部时间对清单进行核对,以作为非对称的内容。

例:

let ones = 1 : ones -- an unending list of 1s
intersect [0,1] ones

这从未产生<代码>1,因为它从未停止对<代码>ones的核对<0<>。

成功的方法需要确保每个清单的每个部分在一定时间内得到访问。

值得注意的是,这将通过两个清单进行核对,并花费大约相等的时间核对每个清单中所有先前审查的内容。

如果可能的话,我也想办法忽视名单上的重复,因为有时是必要的,但这不是一项要求。

最佳回答
问题回答

一种想法可能是使用水泥包<>。 我首先要缓和问题:允许产生重复价值。 在这种情况下,你可以使用:

import Data.List (intersect)

intersectInfinite :: Eq a => [a] -> [a] -> [a]
intersectInfinite = intersectInfinite  1
    where intersectInfinite  n = intersect (take n xs) (take n ys) ++ intersectInfinite  (n+1)

换言之,我们声称:

A∩B = A1 ∩B1∪ A2>∩B> > ∪ ......

载于first is. (一) 没有任何命令,但可以说有某种命令。 如果这套内容包含less,则全部内容将归还。

<c> > 载于A (at indexi)和B (at indexj,c>> 将在segment(not index)上公布。

因此,无论特定名单是否定点,都总是产生一份明确清单(有一定数量的重复)。 唯一的例外是,当你给它一份空洞的清单时,它将永远搁置。 然而,我们在此确保,交汇点的每一部分至少可以一次汇出。

使结果确定下来(如果特定名单是无限的)

Now we can make our definition better. First we make a more advanced version of take, takeFinite (let s first give a straight-forward, but not very efficient defintion):

takeFinite :: Int -> [a] -> (Bool,[a])
takeFinite _ [] = (True,[])
takeFinite 0 _  = (False,[])
takeFinite n (x:xs) = let (b,t) = takeFinite (n-1) xs in (b,x:t)

我们现在可以直截了当地深化,直至<><>>> > 两个名单都到底:

intersectInfinite :: Eq a => [a] -> [a] -> [a]
intersectInfinite = intersectInfinite  1

intersectInfinite  :: Eq a => Int -> [a] -> [a] -> [a]
intersectInfinite  n xs ys | fa && fb = intersect xs ys
                           | fa = intersect ys xs
                           | fb = intersect xs ys
                           | otherwise = intersect xfa xfb ++ intersectInfinite  (n+1) xs ys
    where (fa,xfa) = takeFinite n xs
          (fb,xfb) = takeFinite n ys

This will now terminate given both lists are finite, but still produces a lot of duplicates. There are definitely ways to resolve this issue more.

Here s one way. For each x we make a list of maybes which has Just x only where x appeared in ys. Then we interleave all these lists.

isect :: Eq a => [a] -> [a] -> [a]
isect xs ys = (catMaybes . foldr interleave [] . map matches) xs
  where
    matches x = [if x == y then Just x else Nothing | y <- ys]

interleave :: [a] -> [a] -> [a]
interleave [] ys = ys
interleave (x:xs) ys = x : interleave ys xs

Maybe it can be improved using some sort of fairer interleaving - it s already pretty slow on the example below because (I think) it s doing an exponential amount of work.

> take 10 (isect [0..] [0,2..])
[0,2,4,6,8,10,12,14,16,18]

如果名单的内容被命令,那么你就很容易这样做。

intersectOrd :: Ord a => [a] -> [a] -> [a]
intersectOrd [] _ = []
intersectOrd _ [] = []
intersectOrd (x:xs) (y:ys) = case x `compare` y of
    EQ -> x : intersectOrd xs ys
    LT -> intersectOrd xs (y:ys)
    GT -> intersectOrd (x:xs) ys

这里还有另一个备选办法,利用<代码> 控制. Monad.WalaedSearch

import Control.Monad (guard)
import Control.Applicative
import qualified Control.Monad.WeightedSearch as W

We first define a cost for digging inside the list. Accessing the tail costs 1 unit more. This will ensure a fair scheduling among the two infinite lists.

eachW :: [a] -> W.T Int a
eachW = foldr (x w -> pure x <|> W.weight 1 w) empty

然后,我们完全无视无限名单。

intersection :: [Int] -> [Int] -> [Int]
intersection xs ys = W.toList $ do
   x <- eachW xs
   y <- eachW ys
   guard (x==y)
   return y

更贴有<条码>的《蒙特利尔议定书》>。

intersection2 :: [Int] -> [Int] -> [Int]
intersection2 xs ys = W.toList [ y | x <- eachW xs, y <- eachW ys, x==y ]

Solution

我最后使用了以下执行办法:对David Fletcher的答复稍加修改:

isect :: Eq a => [a] -> [a] -> [a]
isect [] = const [] -- don t bother testing against an empty list
isect xs = catMaybes . diagonal . map matches
    where matches y = [if x == y then Just x else Nothing | x <- xs]

可以用nub来补充,以过滤重复:

isectUniq :: Eq a => [a] -> [a] -> [a]
isectUniq xs = nub . isect xs

Explanation

<代码>isection xs = catMaybes 。 地图匹配

。 3 ! 0将代表ys ! 3 with xs ! 0,如果这些数值有所不同,将改为Nothing。 如果这些数值相同,则该数值为Just

diagonals takes a list of lists and returns a list of lists where the nth output list contains an element each from the first n lists. Another way to conceptualise it is that (diagonals . map matches) ys !! n contains comparisons between elements whose indices in xs and ys sum to n.
diagonal is simply a flat version of diagonals (diagonal = concat diagonals)

因此, (diagonal .mapcompes) ys/code>是xss各要素之间的比较清单,其中各要素大致按以下各要素的指数的总和加以比较:ysx;这意味着早期要素与较后各项要素相比,与中间要素相比,各部分具有相同的优先权。

(cat Maybes . diagonal .mapcompes) ys is a list of only the elements which are in both list, where the elements are around打上了两个要素的比较指数的总和。

Note
(diagonal . map (catMaybes . matches)) ys does not work: catMaybes . matches only yields when it finds a match, instead of also yielding Nothing on no match, so the interleaving does nothing to distribute the work.

相比之下,在选定的解决办法中,NothingJust的数值通过>diagonal ,意味着该方案在寻找多个不同要素,而不是等待一个因素之后,将其注意力分开;而如果在环绕之前删除<>Nothing的数值,则该方案可能花费太多的时间等待对某一特定要素进行无果的搜索以取得成功。

因此,我们会遇到与原始问题相同的问题:虽然一个因素与另一个清单中的任何内容不相称,但方案将保持不变;而所选择的解决办法将只剩下来,而两个清单中的任何内容都找不到对应办法。





相关问题
Finding a class within list

I have a class (Node) which has a property of SubNodes which is a List of the Node class I have a list of Nodes (of which each Node may or may not have a list of SubNodes within itself) I need to be ...

How to flatten a List of different types in Scala?

I have 4 elements:List[List[Object]] (Objects are different in each element) that I want to zip so that I can have a List[List[obj1],List[obj2],List[obj3],List[obj4]] I tried to zip them and I ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

Is List<> better than DataSet for UI Layer in ASP.Net?

I want to get data from my data access layer into my business layer, then prepare it for use in my UI. So i wonder: is it better to read my data by DataReader and use it to fill a List<BLClasses&...

What is the benefit to using List<T> over IEnumerable<T>?

or the other way around? I use generic lists all the time. But I hear occasionally about IEnumerables, too, and I honestly have no clue (today) what they are for and why I should use them. So, at ...

灵活性:在滚动之前显示错误的清单

我有一份清单,在你滚动之前没有显示任何物品,然后这些物品就显示。 是否有任何人知道如何解决这一问题? 我尝试了叫人名单。

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签