最近决定重拾Java,于是拿起了Robert Sedgewick的《算法》。初读两节,发现很多知识点都遗忘了,但是这本书讲得很细,值得一啃。
书里给的第一个例子就是二分查找算法,这是个很经典的算法,晚上闲来无事,就试着用Java实现了。由于这本书的代码包含了作者及其团队封装的包(algs4.jar),我便去网上下载并导入了这个包,但是运行源代码后一直出现如图所示的错误:
我在网上查了很久,都没有找到解决的办法,这就有点尴尬了。也许是Sedgewick他老人家又update了这个包,导致运行时出现了上图所示的问题吧。于是我改了部分代码,将需要readInts()这个函数的部分用标准输入流替换了。
不多说,以下是完整代码:
/*注释部分为出错代码所在的代码块,本代码仍调用了部分algs4.jar中的方法*/
import java.util.Arrays;
import java.io.*;
//import edu.princetion.cs.algs4.In;
//import edu.princetion.cs.algs4.StdIn;
import edu.princetion.cs.algs4.StdOut;
public class BinarySearch{
public static int rank(int k,int[] a)
{//二分查找实现部分
int lo = 0;
int hi = a.length - 1;
int mid = lo + (hi - lo) / 2;
while(lo <= hi){//若lo>hi,则退出循环
if(k < a[mid])//若k在中间值的左边,则将hi的值改为mid+1,即重新划定上界
hi = mid + 1;
else if(k > a[mid])//若k在值的右边,则将lo的值改为mid-1,即重新划定下界
lo = mid - 1;
else //否则说明已找到该数,返回其位置
return mid;
}
return -1;
}
public static void main(String[] args){
BufferedReader reader = new BufferedReader(InputStreamReader(System.in));//这个好像是输入流
String r = null;
try{
r = reader.readline();//按行读取输入的信息
}catch(IOException e){
e.printStackTrace();
}
int[] a = new int[r.length()];//用来存储将输入的字符串转换为int型数据后的数组
for(int i = 0; i < r.length(); i++){
a[i] = Integer.paserInt(String.valueOf(r.charAt(i)));
/*
调用r.charAt(i)代码,返回字符串的第i个字符
调用String.valueOf(s),将char型转换为String(但是此处的字符串只有一个字符)
调用Integer.parseInt(s),将字符串s转换为数字
此处没有出错处理语句,默认输入的为数字型字符串
*/
}
Arrays.sort(a);//注:只有当数组有序时才能进行二分查找
int key = 5;
rank(key,5);
StdOut.println(key);//标准输出,其实与System.out.println(key)效果一致
}
/*
public static void main(String[] args){
int [] whitelist = In.readInts(args[0]);//此处为唯一报错部分,书中源代码是读取文件来进行二分查找的。readInts(filename)函数的作用应为:读取文件,并将文件内容转换为数字输出
Arrays.sort(whitelist);
while(!StdIn.isEmpty()){
int key = StdIn.readInt();
if(rank(key,whitelist) == -1)
StdOut.println(key);
}
}*/
}
最后,再介绍一种十分强大、简单粗暴的实现二分查找的方法:
Arrays.binarysearch(int a,int[] b);
其实,这个算法是封装在Arrays里的。也就是说,对于一个无序数组,我们只需1.Arrays.sort(b);2.Arrays.binarysearch(a,b);就能实现了………………………………………