我正在编写一个名为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之后。
答案 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)
如果您想在没有elem
或elemIndex
的情况下实施它,则可以包含子例程。类似的东西:
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