通用二进制搜索Java
我一直在努力使这个代码工作。我必须创建二进制搜索的通用二进制版本。如果没有可比较的接口,我不知道如何比较两个泛型类型通用二进制搜索Java,java,Java,我一直在努力使这个代码工作。我必须创建二进制搜索的通用二进制版本。如果没有可比较的接口,我不知道如何比较两个泛型类型 import java.util.ArrayList; public class BinarySearcher<T> { private T[] a; public BinarySearcher(T[] words) { a = words; } public int search(T v) {
import java.util.ArrayList;
public class BinarySearcher<T> {
private T[] a;
public BinarySearcher(T[] words) {
a = words;
}
public int search(T v) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
T midVal = a[mid];
if (v.compareTo(midVal) < 0) {
low = mid - 1;
}
else if (v.compareTo(midVal) > 0) {
high = mid + 1;
}
}
return -1;
}
public int compareTo(T a) {
return this.value.compare - b;
}
}
import java.util.ArrayList;
公共类二进制搜索器{
私人T[]a;
公共二进制搜索器(T[]字){
a=文字;
}
公共整数搜索(TV){
int低=0;
int高=a.长度-1;
while(低0){
高=中+1;
}
}
返回-1;
}
公共整数比较(TA){
返回此.value.compare-b;
}
}
这是tester类:
import java.util.Arrays;
import java.util.Scanner;
/**
This program tests the binary search algorithm.
*/
public class BinarySearchTester {
public static void main(String[] args) {
String[] words = {"Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet", "Kilo", "Lima",
"Mike", "November", "Oscar", "Papa", "Quebec", "Romeo",
"Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-Ray",
"Yankee", "Zulu"};
BinarySearcher<String> searcher = new BinarySearcher<String>(words);
System.out.println(searcher.search("November"));
System.out.println("Expected: 13");
System.out.println(searcher.search("October"));
System.out.println("Expected: -1");
}
}
导入java.util.array;
导入java.util.Scanner;
/**
这个程序测试二进制搜索算法。
*/
公共类二进制搜索测试器{
公共静态void main(字符串[]args){
String[]words={“Alpha”、“Bravo”、“Charlie”、“Delta”、“Echo”,
“狐步舞”、“高尔夫”、“酒店”、“印度”、“朱丽叶”、“基洛”、“利马”,
“迈克”、“十一月”、“奥斯卡”、“爸爸”、“魁北克”、“罗密欧”,
“塞拉”、“探戈”、“制服”、“维克多”、“威士忌”、“X光”,
“扬基”,“祖鲁”};
BinarySearcher search=新的BinarySearcher(单词);
System.out.println(searcher.search(“11月”);
System.out.println(“预期:13”);
System.out.println(searcher.search(“十月”);
系统输出打印项次(“预期:-1”);
}
}
公共类二进制搜索程序{…
这将允许您的BinarySearcher处理可以与
compareTo
进行比较的所有内容,这应该足够通用。不可能比较未实现Comparable
接口的类型。而不是使用compareTo()
如果对T
没有任何约束,或者没有关于如何比较两个T
的其他方式的信息,您的泛型方法就无法比较某个任意类型的两个实例T
您有几个选择:
将约束添加到T
:
public class BinarySearcher<T extends Comparable<T>>
旁注:在search
方法中,我会避免调用compareTo
两次;您不知道比较这两个对象是否昂贵。而不是这样:
if (v.compareTo(midVal) < 0) {
low = mid - 1;
}
else if (v.compareTo(midVal) > 0) {
high = mid + 1;
}
if(v.compareTo(midVal)<0){
低=中-1;
}
如果(v.compareTo(midVal)>0,则为其他情况{
高=中+1;
}
这样做:
int result = v.compareTo(midVal);
if (result < 0) {
low = mid - 1;
}
else if (result > 0) {
high = mid + 1;
}
int result=v.compareTo(midVal);
如果(结果<0){
低=中-1;
}
否则,如果(结果>0){
高=中+1;
}
试试这个:
class BinarySearcher<T extends Comparable<T>>
类二进制搜索器
@Erik的回答显示了如何修改代码,以使参数类型T
具有可比性
另一种选择是使用比较器,例如
import java.util.ArrayList;
public class BinarySearcher<T> {
private T[] a;
private Comparator<T> c;
public BinarySearcher(T[] words, Comparator<T> comparator) {
a = words;
c = comparator;
}
public int search(T v) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
T midVal = a[mid];
if (c.compare(v, midVal) < 0) {
low = mid - 1;
}
else if (c.compare(v, midVal) > 0) {
high = mid + 1;
}
}
return -1;
}
}
import java.util.ArrayList;
公共类二进制搜索器{
私人T[]a;
专用比较器c;
公共二进制搜索器(T[]字,比较器){
a=文字;
c=比较器;
}
公共整数搜索(TV){
int低=0;
int高=a.长度-1;
while(低0){
高=中+1;
}
}
返回-1;
}
}
您可以通过修改原始构造函数来组合这两种方法,以使用一个比较器,该比较器将要比较的第一个值转换为Comparable
实例。这可能会进行不安全的转换,如果与T对应的实际类型实际上不是可比的,则会导致ClassCastException
从设计的角度来看,如果
BinarySearcher
构造函数检查words
是否已排序,或者对数组本身进行排序,这将是一个更好的主意。如果单词的顺序不正确,二进制搜索将给出错误的答案。正如前面提到的其他方法一样,leting T extends Comparable将解决您的问题。你为什么要重新发明轮子?您可以轻松使用现有的通用Java二进制搜索:
System.out.println(Arrays.binarySearch(words, "November", null));
注意,如果null作为可比较参数传递,则采用自然元素顺序
享受吧 即使在执行了上面建议的所有更改之后,您使用的条件仍然不正确(您更改了低位和高位指针),并且如果要返回索引,您需要在else之后使用else子句
public class BinarySearcher<T extends Comparable<T>> {
private T[] a;
public BinarySearcher(T[] words) {
a = words;
}
public int search(Comparable<T> v) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
T midVal = a[mid];
int result = v.compareTo(midVal);
if (result < 0) {
high = mid - 1;
}
else if (result > 0) {
low = mid + 1;
}
else {
return mid;
}
}
return -1;
}
}
公共类二进制搜索器{
私人T[]a;
公共二进制搜索器(T[]字){
a=文字;
}
公共整数搜索(可比v){
int低=0;
int高=a.长度-1;
while(低0){
低=中+1;
}
否则{
中途返回;
}
}
返回-1;
}
}
以下类可用于对任何数据类型进行二进制搜索
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class GenericBinarySearch{
private int midPoint(int iMin, int iMax){
return iMin + (iMax - iMin)/2;
}
public <T> int search(List<T> list, T Key, int iMin, int iMax, Comparator<T> comparator){
if(list == null || list.size() == 0){
return -1;
}
int iMid = midPoint(iMin, iMax);
if(iMid > iMax || iMid < iMin){
return -1;
}
if(comparator.compare(list.get(iMid), Key) > 0){
return search(list, Key, iMin, iMid-1, comparator);
}else if(comparator.compare(list.get(iMid), Key) < 0){
return search(list, Key, iMid+1, iMax, comparator);
}else{
return iMid;
}
}
public static void main(String[] args) {
GenericBinarySearch bs = new GenericBinarySearch();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
int key = 2;
int iMin = 0;
int iMax = list.size()-1;
//Java 8 - Lambda expressions
// new Comparator( public T int compare(T o1, T o2) {
// return o1.compareTo(o2);
// }) ---> same expression is replaced by
// (T o1, T o2) -> o1.compareTo(o2) or (o1,o2) -> o1.compareTo(o2)
int index = bs.search(list, key, iMin, iMax, (o1,o2) -> o1.compareTo(o2));
System.out.println(index);
}
}
import java.util.ArrayList;
导入java.util.Comparator;
导入java.util.List;
公共类GenericBinarySearch{
专用int中点(int iMin,int iMax){
返回iMin+(iMax-iMin)/2;
}
公共整数搜索(列表列表、T键、整数iMin、整数iMax、比较器){
if(list==null | | list.size()==0){
返回-1;
}
int iMid=中点(iMin,iMax);
if(iMid>iMax | | iMid0){
返回搜索(列表、键、iMin、iMid-1、比较器);
}else if(comparator.compare(list.get(iMid),Key)<0){
返回搜索(列表、键、iMid+1、iMax、比较器);
}否则{
返回iMid;
}
}
公共静态void main(字符串[]args){
GenericBinarySearch bs=新建GenericBinarySearch();
列表=新的ArrayList();
增加第(1)款;
增加(2);
增加(3);
增加(4);
增加(5);
int键=2;
int-iMin=0;
在里面
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class GenericBinarySearch{
private int midPoint(int iMin, int iMax){
return iMin + (iMax - iMin)/2;
}
public <T> int search(List<T> list, T Key, int iMin, int iMax, Comparator<T> comparator){
if(list == null || list.size() == 0){
return -1;
}
int iMid = midPoint(iMin, iMax);
if(iMid > iMax || iMid < iMin){
return -1;
}
if(comparator.compare(list.get(iMid), Key) > 0){
return search(list, Key, iMin, iMid-1, comparator);
}else if(comparator.compare(list.get(iMid), Key) < 0){
return search(list, Key, iMid+1, iMax, comparator);
}else{
return iMid;
}
}
public static void main(String[] args) {
GenericBinarySearch bs = new GenericBinarySearch();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
int key = 2;
int iMin = 0;
int iMax = list.size()-1;
//Java 8 - Lambda expressions
// new Comparator( public T int compare(T o1, T o2) {
// return o1.compareTo(o2);
// }) ---> same expression is replaced by
// (T o1, T o2) -> o1.compareTo(o2) or (o1,o2) -> o1.compareTo(o2)
int index = bs.search(list, key, iMin, iMax, (o1,o2) -> o1.compareTo(o2));
System.out.println(index);
}
}