Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Scala替代Arrays.binarySearch?_Java_Search_Scala_Programming Languages - Fatal编程技术网

Java Scala替代Arrays.binarySearch?

Java Scala替代Arrays.binarySearch?,java,search,scala,programming-languages,Java,Search,Scala,Programming Languages,Scala中是否有Java的int数组的替代品。binarySearch(Object[]array,Object) 问题是Scala的数组不是协变的,所以我必须先像这样转换我的stringArray:Array[String]: stringArray.asInstanceOf[Array[Object]] 有更好的解决方案吗?据我所知,没有任何内置的解决方案,但您可以使用来相当轻松地完成此任务。像这样: class ObjectArrayTools[T <: AnyRef](a: A

Scala中是否有Java的
int数组的替代品。binarySearch(Object[]array,Object)

问题是Scala的数组不是协变的,所以我必须先像这样转换我的
stringArray:Array[String]

stringArray.asInstanceOf[Array[Object]]

有更好的解决方案吗?

据我所知,没有任何内置的解决方案,但您可以使用来相当轻松地完成此任务。像这样:

class ObjectArrayTools[T <: AnyRef](a: Array[T]) {                  
   def binarySearch(key: T) = {
     java.util.Arrays.binarySearch(a.asInstanceOf[Array[AnyRef]],key)
   }
}
implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new ObjectArrayTools(a)

scala> Array("a","fish","is","some","thing").binarySearch("some")
res26: Int = 3
scala> Array("a","fish","is","some","thing").binarySearch("bye")  
res28: Int = -2
class ObjectArrayTools[T数组(“a”、“fish”、“is”、“some”、“thing”).binarySearch(“再见”)
res28:Int=-2
如果需要,也可以将其他
java.util.array
对象方法添加到同一个类中


总的来说,我觉得习惯于总是导入您最喜欢的Scala实用程序集合是一个好主意。添加这样的功能非常容易,因此您也可以在一般情况下这样做,而不是一直键入
。asInstanceOf[Array[AnyRef]]
,只需稍加努力,您就可以显著提高工作效率。

数组是有趣的野兽。如果您尝试使用“ObjectArrayTools”提供的示例中的代码:

Array(1, 2, 3, 4, 5).binarySearch(3)
你得到

error: value binarySearch is not a member of Array[Int]
          Array(1, 2, 3, 4, 5).binarySearch(3)
有关Scala中数组的情况,请参阅。在任何情况下,您都可以使用此代码,尽管它使用Seq而不是Array。但是,它还有一个额外的优点,即使用排序(恰好也是Java比较器。因此,如果需要,您可以自定义排序行为)

一些例子:

scala> List(1, 2, 3, 4, 5).binarySearch(3)
res0: Int = 2

scala> List(1D, 2D, 3D, 4D, 5D).binarySearch(3.5)
res1: Int = -4

scala> List("a","fish","is","some","thing").binarySearch("bye")
res2: Int = -2
Scala 2.11添加到标准库中。它对索引序列使用二进制搜索,否则使用线性搜索

import scala.collection.Searching._
Array(1, 2, 3, 4, 5).search(3)

用scala编写它并不难

  object BSearch {
    def interative[T](array: Array[T], value: T)(implicit arithmetic: Numeric[T]): Int = {
      var left: Int = 0;
      var right: Int = array.length - 1;
      while (right > left) {
        val mid = left + (right - left) / 2
        val comp = arithmetic.compare(array(mid), value)
        if (comp == 0)
          return mid; //negative if test < value
        else if (comp > 0) //list(mid) > value
          right = mid - 1;
        else if (comp < 0) //list(mid) < value
          left = mid + 1;
      }
      -1;
    }


BSearch.interative(array, value)
对象b搜索{
定义交互[T](数组:数组[T],值:T)(隐式算术:数值[T]):Int={
左变量:Int=0;
var right:Int=array.length-1;
while(右>左){
val mid=左+(右-左)/2
val comp=算术比较(数组(中间)、值)
如果(comp==0)
返回mid;//如果测试<值,则为负值
else if(comp>0)//列表(mid)>值
右=中-1;
else if(comp<0)//列表(mid)
@moshe beeri

如果要用Scala编写,为什么要用Java在Scala中编写?为什么不用Scala编写呢

def split(list:List[Char]): (List[Char], List[Char]) = {
    val len = list.size
    (list.slice(0, len/2), list.slice(len/2,len))
}

def search(target: Char, list: List[Char]):Boolean = {
    list match {
        case Nil => false
        case head :: Nil =>  if (head == target) true else false
        case _ => {
            val c = split(list)
            if (c._1.last >= target) search(target, c._1) else search(target, c._2)
        }
    }
}

这个问题提出已经有几年了,想做一些比较测试,希望它能帮助一些人做出决定:

import scala.collection.Searching._
import _root_.scala.collection.JavaConversions._
import java.util.{Collections, List => JList}
import scala.reflect.ClassTag

class ObjectArrayTools[T <: Int](a: Array[T]) {
   def binarySearch(key: T) = {
     java.util.Arrays.binarySearch(a.asInstanceOf[Array[Int]],key)
   }
}

class SearchableSeq[T](a: Seq[T])(implicit ordering: Ordering[T]) {
    val list: JList[T] = a.toList
    def binarySearch2(key: T): Int = Collections.binarySearch(list, key, ordering)
}

object BinarySearch {
  implicit def anyrefarray_tools[T <: Int](a: Array[T]) = new ObjectArrayTools(a)
  implicit def seqToSearchable[T](a: Seq[T])(implicit ordering: Ordering[T]) =
          new SearchableSeq(a)(ordering)

  def main(args:Array[String]) {
    val informationArray = Array(1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,20,22,23,25,26)
    val informationList = List(1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,20,22,23,25,26)
    //val sortedArray = sortList(informationArray)
    val sortedArray = informationArray
    val sortedList = informationList

    for(x <- 0 to 2) {
      val startTime = System.nanoTime
      val result = binarySearch(sortedArray, 5)
      val result2 = binarySearch(sortedArray, 19)
      println(s"Custom search time elapsed: ${(System.nanoTime - startTime)}")

      val startTime2 = System.nanoTime
      val result3 = sortedArray.search(5)
      val result4 = sortedArray.search(19)
      println(s"Scala search time elapsed: ${(System.nanoTime - startTime2)}")

      val startTime3 = System.nanoTime
      val result5 = sortedArray.binarySearch(5)
      val result6 = sortedArray.binarySearch(19)
      println(s"Java search casting time elapsed: ${(System.nanoTime - startTime3)}")

      val startTime4 = System.nanoTime
      val result7 = sortedList.binarySearch2(5)
      val result8 = sortedList.binarySearch2(19)
      println(s"Java search as list time elapsed: ${(System.nanoTime - startTime4)}")


      val startTime9 = System.nanoTime
      val result10 = binarySearchWithImplicitConversion(sortedArray, 5)
      val result11 = binarySearchWithImplicitConversion(sortedArray, 19)
      println(s"Custom generic time elapsed: ${(System.nanoTime - startTime9)}")

      println("---")
    }
  }

  /*def sortList(list:Array[Int]):Array[Int] = {
    import com.walcron.etc.Quicksort._
    quickSort(list)
  }*/

  //def binarySearch[T <% Ordered[T]](list:Array[T], valueToBeSearch:T)(implicit t:ClassTag[T]):Int =  {
  def binarySearch(list:Array[Int], valueToBeSearch:Int):Int =  {
    def search(start:Int, end:Int):Int = {
      val pos = ((end - start) / 2) + start
      val curr = list(pos)

      if(curr == valueToBeSearch) {
        pos
      }
      else if((end - start) <= 1) {
        -1 * (pos + 1) // Indicates the value should be inserted
      }
      else if(valueToBeSearch > curr) {
        search(pos, end)
      }
      else {
        search(start, pos)
      }
    }

    search(0, list.length)
  }

  def binarySearchWithImplicitConversion[T <% Ordered[T]](list:Array[T], valueToBeSearch:T)(implicit t:ClassTag[T]):Int =  {
    def search(start:Int, end:Int):Int = {
      val pos = ((end - start) / 2) + start
      val curr = list(pos)

      if(curr == valueToBeSearch) {
        pos
      }
      else if((end - start) <= 1) {
        -1 * (pos + 1) // Indicates the value should be inserted
      }
      else if(valueToBeSearch > curr) {
        search(pos, end)
      }
      else {
        search(start, pos)
      }
    }

    search(0, list.length)
  }
}

一般来说,java二进制搜索的性能要好得多;而scala的搜索性能相当差。还有另一个值得注意的性能,似乎泛型类型在这里暗中拖累了性能(因此可能有人可以帮助修复泛型类型)…但间接地,它显示了巨大的性能影响。

关于
def indexOf呢(elem:A,from:Int):Int
这不应该表现得像二进制搜索吗(尽管可能较慢?)@soc没有这个签名,因为
binarySearch
依赖于键的可比性。IIRC,Java只是强制转换并返回一个运行时错误,这不是我们想要从Scala中得到的东西。此外,它只在有序的集合上工作,同样,在没有爆炸的情况下,此时无法静态执行课程数量(已有想法).如果
binarySearch
依赖于
可比较的项目,我们是否应该添加一个约束,例如
t通过索引访问java列表可能非常困难inefficient@piotr.这取决于支持列表的内容。例如,一个ArrayList由一个数组支持;它们在通过i获取元素方面都提供类似的性能ndex。不幸的是,此解决方案不太理想。
Collections.binarySearch
检查提供的列表是否实现了RandomAccess接口(“如果指定的列表未实现RandomAccess接口且较大,此方法将执行基于迭代器的二进制搜索,执行O(n)链接遍历和O(log n)元素比较。”)。JavaConverters提供的列表中没有一个实现该接口。()很好。我没有意识到这一点。看起来scala在2.11中添加了
scala.collection.search
。因此您可以使用:
import scala.collection.search.\u;数组(1,2,3,4,5)。search(3)
我如何才能告诉搜索方法我的数组已排序并且可以使用二进制搜索?@samy您的集合必须排序才能使用
search
。也就是说,如果您对未排序的序列调用
search
,则结果未定义。感谢您的解释,但该方法似乎对我的数组使用线性搜索f type Array[String]它比java.util.Array.binarySearch()慢很多似乎是我使用的scala 2.11版本中的一个bug,@AbhijitSarkar您可以很容易地用scala搜索API区分这些情况,因为
搜索结果
返回的要么是
找到的
,要么是
插入点
。使用
匹配
来判断是哪种情况,这两种情况将被解释它适用于任何阅读代码的人。
import scala.collection.Searching._
import _root_.scala.collection.JavaConversions._
import java.util.{Collections, List => JList}
import scala.reflect.ClassTag

class ObjectArrayTools[T <: Int](a: Array[T]) {
   def binarySearch(key: T) = {
     java.util.Arrays.binarySearch(a.asInstanceOf[Array[Int]],key)
   }
}

class SearchableSeq[T](a: Seq[T])(implicit ordering: Ordering[T]) {
    val list: JList[T] = a.toList
    def binarySearch2(key: T): Int = Collections.binarySearch(list, key, ordering)
}

object BinarySearch {
  implicit def anyrefarray_tools[T <: Int](a: Array[T]) = new ObjectArrayTools(a)
  implicit def seqToSearchable[T](a: Seq[T])(implicit ordering: Ordering[T]) =
          new SearchableSeq(a)(ordering)

  def main(args:Array[String]) {
    val informationArray = Array(1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,20,22,23,25,26)
    val informationList = List(1,2,3,4,5,6,7,8,9,10,11,12,14,15,18,20,22,23,25,26)
    //val sortedArray = sortList(informationArray)
    val sortedArray = informationArray
    val sortedList = informationList

    for(x <- 0 to 2) {
      val startTime = System.nanoTime
      val result = binarySearch(sortedArray, 5)
      val result2 = binarySearch(sortedArray, 19)
      println(s"Custom search time elapsed: ${(System.nanoTime - startTime)}")

      val startTime2 = System.nanoTime
      val result3 = sortedArray.search(5)
      val result4 = sortedArray.search(19)
      println(s"Scala search time elapsed: ${(System.nanoTime - startTime2)}")

      val startTime3 = System.nanoTime
      val result5 = sortedArray.binarySearch(5)
      val result6 = sortedArray.binarySearch(19)
      println(s"Java search casting time elapsed: ${(System.nanoTime - startTime3)}")

      val startTime4 = System.nanoTime
      val result7 = sortedList.binarySearch2(5)
      val result8 = sortedList.binarySearch2(19)
      println(s"Java search as list time elapsed: ${(System.nanoTime - startTime4)}")


      val startTime9 = System.nanoTime
      val result10 = binarySearchWithImplicitConversion(sortedArray, 5)
      val result11 = binarySearchWithImplicitConversion(sortedArray, 19)
      println(s"Custom generic time elapsed: ${(System.nanoTime - startTime9)}")

      println("---")
    }
  }

  /*def sortList(list:Array[Int]):Array[Int] = {
    import com.walcron.etc.Quicksort._
    quickSort(list)
  }*/

  //def binarySearch[T <% Ordered[T]](list:Array[T], valueToBeSearch:T)(implicit t:ClassTag[T]):Int =  {
  def binarySearch(list:Array[Int], valueToBeSearch:Int):Int =  {
    def search(start:Int, end:Int):Int = {
      val pos = ((end - start) / 2) + start
      val curr = list(pos)

      if(curr == valueToBeSearch) {
        pos
      }
      else if((end - start) <= 1) {
        -1 * (pos + 1) // Indicates the value should be inserted
      }
      else if(valueToBeSearch > curr) {
        search(pos, end)
      }
      else {
        search(start, pos)
      }
    }

    search(0, list.length)
  }

  def binarySearchWithImplicitConversion[T <% Ordered[T]](list:Array[T], valueToBeSearch:T)(implicit t:ClassTag[T]):Int =  {
    def search(start:Int, end:Int):Int = {
      val pos = ((end - start) / 2) + start
      val curr = list(pos)

      if(curr == valueToBeSearch) {
        pos
      }
      else if((end - start) <= 1) {
        -1 * (pos + 1) // Indicates the value should be inserted
      }
      else if(valueToBeSearch > curr) {
        search(pos, end)
      }
      else {
        search(start, pos)
      }
    }

    search(0, list.length)
  }
}
Custom search time elapsed: 873373
Scala search time elapsed: 9322723
Java search casting time elapsed: 126380
Java search as list time elapsed: 7375826
Custom generic time elapsed: 4421972
---
Custom search time elapsed: 10372
Scala search time elapsed: 34885
Java search casting time elapsed: 10861
Java search as list time elapsed: 104596
Custom generic time elapsed: 57964
---
Custom search time elapsed: 9121
Scala search time elapsed: 31667
Java search casting time elapsed: 11815
Java search as list time elapsed: 53387
Custom generic time elapsed: 60773