diff --git a/scala/build.sbt b/scala/build.sbt index 6710bb4..9972b7f 100644 --- a/scala/build.sbt +++ b/scala/build.sbt @@ -2,5 +2,6 @@ lazy val root = (project in file(".")) .settings( name := "algo-scala", version := "1.0", - scalaVersion := "2.12.8" + scalaVersion := "2.12.8", + libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test" ) diff --git a/scala/src/main/scala/ch05_array/ArrayDemo.scala b/scala/src/main/scala/ch05_array/ArrayDemo.scala new file mode 100644 index 0000000..73b5e7d --- /dev/null +++ b/scala/src/main/scala/ch05_array/ArrayDemo.scala @@ -0,0 +1,53 @@ +package ch05_array + +class ArrayDemo(capacity: Int) { + + var data: Array[Char] = new Array[Char](capacity) + var length: Int = 0 + + def find(index: Int): Char = { + if (index < 0 || index > length) { + return 0.toChar + } + data(index) + } + + def insert(index: Int, value: Char): Boolean = { + if (length == capacity) { + return false + } + + if (index < 0 || index >= capacity) { + return false + } + + for (i <- length until index by -1) { + data(i) = data(i - 1) + } + data(index) = value + length += 1 + + true + } + + def delete(index: Int): Char = { + if (length == 0) { + throw new IllegalStateException("array is empty") + } + if (index >= length) { + throw new IllegalStateException("index out of range, current data length is " + length) + } + val result = data(index) + for (i <- index until length-1) { + data(i) = data(i + 1) + } + + length -= 1 + result + } + + def print: String = { + data.subSequence(0, length).toString + } + +} diff --git a/scala/src/main/scala/11_sorts/Sorts.scala b/scala/src/main/scala/ch11_sorts/Sorts.scala similarity index 95% rename from scala/src/main/scala/11_sorts/Sorts.scala rename to scala/src/main/scala/ch11_sorts/Sorts.scala index dfce2d7..bf110d3 100644 --- a/scala/src/main/scala/11_sorts/Sorts.scala +++ b/scala/src/main/scala/ch11_sorts/Sorts.scala @@ -1,4 +1,6 @@ -import scala.util.control.Breaks._ +package ch11_sorts + +import scala.util.control.Breaks.{break, breakable} /** * 冒泡排序、插入排序、选择排序 diff --git a/scala/src/main/scala/15_bsearch/BSearch.scala b/scala/src/main/scala/ch15_bsearch/BSearch.scala similarity index 95% rename from scala/src/main/scala/15_bsearch/BSearch.scala rename to scala/src/main/scala/ch15_bsearch/BSearch.scala index 0c8d0b4..2165938 100644 --- a/scala/src/main/scala/15_bsearch/BSearch.scala +++ b/scala/src/main/scala/ch15_bsearch/BSearch.scala @@ -1,3 +1,5 @@ +package ch15_bsearch + object BSearch { def search(nums: Array[Int], target: Int): Int = { var low = 0 @@ -12,7 +14,7 @@ object BSearch { return mid } } - + return -1 } } diff --git a/scala/src/main/scala/15_bsearch/BSearchRecursive.scala b/scala/src/main/scala/ch15_bsearch/BSearchRecursive.scala similarity index 85% rename from scala/src/main/scala/15_bsearch/BSearchRecursive.scala rename to scala/src/main/scala/ch15_bsearch/BSearchRecursive.scala index b14a706..ca7befc 100644 --- a/scala/src/main/scala/15_bsearch/BSearchRecursive.scala +++ b/scala/src/main/scala/ch15_bsearch/BSearchRecursive.scala @@ -1,20 +1,22 @@ +package ch15_bsearch + object BSearchRecursive { def search(nums: Array[Int], target: Int): Int = { return searchInternal(nums, target, 0, nums.length - 1) } - + def searchInternal(nums:Array[Int], target: Int, low: Int, high: Int): Int = { if(low <= high){ val mid = low + ((high - low) >> 2) if(nums(mid) > target){ searchInternal(nums, target, low, mid - 1) - } else if (nums(mid) < target){ + } else if (nums(mid) < target){ searchInternal(nums, target, mid + 1, high) } else { return mid } }else{ - return -1 + return -1 } } } diff --git a/scala/src/test/scala/ch05_array/ArrayDemoSpec.scala b/scala/src/test/scala/ch05_array/ArrayDemoSpec.scala new file mode 100644 index 0000000..98691ba --- /dev/null +++ b/scala/src/test/scala/ch05_array/ArrayDemoSpec.scala @@ -0,0 +1,67 @@ +package ch05_array + +import org.scalatest.{FlatSpec, Matchers} + +class ArrayDemoSpec extends FlatSpec with Matchers { + + behavior of "ArrayDemoTest" + + it should "find value after insert" in { + val demo = new ArrayDemo(10) + assert(demo.insert(0, 'a')) + assert(demo.insert(1, 'b')) + assert(demo.insert(2, 'c')) + assert(demo.insert(3, 'd')) + assert(demo.insert(4, 'e')) + demo.print should equal("abcde") + + assert(demo.insert(2, 'x')) + demo.print should equal("abxcde") + } + + it should "not insert value if capacity is full " in { + val demo = new ArrayDemo(10) + for (i <- Range(0, 10)) { + demo.insert(i, (i + 97).toChar) + } + + assert(!demo.insert(1, 'a')) + } + + it should "not insert if index is negative" in { + val demo = new ArrayDemo(10) + assert(!demo.insert(-1, 'a')) + } + + it should "not insert if index is exceed capacity" in { + val demo = new ArrayDemo(10) + assert(!demo.insert(10, 'a')) + assert(!demo.insert(11, 'a')) + } + + it should "not find after delete" in { + val demo = new ArrayDemo(10) + assert(demo.insert(0, 'a')) + assert(demo.insert(1, 'b')) + assert(demo.insert(2, 'c')) + assert(demo.insert(3, 'd')) + assert(demo.insert(4, 'e')) + demo.print should equal("abcde") + + + assert(demo.insert(2, 'x')) + demo.print should equal("abxcde") + + demo.delete(2) should equal('x') + demo.find(2) should not equal ('x') + demo.print should equal("abcde") + } + + it should "not delete for empty array" in { + val demo = new ArrayDemo(10) + assertThrows[IllegalStateException] { + demo.delete(2) should equal('x') + } + } + +}