【问题标题】:Check if coordinates create a loop检查坐标是否创建循环
【发布时间】:2016-11-22 00:18:31
【问题描述】:

我将步行者的 x/y 坐标元组存储在数组 ArrayBuffet((Int, Int)) 中。

代表(0,0)(2,1) 之间旅程的步骤可以是((0,0), (0,1), (1,1), (2,1))((0,0), (1,1), (2,1)) 等。

麻烦的是,我需要一种方法来测试步行者是否在绕圈行驶。

例如考虑从(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
    }
  }

如果步行者在一次旅程中多次访问某个坐标。但是,如果 walker 从 (0,0) 移动到 (0,1) 甚至到 (0,2),但随后通过 (0,1) 返回相同的路径,则不应将其视为循环。

谁能为我的isLoop 方法提供解决方案?

【问题讨论】:

  • 您对循环的定义不清楚 - 如果我理解正确,当且仅当路径包含相同的 vertex 时(例如 (0,0) ) 不止一次,但有多个路径(由 组成(例如(0,0) -&gt; (0,1))通过该顶点?

标签: scala


【解决方案1】:

如果我的理解正确,您只是想确定一个集合是否有 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))))

【讨论】:

  • 很确定这将是 ~O(n^2) 的时间复杂度,因为您对列表的每个元素执行 O(n) contains
【解决方案2】:

不确定这是最优雅的解决方案,但我认为它可以满足您的需求:

// 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多