Skip to content

Instantly share code, notes, and snippets.

@asethia
Last active July 8, 2018 14:20
Show Gist options
  • Save asethia/9c8b80f5188066c6361835e7b048adc5 to your computer and use it in GitHub Desktop.
Save asethia/9c8b80f5188066c6361835e7b048adc5 to your computer and use it in GitHub Desktop.
Assume you have a method isSubstring which checks if one word is a substring of another.
import org.scalatest.{Matchers, WordSpec}
import scala.annotation.tailrec
/**
* Assume you have a method isSubstring which checks if one word is a substring of another.
* Given two strings, 51 and 52, write code to check if 52 is a rotation of 51 using only
* one call to isSubstring (e.g.,"waterbottle"is a rotation of"erbottlewat").
* Time Complexity: O(n)
* Created by Arun Sethia on 7/7/18.
*/
trait StringRotation {
/**
* this is using high order function contains
*
* @param s1
* @param s2
* @return
*/
def isSubStringHighOrder(s1: String, s2: String): Boolean = {
if (s1.length != s2.length)
false
else {
val n = s1 + s1
n.contains(s2)
}
}
/**
* this is without using any high order functions
*
* @param s1
* @param s2
* @return
*/
def isSubString(s1: String, s2: String) = {
//convert to char list
val s1Chars: List[Char] = s1.toList
//length of s1 string
val s1Len = s1Chars.length
@tailrec
def isRotatedSubString(lastMatch: Boolean, mchars: List[Char], matchIndex: Int): Boolean = {
if (mchars == Nil) lastMatch
else {
val cChar = mchars.head
val nChar = mchars.tail
//current char from s1 is matching with s2 char
val matches = (s1Chars(matchIndex) == cChar)
val next =
if (matches) nChar
else {
//since last match was true and now it is not matching means wrong string
if ((matchIndex > 0 && lastMatch) || nChar == Nil) Nil
else mchars
}
if (matchIndex == (s1Len - 1)) {
//if last matched index was last one then move to zeroth index
isRotatedSubString(matches, next, 0)
} else {
//else increment by 1
isRotatedSubString(matches, next, matchIndex + 1)
}
}
}
//if lengths are not equal
if (s1Len != s2.length)
false
else //start matching rotation
isRotatedSubString(false, s2.toList, 0)
}
}
class StringRotationSpec extends WordSpec
with Matchers
with StringRotation {
"erbottlewat" should {
"rotated string of waterbottle" in {
assert(isSubString("waterbottle", "erbottlewat"))
}
}
"waterbottle" should {
"rotated string of erbottlewat" in {
assert(isSubString("erbottlewat", "waterbottle"))
}
}
"a" should {
"not rotated string of b" in {
assert(!isSubString("a", "b"))
}
}
"abb" should {
"not rotated string of bb" in {
assert(!isSubString("abb", "bb"))
}
}
"abb" should {
"rotated string of bba" in {
assert(isSubString("abb", "bba"))
}
}
"erbottlewat" should {
"rotated string of waterbottle using high order fn" in {
assert(isSubStringHighOrder("waterbottle", "erbottlewat"))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment