Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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
Scala::树映射在更新后不平衡?_Scala_Immutability_Treemap - Fatal编程技术网

Scala::树映射在更新后不平衡?

Scala::树映射在更新后不平衡?,scala,immutability,treemap,Scala,Immutability,Treemap,我想做的是能够调整TreeMap中项目的键顺序,所以 我可能可以通过一些静态数据找到一个对象,这些数据不会改变 如果贴图是展平的,则对象的位置应考虑其优先级 以下测试用例适用于numEntries=6,但不适用于大于7的值。我真的不明白那里出了什么问题,但我怀疑在一些更新/拷贝之后,树会被解除。所以,有人可以提出建议吗?是我的错还是Scala 2.9中的树形图有某种缺陷 如果循环失败,则更新 for (i <- 1 to (numEntries - 1)) { 替换为 for (i &l

我想做的是能够调整TreeMap中项目的键顺序,所以

我可能可以通过一些静态数据找到一个对象,这些数据不会改变 如果贴图是展平的,则对象的位置应考虑其优先级 以下测试用例适用于numEntries=6,但不适用于大于7的值。我真的不明白那里出了什么问题,但我怀疑在一些更新/拷贝之后,树会被解除。所以,有人可以提出建议吗?是我的错还是Scala 2.9中的树形图有某种缺陷

如果循环失败,则更新

for (i <- 1 to (numEntries - 1)) {
替换为

for (i <- (numEntries - 1) to 1 by -1) {
一切正常。看来这就是树状图中的错误

  import org.scalatest.FlatSpec
  import collection.immutable.TreeMap
  import org.junit.runner.RunWith
  import org.scalatest.junit.JUnitRunner

  @RunWith(classOf[JUnitRunner])
  class TreeMapTest extends FlatSpec {

    //val numEntries = 6;
    val numEntries = 10;

    sealed case class Entry(first: Option[Int], last: Int) extends Ordered[Entry] {

      def compare(that: TreeMapTest.this.type#Entry) = {
        if (first.isEmpty || that.first.isEmpty) {
          last compare that.last
        } else {
          (first.get compare that.first.get) match {
            case 0 => last compare that.last
            case x => x
          }
        }
      }

      def increase() = copy(first = Some(this.first.getOrElse(0) + 1))

    }

    type Container = TreeMap[Entry, Entry]

    "TreeMap" should "allow updates" in {
      var dataMap: Container = new Container() ++ (for (i <- 1 to numEntries) yield Entry(Some(0), i) -> Entry(Some(0), i))
      for (i <- 1 to (numEntries - 1)) {
        val key = new Entry(None, i)
        dataMap.get(new Entry(None, i)) match {
          case Some(e) =>
            val newEntry = e.increase()
            dataMap = (dataMap - key) + (newEntry -> newEntry)
          case None => fail("Can not find entry " + key)
        }
      }
    }

  }

我发现TreeMap基本操作中不太可能有bug——Scala 2.9.0之前有很多bug,但现在有一个强大的测试套件支持RedBlack,它支持store

更有可能的是,问题出现在您没有一个完整的订单。假设你有三个要素:

val a = Entry(Some(0), 3)
val b = Entry(Some(1), 0)
val c = Entry(None, 1)
那么以下是正确的:

scala> a < b
res39: Boolean = true

scala> b < c
res40: Boolean = true

scala> c < a
res41: Boolean = true
因此,d
      b
     / \ 
    a   e
   /
  d

现在,如果你在这棵树中查找c,你会首先比较c和b,发现c比b大。这意味着您将只查看包含e的正确分支,而永远不会找到d。

我发现TreeMap基本操作中不太可能有错误-Scala 2.9.0之前有很多错误,但现在有一个强大的测试套件支持RedBlack,它支持store

更有可能的是,问题出现在您没有一个完整的订单。假设你有三个要素:

val a = Entry(Some(0), 3)
val b = Entry(Some(1), 0)
val c = Entry(None, 1)
那么以下是正确的:

scala> a < b
res39: Boolean = true

scala> b < c
res40: Boolean = true

scala> c < a
res41: Boolean = true
因此,d
      b
     / \ 
    a   e
   /
  d

现在,如果你在这棵树中查找c,你会首先比较c和b,发现c比b大。这意味着您将只查看包含e的右侧分支,您将永远不会找到d。

首选1直到numEntries超过1到numEntries-1。首选1直到numEntries超过1到numEntries-1。那么,如果我以相反的顺序迭代,它为什么能正常工作呢?另外请注意,我没有在地图中没有的项目,它只在我知道有效负载的情况下使用,但不知道项目的当前顺序。因此,当我在地图中插入一些东西时,它定义了严格且一致的顺序。这纯粹是运气,算法在后退时选择了正确的比较。正如Daniel指出的,您的比较函数被破坏了,但这并不意味着它在幸运的情况下不能产生正确的结果。@jdevelop我举了一个有效树的例子来重现您的问题。那么,如果我按相反的顺序迭代,为什么它能正常工作呢?另外请注意,我没有在地图中没有的项目,它只在我知道有效负载的情况下使用,但不知道项目的当前顺序。因此,当我在地图中插入一些东西时,它定义了严格且一致的顺序。这纯粹是运气,算法在后退时选择了正确的比较。正如Daniel指出的,您的比较函数被破坏了,但这并不意味着它在幸运的情况下不能产生正确的结果。@jdevelop我举了一个有效树的例子来重现您的问题。