Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
Loops 使用递归而不是循环(无列表)将c代码转换为haskell代码_Loops_Haskell_Recursion_Nested_Counter - Fatal编程技术网

Loops 使用递归而不是循环(无列表)将c代码转换为haskell代码

Loops 使用递归而不是循环(无列表)将c代码转换为haskell代码,loops,haskell,recursion,nested,counter,Loops,Haskell,Recursion,Nested,Counter,我想将下面的c代码转换为haskell代码,而不使用列表。它返回给定n的两个数字的出现次数,其中n满足n=a*a*b*b*b 我想惯用翻译应该是这样的: n = 46656 tr = sqrt n counter = length [ () | i <- [1..tr] , j <- [1..tr] , i*i*j*j*j == n ] 并不是说这是不可能的,但绝对不是最好看的: counter n = go (sqrt n) (sqrt n

我想将下面的c代码转换为haskell代码,而不使用列表。它返回给定n的两个数字的出现次数,其中n满足n=a*a*b*b*b


我想惯用翻译应该是这样的:

n = 46656
tr = sqrt n
counter = length
    [ ()
    | i <- [1..tr]
    , j <- [1..tr]
    , i*i*j*j*j == n
    ]

并不是说这是不可能的,但绝对不是最好看的:

counter n = go (sqrt n) (sqrt n)
    where
    go 0 _  = 0
    go i tr = (go2 tr 0 i) + (go (i - 1) tr)
    go2 0 c i = c
    go2 j c i = go2 (j - 1) (if i^2 * j^3 == n then c + 1 else c) i

翻译命令式代码的一种通用且相对简单的方法是用一个函数替换每个基本块,并为它使用的每一个状态提供一个参数。如果它是一个循环,它将使用这些参数的不同值重复跟踪调用本身。如果您不关心打印中间结果,则直接翻译为:

主程序打印外部循环的结果,外部循环从i=1和计数器=0开始

这些是常量,因此我们可以将它们绑定到循环之外:

    n = 46656
    tr = floor (sqrt n)
外部循环尾部使用递增的i调用自身,计数器由内部循环更新,直到i>tr,然后返回最终计数器

    outer i counter
      | i <= tr = outer (i + 1) (inner 1 counter)
      | otherwise = counter
      where

回答得很好,我还考虑过为计数器查找列表的长度,但不幸的是,我必须在haskell中实现它,而不使用列表和导入的代码:-。也许只剩下递归了?就像重新发明轮子。谁让你这么做而不列出清单?似乎是一个毫无意义的练习。我的捕获者:-抱歉,hahaI将sqrt更改为一个自定义sqrtInt函数,它成功了。你是一个救世主,真的从心底感谢你!!!你的作业似乎和我的一样
main = print (outer 1 0)
  where
    n = 46656
    tr = floor (sqrt n)
    outer i counter
      | i <= tr = outer (i + 1) (inner 1 counter)
      | otherwise = counter
      where
        inner j counter'
          | j <= tr = inner (j + 1) $ let
            res = i ^ 2 * j ^ 3
            in if res == n then counter' + 1 else counter'
          | otherwise = counter'