Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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
Algorithm O(n^2)算法运行时间差_Algorithm_Haskell_Time Complexity - Fatal编程技术网

Algorithm O(n^2)算法运行时间差

Algorithm O(n^2)算法运行时间差,algorithm,haskell,time-complexity,Algorithm,Haskell,Time Complexity,我正试图和哈斯克尔一起解决问题,但我已经超过了时间限制。我很确定我的算法复杂度是我能得到的最好的。因此,我怀疑Haskell本身就是问题所在(库、严格性等),但我不知道它可能是什么 import Data.Array import Data.List main :: IO () main = do x <- readLn interact $ unlines . fmap proccess . take x . lines pro

我正试图和哈斯克尔一起解决问题,但我已经超过了时间限制。我很确定我的算法复杂度是我能得到的最好的。因此,我怀疑Haskell本身就是问题所在(库、严格性等),但我不知道它可能是什么

import           Data.Array
import           Data.List

main :: IO ()
main = do
    x <- readLn
    interact $ unlines . fmap proccess . take x . lines

proccess :: String -> String
proccess line = show $ minimumDisjoint line

minimumDisjoint :: String -> Int
minimumDisjoint s = minimumBy sortFn [1..len] -- gets minimum elem from list O(n)
    where
    len = length s
    str = listArray (1, len) s
    sortFn i1 i2 = foo i1 i2  -- basically 'string1 > string2' O(n)
        where
        foo i3 i4
            | i3 > len      = foo 1 i4
            | i4 > len      = foo i3 1
            | i3 == i1 -1   = ord
            | ord == EQ     = foo (i3+1) (i4+1)
            | otherwise     = ord
            where
            ord = compare (str ! i3) (str ! i4)
导入数据。数组
导入数据。列表
main::IO()
main=do
x字符串
过程行=显示$minimumDisjoint行
最小不相交::字符串->整数
minimumDisjoint s=minimumBy sortFn[1..len]--从列表O(n)中获取最小元素
哪里
len=长度s
str=listArray(1,len)s
sortFn i1 i2=foo i1 i2——基本上是'string1>string2'O(n)
哪里
foo i3 i4
|i3>len=Foo1I4
|i4>len=FooI3 1
|i3==i1-1=ord
|ord==EQ=foo(i3+1)(i4+1)
|否则=ord
哪里
ord=比较(str!i3)(str!i4)

谢谢你的建议

最坏的情况是所有元素都相等的字符串,看起来像
minimumDisjoin
是O(n^2)

也许这会起作用,可能是O(n):

通过字符串查找最小元素的索引列表

但您需要的不是索引连续运行的起始位置和长度的列表:运行长度编码

接下来是处理包裹

然后,在最长距离跑后采取适当的位置


下一关只需比较最长运行设置后的点。最糟糕的情况是,这是原始列表的一半大小,并且正在比较非重叠字符串,比原始重叠问题更有效。

由于输入仅为ASCII,您应该尝试使用
ByteString
无处不在,而不是
String
,以获得O(1)索引,而不是O(n)在
sortFn
和更快的I/O中。我不熟悉Haskel,但您使用的方法是什么,也许您可以简单地解释一下?这个问题可以在
O(n)
O(n*log(n))
时间内解决,两者都应该很容易通过测试。@FordO。如果是
O(n^2)
那么问题在于算法,而不是语言非常确定
O(n^2)
对于一个长度字符串
1e5
已经是
1e10
操作的顺序,即使在功能强大的机器上进行了最佳优化
C
代码,也只需几秒钟。通常情况下,如果您看到时间限制为0.5s,比如这个问题,你需要努力寻找一个线性或
O(n*log(n))
的解决方案,如果你愿意的话,我可以为你提供方法,但是如果最初的主题是询问haskell代码的疑难解答,那么这将是一个离题的问题:Pmuch simpler-将字符串x附加到它本身,x->x+x。现在构建后缀数组,并在其中选择起始索引范围为[0..n-1]的最小后缀