一个haskell函数来测试一个整数是否出现在另一个整数之后

时间:2017-04-23 20:45:11

标签: algorithm haskell

我正在编写一个名为after的函数,该函数将整数列表和两个整数作为参数。在列表之后num1 num2应该返回True如果列表中出现num1并且列表afternum1中出现num2。 (不一定紧接在之后)。

after::[Int]->Int->Int->Bool
after [] _ _=False
after [x:xs] b c 
    |x==b && c `elem` xs =True 
    |x/=b && b `elem` xs && b `elem` xs=True

这就是我到目前为止,我最大的问题是我不知道如何强迫num2在num1之后。

3 个答案:

答案 0 :(得分:7)

有几种不同的方法可以解决这个问题;虽然很有可能直接进行递归,但这很好 如果有另一个选项,请避免显式使用递归。

这是一个使用一些列表实用程序的简单版本。请注意,我们操作的对象通常是最后一个参数,这是一个Haskell习语。在这种情况下,切换参数让我们把它写成一个管道,它的第三个参数(列表)是隐式传递的:

after :: Int -> Int -> [Int] -> Bool
after a b = elem b . dropWhile (/= a)

希望这很容易理解;我们删除列表中的元素,直到我们点击a,假设我们找到一个,我们检查剩余列表中是否有b。如果没有a,则此列表为[],显然此处没有b,因此按预期返回False。

如果'a'和'b'相等,你没有说明会发生什么,所以我会让你自己适应那种情况。提示:在某处添加tail;)

如果您有兴趣,可以采用以下几种方法:

使用折叠非常容易处理;

我们有三种状态可以建模。要么我们正在寻找第一个元素,要么 我们正在寻找第二个元素,或者我们已经找到它们(按照正确的顺序)。

data State =
  FindA | FindB | Found
  deriving Eq

然后我们可以将列表“折叠”(也就是减少)到它是否匹配的结果。

after :: Int -> Int -> [Int] -> Bool
after a b xs = foldl go FindA xs == Found
  where
    go FindA x = if x == a then FindB else FindA
    go FindB x = if x == b then Found else FindB
    go Found _ = Found

如果您愿意,也可以递归地执行:

after :: Int -> Int -> [Int] -> Bool
after _ _ [] = False
after a b (x:xs) 
  | x == a = b `elem` xs
  | otherwise = after a b xs

干杯!

答案 1 :(得分:1)

您可以将其拆分为两部分:第一部分将找到import UIKit class TTTImageView: UIImageView { var player:String? var activated:Bool! = false func setPlayer (_ _player:String){ "<-- error message for this line of code" self.player = _player if activated == false{ if _player == "x"{ self.image = UIImage(named: "x") }else{ self.image = UIImage(named: "o") } activated = true } } } 的第一个匹配项。之后,您只需要删除所有元素,然后检查num1是否在列表的其余部分。

第一部分有标准函数elemIndex。第二个只是num2

elem

答案 2 :(得分:1)

如果您想在没有elemelemIndex的情况下实施它,则可以包含子例程。类似的东西:

after xs b c = go xs False
  where go (x:xs) bFound
          | x == b && not (null xs) = go xs True
          | bFound && x == c        = True
          | null xs                 = False
          | otherwise               = go xs bFound