Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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_Ghc_Ghci_Palindrome - Fatal编程技术网

List Haskell(长得可怕)回文检查

List Haskell(长得可怕)回文检查,list,haskell,ghc,ghci,palindrome,List,Haskell,Ghc,Ghci,Palindrome,我正在努力向臭名昭著的方向发展,我在四处游荡(看看列表是否是回文)。我知道大多数解决方案在合理的短名单上都能很好地发挥作用。现在我如何编写一个函数来测试一个很长的列表是否是回文,例如 let ll = [1..10000000] ++ [10000000, 10000000-1..1] ++ [7] 我(也许天真地)试图这样测试它: isPalindrome [] = True isPalindrome [_] = True isPalindrome [x,y] = x==y isPalind

我正在努力向臭名昭著的方向发展,我在四处游荡(看看列表是否是回文)。我知道大多数解决方案在合理的短名单上都能很好地发挥作用。现在我如何编写一个函数来测试一个很长的列表是否是回文,例如

let ll = [1..10000000] ++ [10000000, 10000000-1..1] ++ [7]
我(也许天真地)试图这样测试它:

isPalindrome [] = True
isPalindrome [_] = True
isPalindrome [x,y] = x==y
isPalindrome (x:xs) = isPalindrome [x,last xs] && (isPalindrome $ init xs)
我假设如果
isPalindrome[x,last xs]
的计算结果为
False
,则不会计算
&
昂贵的右侧

我分析了上述情况,以下是它产生的结果:

Mon Jun 30 18:33 2014 Time and Allocation Profiling Report  (Final)

   h99 +RTS -p -RTS

total time  =        1.29 secs   (1292 ticks @ 1000 us, 1 processor)
total alloc = 2,720,050,200 bytes  (excludes profiling overheads)

COST CENTRE  MODULE  %time %alloc

main         Main     95.6  100.0
isPalindrome Main      4.4    0.0

                                                          individual     inherited
COST CENTRE     MODULE                  no.     entries  %time %alloc   %time %alloc

MAIN            MAIN                     43           0    0.0    0.0   100.0  100.0
 CAF            Main                     85           0    0.0    0.0   100.0  100.0
  main          Main                     86           1   95.6  100.0   100.0  100.0
   isPalindrome Main                     87           2    4.4    0.0     4.4    0.0
 CAF            GHC.Conc.Signal          84           0    0.0    0.0     0.0    0.0
 CAF            GHC.IO.Encoding          77           0    0.0    0.0     0.0    0.0
 CAF            GHC.IO.Encoding.Iconv    75           0    0.0    0.0     0.0    0.0
 CAF            GHC.IO.Handle.FD         68           0    0.0    0.0     0.0    0.0
 CAF            GHC.Show                 63           0    0.0    0.0     0.0    0.0
从中我推断问题在于
last xs
,这可能需要计算整个
xs
。如果是,是否有解决办法?或者仅仅是
[a..b]
的实现,即 贪婪


谢谢。

我想这是你怀疑的
最后一个xs
。建议:在执行任何递归之前,在中点*处拆分字符串,并反转后半部分。然后在每次递归时比较两个字符串的第一个字符*如果字符串长度为奇数,则两个字符串都应包含中间字符。

我认为这是您怀疑的
最后一个xs
。建议:在执行任何递归之前,在中点*处拆分字符串,并反转后半部分。然后在每次递归时比较两个字符串的第一个字符*如果字符串长度为奇数,则两个字符串都应包含中间字符。

正如您猜测的那样,
最后一个xs
是个问题-它将在列表长度上花费线性时间,并强制立即生成整个列表(
[a..b]
与Haskell列表一般一样是惰性的)。因此,您的
isPalindrome
函数总共将是二次时间

对于一个简单的实现,我将从
xs==reverse xs
开始,它具有正确的渐近行为(线性),但具有相对较高的常数因子,并将在
reverse
到达列表末尾并开始生成结果时,在内存中有两个完整的列表副本

通过查看
长度,然后在中间点拆分列表,或者在一次传球中做一些更聪明的事情,您可能会对该方法有所改进


然而,我认为,为了获得更好的性能,您需要切换数据结构-我会查看类似于或的内容。

正如您猜测的那样,
最后一个xs
是个问题-它将花费列表长度的线性时间,并强制立即生成整个列表(
[a..b]
是懒惰的,就像Haskell列表一般一样)。因此,您的
isPalindrome
函数总共将是二次时间

对于一个简单的实现,我将从
xs==reverse xs
开始,它具有正确的渐近行为(线性),但具有相对较高的常数因子,并将在
reverse
到达列表末尾并开始生成结果时,在内存中有两个完整的列表副本

通过查看
长度,然后在中间点拆分列表,或者在一次传球中做一些更聪明的事情,您可能会对该方法有所改进


然而,我认为,为了获得更好的性能,您需要切换数据结构-我将查看类似于或的内容。

建议在以下位置使用一系列有趣的回文函数:

天真的

无意义

palindrome = liftM2 (==) reverse id
实用的

palindrome = (==) <$> reverse <*> id

以下是一些有趣的回文函数:

天真的

无意义

palindrome = liftM2 (==) reverse id
实用的

palindrome = (==) <$> reverse <*> id

哈,又是你!谢谢你回答我的哈斯克尔问题。事实上,
Data.Dequeue
似乎是这个实现的更好的数据结构。哈,你又来了!谢谢你回答我的哈斯克尔问题。实际上,
Data.Dequeue
似乎是这种实现的更好的数据结构。