From 93927772601b5681953e5e2d5e3ed70d7cc4d667 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 28 Dec 2018 14:29:42 +0800 Subject: [PATCH] transformed binary search --- .../src/main/scala/ch16_bsearch/BSearch.scala | 87 +++++++++++++++++++ .../test/scala/ch16_bsearch/BSearchTest.scala | 31 +++++++ 2 files changed, 118 insertions(+) create mode 100644 scala/src/main/scala/ch16_bsearch/BSearch.scala create mode 100644 scala/src/test/scala/ch16_bsearch/BSearchTest.scala diff --git a/scala/src/main/scala/ch16_bsearch/BSearch.scala b/scala/src/main/scala/ch16_bsearch/BSearch.scala new file mode 100644 index 0000000..74e2fbe --- /dev/null +++ b/scala/src/main/scala/ch16_bsearch/BSearch.scala @@ -0,0 +1,87 @@ +package ch16_bsearch + +object BSearch { + + //find the first index of given value + //-1 if not found + def findFirstValue(items: Array[Int], target: Int): Int = { + require(items.length > 0, "given array is empty") + var low = 0 + var high = items.length - 1 + while (low <= high) { + val mid = low + (high - low) / 2 + if (items(mid) > target) { + high = mid - 1 + } else if (items(mid) < target) { + low = mid + 1 + } else { + //find the value in the array + if (mid == 0 || items(mid - 1) != target) { + return mid + } else { + high = mid - 1 + } + } + } + -1 + } + + def findLastValue(items: Array[Int], target: Int): Int = { + var low = 0 + var high = items.length - 1 + while (low <= high) { + val mid = low + (high - low) / 2 + if (items(mid) > target) { + high = mid - 1 + } else if (items(mid) < target) { + low = mid + 1 + } else { + //find the target value + if (mid == items.length - 1 || items(mid + 1) != target) { + return mid + } else { + low = mid + 1 + } + } + } + -1 + } + + def findFirstGreaterThan(items: Array[Int], target: Int): Int = { + var low = 0 + var high = items.length + while (low <= high) { + val mid = low + (high - low) / 2 + if (items(mid) >= target) { + //find the range + if (mid == 0 || items(mid - 1) < target) { + return mid + } else { + high = mid - 1 + } + } else { + low = mid + 1 + } + } + -1 + } + + def findLastSmallerThan(items: Array[Int], target: Int): Int = { + var low = 0 + var high = items.length - 1 + while (low <= high) { + var mid = low + (high - low) / 2 + if (items(mid) <= target) { + //find the range + if (mid == items.length - 1 || items(mid + 1) > target) { + return mid + } else { + low = mid + 1 + } + } else { + high = mid - 1 + } + } + -1 + } +} diff --git a/scala/src/test/scala/ch16_bsearch/BSearchTest.scala b/scala/src/test/scala/ch16_bsearch/BSearchTest.scala new file mode 100644 index 0000000..89da6fa --- /dev/null +++ b/scala/src/test/scala/ch16_bsearch/BSearchTest.scala @@ -0,0 +1,31 @@ +package ch16_bsearch + +import org.scalatest.{FlatSpec, Matchers} + +class BSearchTest extends FlatSpec with Matchers { + + behavior of "BSearchTest" + + it should "findFirstValue" in { + val items = Array(1, 3, 4, 5, 6, 8, 8, 8, 11, 18) + BSearch.findFirstValue(items, 8) should equal(5) + } + + it should "findLastValue" in { + val items = Array(1, 3, 4, 5, 6, 8, 8, 8, 11, 18) + BSearch.findLastValue(items, 8) should equal(7) + } + + it should "findFirstGreaterThan" in { + val items = Array(1, 3, 4, 5, 6, 8, 8, 8, 11, 18) + BSearch.findFirstGreaterThan(items, 2) should equal(1) + BSearch.findFirstGreaterThan(items, 8) should equal(5) + } + + it should "findLastSmallerThan" in { + val items = Array(1, 3, 4, 5, 6, 8, 8, 8, 11, 18) + BSearch.findLastSmallerThan(items, 2) should equal(0) + BSearch.findLastSmallerThan(items, 8) should equal(7) + } + +}