diff --git a/scala/src/main/scala/ch07_linkedlist/LinkedListAlgo.scala b/scala/src/main/scala/ch07_linkedlist/LinkedListAlgo.scala index 1557283e..00af2b79 100644 --- a/scala/src/main/scala/ch07_linkedlist/LinkedListAlgo.scala +++ b/scala/src/main/scala/ch07_linkedlist/LinkedListAlgo.scala @@ -2,8 +2,6 @@ package ch07_linkedlist import ch06_linkedlist.Node -import scala.util.control.Breaks._ - object LinkedListAlgo { //reverse a linked list diff --git a/scala/src/main/scala/ch08_stack/BrowserDemo.scala b/scala/src/main/scala/ch08_stack/BrowserDemo.scala new file mode 100644 index 00000000..555eb79d --- /dev/null +++ b/scala/src/main/scala/ch08_stack/BrowserDemo.scala @@ -0,0 +1,31 @@ +package ch08_stack + +class BrowserDemo(var currentPageOpt: Option[String], val backStack: StackDemo[String], + val forwardStack: StackDemo[String]) { + + def this() = this(None, new StackDemo[String], new StackDemo[String]) + + def open(page: String) = { + currentPageOpt.foreach(backStack.push) + forwardStack.clear() + currentPageOpt = Some(page) + } + + def canGoBack(): Boolean = backStack.size > 0 + + def goBack(): Unit = { + backStack.pop().foreach(page => { + forwardStack.push(currentPageOpt.get) + currentPageOpt = Some(page.data) + }) + } + + def canGoForward(): Boolean = forwardStack.size > 0 + + def goForward(): Unit = { + forwardStack.pop().foreach(page => { + backStack.push(currentPageOpt.get) + currentPageOpt = Some(page.data) + }) + } +} diff --git a/scala/src/main/scala/ch08_stack/StackDemo.scala b/scala/src/main/scala/ch08_stack/StackDemo.scala new file mode 100644 index 00000000..12a3a10b --- /dev/null +++ b/scala/src/main/scala/ch08_stack/StackDemo.scala @@ -0,0 +1,32 @@ +package ch08_stack + +class Node[T](var data: T, var next: Option[Node[T]]) + +class StackDemo[T] { + + + var headOpt: Option[Node[T]] = None + var size = 0 + + def clear(): Unit = { + headOpt = None + size = 0 + } + + def push(data: T) = { + val newHead = new Node(data, headOpt) + headOpt = Some(newHead) + size += 1 + } + + def pop(): Option[Node[T]] = { + headOpt match { + case None => None + case Some(head) => + headOpt = head.next + size -= 1 + Some(head) + + } + } +} diff --git a/scala/src/test/scala/ch08_stack/BrowserDemoTest.scala b/scala/src/test/scala/ch08_stack/BrowserDemoTest.scala new file mode 100644 index 00000000..e78665cf --- /dev/null +++ b/scala/src/test/scala/ch08_stack/BrowserDemoTest.scala @@ -0,0 +1,74 @@ +package ch08_stack + +import org.scalatest.{FlatSpec, Matchers} + +class BrowserDemoTest extends FlatSpec with Matchers { + + behavior of "BrowserDemoTest" + + it should "canGoBack" in { + val browser = new BrowserDemo() + assert(!browser.canGoBack()) + browser.open("a") + assert(!browser.canGoBack()) + browser.open("b") + assert(browser.canGoBack()) + browser.currentPageOpt.get should equal("b") + } + + it should "goBack" in { + val browser = new BrowserDemo() + browser.open("a") + browser.open("b") + browser.currentPageOpt.get should equal("b") + assert(browser.canGoBack()) + browser.goBack() + assert(!browser.canGoBack()) + browser.currentPageOpt.get should equal("a") + } + + it should "canGoForward" in { + val browser = new BrowserDemo() + browser.open("a") + browser.open("b") + browser.currentPageOpt.get should equal("b") + assert(browser.canGoBack()) + browser.goBack() + assert(!browser.canGoBack()) + browser.currentPageOpt.get should equal("a") + assert(browser.canGoForward()) + } + + it should "goForward" in { + val browser = new BrowserDemo() + browser.open("a") + browser.open("b") + browser.currentPageOpt.get should equal("b") + assert(browser.canGoBack()) + browser.goBack() + assert(!browser.canGoBack()) + browser.currentPageOpt.get should equal("a") + assert(browser.canGoForward()) + browser.goForward() + browser.currentPageOpt.get should equal("b") + } + + it should "open new page to clear forward stack" in { + val browser = new BrowserDemo() + browser.open("a") + browser.open("b") + browser.currentPageOpt.get should equal("b") + assert(browser.canGoBack()) + browser.goBack() + assert(!browser.canGoBack()) + browser.currentPageOpt.get should equal("a") + assert(browser.canGoForward()) + browser.open("c") + assert(!browser.canGoForward()) + browser.goBack() + browser.currentPageOpt.get should equal("a") + } + + + +} diff --git a/scala/src/test/scala/ch08_stack/StackDemoTest.scala b/scala/src/test/scala/ch08_stack/StackDemoTest.scala new file mode 100644 index 00000000..a875f9eb --- /dev/null +++ b/scala/src/test/scala/ch08_stack/StackDemoTest.scala @@ -0,0 +1,29 @@ +package ch08_stack + +import org.scalatest.{FlatSpec, Matchers} + +class StackDemoTest extends FlatSpec with Matchers { + + behavior of "StackDemoTest" + + it should "push/pop should be FILO" in { + val stack = new StackDemo[String] + val num = 100 + for (i <- 1 to num) { + stack.push(i.toString) + } + + for (i <- num to 1 by -1) { + stack.pop().get.data should equal(i.toString) + } + } + + it should "pop should also work for empty stack" in { + val stack = new StackDemo[Int] + val num = 100 + for (i <- num to 1 by -1) { + assert(stack.pop().isEmpty) + } + } + +}