我正在尝试将以下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;
}
}
答案 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;
}
}