case class Employee (id: Int, name : String, age : Int)
// Added four emplyees emp1, emp2 emp3, emp4 to the list like below::
val emp1 = Employee(101, "name1", 101)
val emp2 = Employee(102, "name2", 102)
val emp3 = Employee(103, "name3", 103)
val emp4 = Employee(104, "name4", 104)
list = scala.List(emp1, emp2, emp3, emp4)
我想使用BINARY SEARCH在列表中按员工的姓名搜索,然后检索该员工对象。
请注意:搜索复杂度应为O(logn),我们不应为此目的使用任何地图。
类似
val emp = list.binarysearch("name2")
println("the returned employee's age: ", emp.age) //should print 102
任何帮助将不胜感激!!
答案 0 :(得分:3)
Searching提供二进制搜索,但是您需要一个索引序列,而不是线性序列(即List
),正如其他人所解释的那样-否则您仍然可以使用search
但您会得到线性的O(n)行为,而不是O(Log n)。
您说要搜索名称,因此需要按名称排序,否则结果可能会不一致。您应该研究scala.math.Ordering
因此,如果您可以将列表转换为数组,则可以执行此操作。
case class Employee (id: Int, name : String, age : Int)
val emp1 = Employee(1, "Jane Doe", 45)
val emp2 = Employee(2, "Jon Doe", 54)
val emp3 = Employee(3, "Tera Patrick", 38)
val emp4 = Employee(4, "Jenna Jameson", 36)
// convert to an array
val employees = List(emp1, emp2, emp3, emp4).toArray
// define your ordering
import scala.math.Ordering
implicit object NameOrdering extends Ordering[Employee] {
def compare(a:Employee, b:Employee) = a.name compare b.name
}
// now sort
import scala.util.Sorting
Sorting.quickSort(employees)(NameOrdering)
然后。
import scala.collection.Searching._
// If the element is found its index is returned
scala> val result = employees.search(emp3)
result: collection.Searching.SearchResult = Found(3)
要检索元素,请对结果使用insertionPoint
方法。
scala> employees(result.insertionPoint)
res6: Employee = Employee(3,Tera Patrick,38)
如果找不到该元素,则返回其插入点在排序序列中的索引。
val emp5 = Employee(5, "Aurora Snow", 34) // not added
scala> employees.search(emp5)
res2: collection.Searching.SearchResult = InsertionPoint(0)
答案 1 :(得分:0)
您永远无法在O(log n)中的scala List()上进行二进制搜索,因为我们无法一次丢弃一半的列表,因此必须遍历直到那。但是,可以使用数组来完成。在Scala中,您可以创建一个隐式类,以在任何Array [String]实例上具有binarySearch()方法
implicit class StrArrayOps(strArray: Array[String]) {
@scala.annotation.tailrec
private def bs(arr: Array[String], s: Int, e: Int, str: String): Option[Int] = {
if (e<s) {
None
} else {
val m = (s+e)/2
val mid = arr(m)
if (mid == str) {
Some(m)
} else {
if (str.compareTo(mid) > 0) {
bs(arr, m+1, e, str)
} else {
bs(arr, 0, m-1, str)
}
}
}
}
//returns None if str not found in the strArray
//returns Some(i) where i is the index of str in the strArray
def binarySearch(str: String): Option[Int] = bs(strArray, 0, strArray.length-1, str)
}
您可以按以下方式使用它
scala> val a = Array("name1", "name2", "name3")
a: Array[String] = Array(name1, name2, name3)
scala> a.binarySearch("name2")
res20: Option[Int] = Some(1)
scala> a.binarySearch("name1")
res21: Option[Int] = Some(0)
scala> a.binarySearch("name3")
res22: Option[Int] = Some(2)
scala> a.binarySearch("name34")
res23: Option[Int] = None