二进制搜索,从java到Actionscript

时间:2009-12-31 21:25:58

标签: java flash actionscript-3 binary

我正在尝试将以下java二进制搜索例程转换为as3。 我假设'compareTo'是内置的java方法,而'>>>'是一种按位运算。

任何熟悉actionscript 3和Java的人都能帮忙解决这个问题吗?

package binary;

public class Finder {

  public static int find( String[ ] keys, String target) {
    int high = keys.length;
    int low = -1;
    while (high - low>1) {
      int probe = (low + high)>>> 1;
      if (keys[probe].compareTo(target) > 0)
        high = probe;
      else
        low = probe;
    }

    if (low==-1 || keys[low].compareTo(target) !=0)
      return -1;
    else
      return low;
  }
}

3 个答案:

答案 0 :(得分:6)

这是一个功能性的AS3版本:

    public static function find(keys:Array, target:String):int {
        var high:int = keys.length;
        var low:int = -1;
        while (high - low > 1) {
            var probe:int = (low + high) / 2;
            if (keys[probe] > target)
                high = probe;
            else
                low = probe;
        }

        if (low == -1 || keys[low] !== target)
            return -1;
        else
            return low;
    }
顺便说一句,我建议你重命名这个函数更有意义,比如binarySearch(),这表明调用者最好对数组进行排序。像find()这样的名称并不意味着这样。

答案 1 :(得分:2)

我无法帮助您使用Actionscript,但compareTo确实是标准的Java方法。它会将调用它的对象与其参数进行比较,如果对象小于参数则返回负值,如果更大则返回正值,如果相等则返回0>>>运算符是右移运算符;您可以将>>> 1替换为/ 2(除以2)。如果编译器足够智能,可以使用移位运算符进行不必要的混淆,如果更好的话,可以使用常量替换除法。 (旁白:如果你的数组有超过2个 30 元素,请阅读this。)

答案 2 :(得分:2)

您应该尽可能使用内置Flash功能。它使您的代码更易于维护,并且生成的SWF将更快更小。查看indexOf() method on Array

这是家庭作业还是你有其他理由使用手写的搜索?

编辑:我应该补充一点,内置搜索是从您提供的索引开始的线性搜索。如果您有一个已经排序的大型数组,则二进制搜索可能会更快。您将不得不尝试交叉的位置 - 它可能低至10.如果您的数组尚未排序,内置的线性搜索将击败组合排序和二进制搜索的裤子。

第二次编辑:我很好奇数组必须有多大才能使indexOf()变慢,所以我运行了一些测试。搜索50个项目的数组,indexOf()对所有项目都更快。搜索100,000个项目的数组,indexOf()的速度最快可达100,然后二进制搜索占主导地位。

要查找100,000个项目中的第50,000个项目,二进制搜索需要0.0078ms而indexOf()需要3.382ms。

这是测试代码。我以前从未对AS3进行过性能测试,因此在静态机器上观看经过的时间是我得到的最好的。 (sprintf是在SO上发布的实现。它只用于生成字符串。)

    private static var myArray:Array;

    public static function setup():void {
        myArray = new Array();
        for (var i:int=0; i < 50; ++i) {
            myArray[i] = sprintf("s%06d", i);
        }
    }

    public static function timingTest():void {
        if (myArray == null) {
            setup();
        }

        var start:Number = getTimer();
        for (var j:int=0; j < 5000; ++j) {
            if (binarySearch(myArray, "s000049") != 49) {
                trace("oops!");
            }
        }
        trace("avg msecs per binarySearch " + (getTimer() - start)/j);

        start = getTimer();
        for (var k:int=0; k < 5000; ++k) {
            if (myArray.indexOf("s000049") != 49) {
                trace("oops!");
            }
        }
        trace("avg msecs per indexOf " + (getTimer() - start)/k);
    }

    public static function binarySearch(keys:Array, target:String):int {
        var high:int = keys.length;
        var low:int = -1;
        while (high - low > 1) {
            var probe:int = (low + high) / 2;
            if (keys[probe] > target)
                high = probe;
            else
                low = probe;
        }
        if (low == -1 || keys[low] !== target)
            return -1;
        else
            return low;
    }
}