我为数组ArrayBuffet((Int, Int))
中的walker存储x / y坐标的元组。
代表(0,0)
和(2,1)
之间旅程的步骤可以是((0,0), (0,1), (1,1), (2,1))
,((0,0), (1,1), (2,1))
等。
麻烦的是,我需要一种方法来测试步行者是否在圈子里旅行。
E.g。考虑从(0,0)
到(0,1)
的步行路线,其中步行者的路径为((0,0), (1,0), (1,-1), (0,0), (0,1))
。步行者将走了一圈。
方法
def hasLoop(path: ArrayBuffer[(Int,Int)]): Boolean = {
if (path.length < 3) return false
else {
for i <- 0 to path.length - 1 {
val temp = path
temp.remove(i)
if (temp.contains(i)) return true
}
return false
}
}
如果步行者在一次旅行中多次访问坐标。但是,如果助行器从(0,0)
移动到(0,1)
或甚至到(0,2)
,但随后通过(0,1)
返回相同的路径,则不应将其视为循环。
任何人都可以为我的isLoop
方法提供解决方案吗?
答案 0 :(得分:0)
如果我理解正确,您只是想确定一个集合是否具有2次或更多次的相同值。
@annotation.tailrec
def hasLoop(path: Seq[(Int, Int)]): Boolean =
if (path.size < 2) false
else if (path.tail.contains(path.head)) true
else hasLoop(path.tail)
println(hasLoop(Array((0, 0), (0, 1))))
println(hasLoop(Array((0, 0), (1, 0), (1, -1), (0, 0), (0, 1))))
答案 1 :(得分:0)
不确定这是最优雅的解决方案,但我认为它能满足您的需求:
// some type aliases to make this more readable, can do without them too
type Vertex = (Int,Int)
type Edge = (Vertex, Vertex)
def hasLoop(path: Array[Vertex]): Boolean = {
// create all edges - connections between one vertex and the next one in path
val edges: Array[Edge] = path.zip(path.drop(1))
// fold right searching for PREVIOUS edges for which SRC equals current edge's DESTINATION,
// but DESTINATION does not equal current edge's SOURCE
val foldResult: (Seq[Edge], Boolean) = edges.foldLeft((Seq[Edge](), false)) {
case ((visited, found), e) =>
(visited :+ e, found || visited.exists(oldE => oldE._1 == e._2 && oldE._2 != e._1) )
}
foldResult._2 // return the boolean result
}
println(hasLoop(Array((0,0), (1,0), (1,-1), (0,0), (0,1)))) // true
println(hasLoop(Array((0,0), (1,0), (1,-1), (0,0)))) // true
println(hasLoop(Array((0,0), (1,0), (1,-1), (1,0), (0,0)))) // false
println(hasLoop(Array((0,0), (1,0), (1,-1)))) // false