我正在使用scala.collection.mutable.TreeSet而我遇到了一个问题,在调用android {
buildTypes {
debug {
}
release {
}
}
productFlavors {
free {
}
paid {
}
}
}
configurations {
freeDebugCompile
paidDebugCompile
freeReleaseCompile
paidReleaseCompile
}
dependencies {
freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')
}
时无法删除元素。
我的代码:
-=
以下示例显示,未删除(18,46)。直到那一刻,删除工作完美。我有其他测试用例,它们完美地工作以及在达到大约100次迭代之前不会发生此问题的其他情况。我对val discovered = new TreeSet[Position]()(Ordering by { position => estimation(position) })
//Position is defined as: type Position = (Int, Int)
discovered += start
var x = 0
while(!discovered.isEmpty){
val current = discovered.head
println(discovered)
discovered -= current
println(discovered)
x += 1
println(s"$x $current")
[...] //Code to process current and discover new positions
}
的不可变实现有了相同的结果。
部分输出:
TreeSet
答案 0 :(得分:3)
问题是你的排序不稳定,两个给定元素之间的关系可能会在代码运行时发生变化,使树的内容无效(你没想到每次都会重新排序树的元素你更新你的哈希地图,是吗?)。
我认为,你应该考虑完全抛弃你拥有的东西,并从一开始就重新思考你的方法。尝试在功能方面实现它,避免使用变量和可变结构可能会有所帮助,除了使代码更清晰,更清晰之外,它还可以帮助您避免像这样的错误。
答案 1 :(得分:0)
感谢大家的回答!排序与问题有关,因此找到错误有很多帮助。
澄清:
我实现了很多功能齐全的代码库。对于这个算法,由于几个原因是不可能的。另外:如果有一个PriorityQueue,它有一个updateElement()函数,我会使用它而不是TreeSet来获得更好的性能并避免我遇到的问题。
我的解决方案:
如上所述:我必须将其变为可变且主要是必要的。问题在于那些代码行
estimation(somePosition) = newScore
if(alreadyDiscovered){ discovered -= somePosition }
discovered += somePosition
从somePosition
删除discovered
正在使用排序,该排序在上面的行中已更改。因此,当RB树尝试删除元素时,它不再找到它。 以下代码适用于所有测试用例
if(alreadyDiscovered){ discovered -= somePosition }
estimation(somePosition) = newScore
discovered += somePosition
如果在vanilla scala中有一个比TreeSet更好的数据结构来执行此任务,我很乐意切换到该任务。