From ab9f58704c883e28fe1567cc55d52fe80d9a016f Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Thu, 10 Jan 2019 13:35:55 +0800 Subject: [PATCH] impl top K items --- .../ch29_heap_solutions/TopKItemsKeeper.scala | 30 +++++++++++++++++++ .../TopKItemsKeeperTest.scala | 25 ++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 scala/src/main/scala/ch29_heap_solutions/TopKItemsKeeper.scala create mode 100644 scala/src/test/scala/ch29_heap_solutions/TopKItemsKeeperTest.scala diff --git a/scala/src/main/scala/ch29_heap_solutions/TopKItemsKeeper.scala b/scala/src/main/scala/ch29_heap_solutions/TopKItemsKeeper.scala new file mode 100644 index 0000000..88eba56 --- /dev/null +++ b/scala/src/main/scala/ch29_heap_solutions/TopKItemsKeeper.scala @@ -0,0 +1,30 @@ +package ch29_heap_solutions + +import scala.collection.mutable + +/** + * keep the top k items in the the class + */ +class TopKItemsKeeper(val itemsToKeepCount: Int) { + + + //have a smallest value top heap + val queue = new mutable.PriorityQueue[Int]()(scala.math.Ordering.Int.reverse) + + def put(item: Int): Unit = { + if (queue.length < itemsToKeepCount) { + queue += item + return + } + + //queue already have the k items + if (item.compareTo(queue.head) > 0) { + queue.dequeue() + queue += item + } + } + + def get(): List[Int] = { + queue.clone().dequeueAll + } +} diff --git a/scala/src/test/scala/ch29_heap_solutions/TopKItemsKeeperTest.scala b/scala/src/test/scala/ch29_heap_solutions/TopKItemsKeeperTest.scala new file mode 100644 index 0000000..b3dd0c9 --- /dev/null +++ b/scala/src/test/scala/ch29_heap_solutions/TopKItemsKeeperTest.scala @@ -0,0 +1,25 @@ +package ch29_heap_solutions + +import org.scalatest.{FlatSpec, Matchers} + +import scala.util.Random + +class TopKItemsKeeperTest extends FlatSpec with Matchers { + + behavior of "TopKItemsKeeperTest" + + it should "put and get top K from the keeper" in { + val length = 50 + val k = 5 + val topKItemsKeeper = new TopKItemsKeeper(k) + val nums = new Array[Int](length) + for (i <- Range(0, length)) { + nums(i) = Random.nextInt + } + + nums.foreach(topKItemsKeeper.put) + val ordering = scala.math.Ordering.Int.reverse + topKItemsKeeper.get().toArray.sorted(ordering) should equal(nums.sorted(ordering).slice(0, k)) + } + +}