我试图通过实施Sedgewick和Wayne的“算法的第4版”(scala)(以及我的技术诀窍,功能风格)练习,将学习与乐趣混合在一起。
在练习1.5.7我阻止并希望有人可以帮助我。所以任务是编写QuickUnion实现。您可以找到Java implementation here。
我已经编写了我的scala版本,它似乎有意义,但控制台输出完全令人沮丧。我正在创建一个包含625个初始组件的数组,但是......最后的组件数量是......零以下
不用多说这是我的实施:
<h4>3. Scouting for a location</h4>
父abstract class和underlying trait都在我的github存储库中。为了便于阅读,我正在Main类下面复制:
package ca.vgorcinschi.algorithms1_5_7.quickUnionUF
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
class QuickUnionUF(size: Int) extends AbstractUF(size) {
override val array = (0 to size).toArray
override def find(p: Int): Int = {
validate(p)
Stream.iterate(p)(p => array(p)).dropWhile { _ != array(p) }.head
}
override def connected(p: Int, q: Int): Boolean = find(p) == find(q)
override def union(p: Int, q: Int) = {
/*
* need to declare Futures outisde
* for-comprehension loop to run in parallel
*/
val fRootP = Future { find(p) }
val fRootQ = Future { find(q) }
for {
rootP <- fRootP
rootQ <- fRootQ
if (rootP != rootQ)
} {
array(rootP) = rootQ
count -= 1
}
}
}
此外,这些是运行输出的第一行和最后一行:
import scala.io.Source
import ca.vgorcinschi.algorithms1_5_7.quickUnionUF.QuickUnionUF
import scala.util.matching.Regex
object Main extends App {
val allLines = Source.fromFile("src/main/resources/mediumUF.txt").getLines().toList
//get & print the initial number of components
val size = allLines.head.trim.toInt
println(s"Le nombre initial de composants est $size")
val uf = new QuickUnionUF(size)
val Integer = new Regex("(-)?(\\d+)")
for (line <- allLines.tail) {
val p = Integer findFirstIn line
assert(p.isDefined)
val intP = p.get toInt
val q = Integer findFirstIn line.substring(p.get.length).replace("\\s+", "")
assert(q.isDefined)
val intQ = q.get.toInt
if (!uf.connected(intP, intQ)) {
uf.union(intP, intQ)
println(s"L`union fait sur $intP et $intQ")
println(s"Le nombre des composants est maintenant - ${uf.counter()}")
}
}
}
我确实害怕鞋子在我的未来或基于流的查找中捏,但我似乎无法弄明白......
答案 0 :(得分:0)
我想我明白了。解决方案很奇怪,因为它让我想知道原始解决方案是如何工作的。基本上我只是重写了父类中的counter()来返回array.distinct.length
,即不同的整数或根:
/*
* takes the initial number of components
* as its argument
*/
abstract class AbstractUF(var count: Int) extends UF{
override def counter() = array.distinct.length
val array: Array[Int]
...
}
输出:
Le nombre initial de composants est 625
L`union fait sur 528 et 503
Le nombre des composants est maintenant - 625
L`union fait sur 548 et 523
Le nombre des composants est maintenant - 624
L`union fait sur 389 et 414
Le nombre des composants est maintenant - 623
L`union fait sur 446 et 421
Le nombre des composants est maintenant - 622
L`union fait sur 552 et 553
Le nombre des composants est maintenant - 621
L`union fait sur 154 et 155
Le nombre des composants est maintenant - 620
...
Le nombre des composants est maintenant - 266
L`union fait sur 295 et 320
Le nombre des composants est maintenant - 266
L`union fait sur 160 et 159
Le nombre des composants est maintenant - 266
L`union fait sur 463 et 464
Le nombre des composants est maintenant - 266
L`union fait sur 10 et 35
Le nombre des composants est maintenant - 266
L`union fait sur 619 et 594
Le nombre des composants est maintenant - 265
L`union fait sur 403 et 402
Le nombre des composants est maintenant - 265