我一直在努力使这段代码有效。我必须创建二进制搜索的通用二进制版本。我不确定如何在没有类似接口的情况下比较两种泛型类型
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.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");
}
}
答案 0 :(得分:10)
public class BinarySearcher<T extends Comparable<T>> { ...
这将允许您的BinarySearcher为可以与compareTo
进行比较的所有内容工作,这应该是通用的。
答案 1 :(得分:7)
您的通用方法无法比较某些任意类型T
的两个实例,而不会对T
有任何限制,或者有其他方式提供有关如何比较两个T
的信息第
您有几个选择:
向T
添加约束:
public class BinarySearcher<T extends Comparable<T>>
或者将Comparator<T>
传递给您可以调用的search
方法进行比较:
public int search(T v, Comparator<T> comp) {
// ...
if (comp.compare(v, midVal < 0)) {
// ...
}
旁注:我会避免在compareTo
方法中拨打search
两次;你不知道比较这两个对象是否昂贵。而不是:
if (v.compareTo(midVal) < 0) {
low = mid - 1;
}
else if (v.compareTo(midVal) > 0) {
high = mid + 1;
}
做这样的事情:
int result = v.compareTo(midVal);
if (result < 0) {
low = mid - 1;
}
else if (result > 0) {
high = mid + 1;
}
答案 2 :(得分:1)
即使执行了上面建议的所有更改,您使用的条件也不正确(更改低指针和高指针),如果要返回索引,则需要在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;
}
}
答案 3 :(得分:0)
不可能比较未实现Comparable
接口的类型。不是使用compareTo()
。
答案 4 :(得分:0)
试试这个:
class BinarySearcher<T extends Comparable<T>>
答案 5 :(得分:0)
@ Erik的回答显示了如何修改代码,以便它要求参数类型T
具有可比性。
另一种选择是使用Comparator<T>
; e.g。
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;
}
}
你可以通过修改原始构造函数来结合这两种方法,以使用比较器来转换它想要与Comparable
实例进行比较的第一个值。这可能会进行不安全的转换,如果与T对应的实际类型实际上不是ClassCastException
,则会导致Comparable
。
从设计角度来看,如果BinarySearcher
构造函数检查words
已排序或对数组本身进行排序,那将是一个更好的主意。如果未正确订购words
,二进制搜索将给出错误的答案。
答案 6 :(得分:0)
正如其他人已经提到的那样,提升T扩展Comparable将解决您的问题。 Buuuut为什么要重新发明轮子?您可以轻松使用现有的通用Java二进制搜索:
System.out.println(Arrays.binarySearch(words, "November", null));
请注意,如果将null作为可比较参数传递,则采用自然元素顺序!
享受!
答案 7 :(得分:0)
可以使用以下类对二进制搜索任何数据类型。
Try
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Pradnya_DataB.mdb"
con.Open()
ds1 = New DataSet
ss = "Select c1.cust_name,c1.cust_bottle_type,c2.B_Pending From Customer c1"
ss = ss + " INNER JOIN Bottel_Collect c2 ON c2.Cust_ID=c1.Cust_ID WHERE c1.Cust_ID=" & CInt(lblText.Text)
'ss = "Select * from Customer"
da = New OleDbDataAdapter(ss, con)
da.Fill(ds1)
If ds1.Tables.Count > 0 Then
TextBox2.Text = ds1.Tables("Custmor").Rows(0).Item(0).ToString()
TextBox5.Text = ds1.Tables("Customer").Rows(0).Item(1).ToString()
TextBox6.Text = ds1.Tables("Bottel_Collect").Rows(0).Item(5).ToString()
End If
con.Close()
rd.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try