Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell中具有重复的交点的快速长度_List_Haskell_Optimization - Fatal编程技术网

List Haskell中具有重复的交点的快速长度

List Haskell中具有重复的交点的快速长度,list,haskell,optimization,List,Haskell,Optimization,我正在写一个智囊团解算器,在一个内部循环中,我计算两个列表的长度。现在我的功能是 overlap :: Eq c => [c] -> [c] -> Int overlap [] _ = 0 overlap (x:xs) ys | x `elem` ys = 1 + overlap xs (delete x ys) | otherwise = overlap xs ys 有没有可能让这更快?如果有帮助的话,overlap的参数是长度相同的短列表,最多6个元素,c

我正在写一个智囊团解算器,在一个内部循环中,我计算两个列表的长度。现在我的功能是

overlap :: Eq c => [c] -> [c] -> Int
overlap [] _ = 0
overlap (x:xs) ys
    | x `elem` ys = 1 + overlap xs (delete x ys)
    | otherwise = overlap xs ys

有没有可能让这更快?如果有帮助的话,
overlap
的参数是长度相同的短列表,最多6个元素,
c
类型的可能值少于10个。

是否对多个
xs
使用相同的
ys

如果是,您可以尝试为
ys
中的每个元素计算哈希值,并通过该值进行匹配,但请记住,计算哈希值需要比6次比较快

如果其中任何一个是
Ord
,您也可以提前对其进行排序,并只验证
ys
的必要部分

然而,如果你需要快速随机访问列表不是最好的结构,你可能应该看看
数据.Array
数据.HashMap

一般来说,要提高这种算法的性能(几乎)是不可能的:为了删除两个无序和不可破坏的列表中的重复项,可以在O(n^2)中完成

但通常,您可以在以下条件下提高性能(根据条件,采用不同的方法):

  • 例如,如果您可以确保为创建/修改的每个列表/…,保持元素的顺序;这可能需要一些工程。在这种情况下,该算法可以在O(n)中运行

    在这种情况下,您可以使用以下工具运行它:

    --Use this only if xs and ys are sorted
    overlap :: Ord c => [c] -> [c] -> Int
    overlap (x:xs) (y:ys) | x < y = overlap xs (y:ys)
                          | x > y = overlap (x:xs) ys
                          | otherwise = 1 + overlap xs ys
    overlap [] _ = 0
    overlap _ [] = 0
    

排序可以在O(n logn)中完成,而比较可以在O(n^2)中完成,至少要使其尾部递归(因为返回类型是平坦的)。您应该进行基准测试——排序可能仍然值得。@Anschelshaffer-Cohen:如果n=6,我看不出优化这个函数有什么好处。分析通常集中在需要大量计算工作的部分。您可能有一个特定的类型
c
:尝试直接使用它,而不是使用多态函数。或者使用
SPECIALIZE
GHC pragma。我不确定GHC何时专门化。检查GHC核心,看看您的案例中是否真的这样做了。或者添加一个SPECIALIZE pragma,看看它是否对性能有任何影响。我对多个
xs
使用相同的
ys
。但是比较是便宜的(实际上
c
Int
),所以我不认为哈希法会有帮助。我将在未来24小时内的某个时间对这两个想法进行基准测试。当列表很短时,渐近时间复杂度可能是无关紧要的,所以我不想以这种或那种方式猜测什么是最快的。@AnschelSchaffer Cohen:我认为优化在处理如此小的列表时有点(抱歉)无用。一般来说,你不会在这些问题上浪费大量时间。
--Use this only if c can be ordered
overlap :: Ord c => [c] -> [c] -> Int
overlap xs ys = size $ intersection (fromList xs) (fromList ys)