Java最左端二进制搜索
我试图修改一个递归二进制搜索函数,以便在数组包含元素的倍数时,它能找到元素最左边的索引Java最左端二进制搜索,java,arrays,search,integer,binary-search,Java,Arrays,Search,Integer,Binary Search,我试图修改一个递归二进制搜索函数,以便在数组包含元素的倍数时,它能找到元素最左边的索引 import java.util.*; import java.util.Arrays; import java.io.File; import java.io.IOException; public class LeftmostBinarySearch { private static int myBinarySearch(int key, int[] a, int lo, int hi) {
import java.util.*;
import java.util.Arrays;
import java.io.File;
import java.io.IOException;
public class LeftmostBinarySearch {
private static int myBinarySearch(int key, int[] a, int lo, int hi) {
if (lo > hi) {
return -1;
}
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) {
return myBinarySearch(key, a, lo, mid - 1);
} else if (key > a[mid]) {
return myBinarySearch(key, a, mid + 1, hi);
} else {
return mid;
}
}
public static int myBinarySearch(int key, int[] a) {
return myBinarySearch(key, a, 0, a.length - 1);
}
public static void main(String[] args) throws IOException {
String fileName = args[0] + ".txt";
System.out.println(fileName);
Scanner scanner = new Scanner(new File(fileName));
int[] data = new int[7];
int i = 0;
int j = 0;
while (scanner.hasNextInt()) {
data[i] = scanner.nextInt();
i++;
}
Arrays.sort(data);
System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", " 0",
" ", " 1", " ", " 2", " ", " 3", " ", " 4", " ", " 5", " ", " 6\n");
System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", data[j],
" ", data[j + 1], " ", data[j + 2], " ", data[j + 3], " ",
data[j + 4], " ", data[j + 5], " ", data[j + 6] + "\n");
int input = new Scanner(System.in).nextInt();
while ((Integer) input != null) {
int key = input;
System.out.println(data[0]);
if (myBinarySearch(key, data) != -1) {
System.out.println(input + " found: "
+ myBinarySearch(key, data));
}
input = new Scanner(System.in).nextInt();
}
}
}
我已经尝试将计算mid的方式更改为(hi+lo-1)/2,它适用于40,给出索引3,但对于20,给出索引2。您需要检查如果(key==a[mid])
。如果相等,则需要检查左侧部分的最后一个元素是否相同,直到找到另一个元素为止
import java.util.*;
import java.util.Arrays;
import java.io.File;
import java.io.IOException;
public class LeftmostBinarySearch {
private static int myBinarySearch(int key, int[] a, int lo, int hi) {
if (lo > hi) {
return -1;
}
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) {
return myBinarySearch(key, a, lo, mid - 1);
} else if (key > a[mid]) {
return myBinarySearch(key, a, mid + 1, hi);
} else {
return mid;
}
}
public static int myBinarySearch(int key, int[] a) {
return myBinarySearch(key, a, 0, a.length - 1);
}
public static void main(String[] args) throws IOException {
String fileName = args[0] + ".txt";
System.out.println(fileName);
Scanner scanner = new Scanner(new File(fileName));
int[] data = new int[7];
int i = 0;
int j = 0;
while (scanner.hasNextInt()) {
data[i] = scanner.nextInt();
i++;
}
Arrays.sort(data);
System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", " 0",
" ", " 1", " ", " 2", " ", " 3", " ", " 4", " ", " 5", " ", " 6\n");
System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", data[j],
" ", data[j + 1], " ", data[j + 2], " ", data[j + 3], " ",
data[j + 4], " ", data[j + 5], " ", data[j + 6] + "\n");
int input = new Scanner(System.in).nextInt();
while ((Integer) input != null) {
int key = input;
System.out.println(data[0]);
if (myBinarySearch(key, data) != -1) {
System.out.println(input + " found: "
+ myBinarySearch(key, data));
}
input = new Scanner(System.in).nextInt();
}
}
}
在向左或向右分支之前,应进行以下检查
if (key == a[mid]) {
while (--mid >= 0) {
if (key != a[mid]) {
break;
}
}
return ++mid;
}
问题在于最后一行:
else return mid;
您的列表包含重复项,因此mid可能不是最左边的匹配项。因此,请尝试:
else {
while(--mid>=0) {
if (a[mid]!=key) break;
}
return mid+1;
}
成功了。我没有考虑在最后做这件事。谢谢!然而,这又引入了另一对决策块和循环,增加了算法的复杂性,是否有使用“标准”实现的优化方法,或者应该使用Hermann Bottenbruch的替代过程->