心血来潮
最近突然像提升一下编程功底,想试试acm题,但还是有点害怕。找了些书籍,看到算法这本书,经典之作,又是java编写,可省去好多麻烦,便开始学习。
pdf,提取码wexq
官方网站,有代码与资料
一些问题
算法这一书使用了普林斯顿大学自定义的java标准库,algs4.jar,提取码gmeq,需要将其下载导入使用。使用的过程中有一些坑,就顺便记录下来了。
本人使用的时IDEA,创建了一个工程名为Algorithms的工程。
algs4.jar的放置位置
应该放在工程使用的jdk的扩展文件夹里,比如我使用的是jdk8,其位置即为D:\Java\jdk1.8.0_211\jre\lib\ext\algs.jar
首先我的工程结构为
使用的书上的代码
package Chapter1_base;
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import java.util.Arrays;
/**
* @author ZhangXiong
* @version v12.0.1
* @date 2021-01-13
* 二分查找
* 使用方式
* javac J02BinarySearch.java
* java J02BinarySearch tinyAllowlist.txt < tinyText.txt
* java J02BinarySearch largeAllowlist.txt < largeText.txt | more
*/
public class J02BinarySearch {
/**
* 二分
* @param key 要找的值
* @param a 排好序的数组
* @return
*/
public static int rank(int key, int[] a) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) {
hi = mid - 1;
} else if
(key > a[mid]) {
lo = mid + 1;
} else {
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] whitelist = In.readInts(args[0]); // 白名单里的数进行读取
Arrays.sort(whitelist);
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
if (rank(key, whitelist) == -1) {
StdOut.println(key);
}
}
}
}
要对该工程导入依赖就点击file的Project Structure进行设置
然后这样添加algs4.jar包所在位置
然后勾选点击应用即可。
在IDEA的Terminal进行测试
请务必正确放置algs4.jar的位置,否者使用命令行编译的时候会出现找不到文件的问题,例如错误的位置
就会出现包不存在的情况
D:\Java\JavaProject\Algorithms\src\Chapter1_base>javac J02BinarySearch.java
J02BinarySearch.java:3: 错误: 程序包edu.princeton.cs.algs4不存在
import edu.princeton.cs.algs4.In;
^
J02BinarySearch.java:4: 错误: 程序包edu.princeton.cs.algs4不存在
import edu.princeton.cs.algs4.StdIn;
^
J02BinarySearch.java:5: 错误: 程序包edu.princeton.cs.algs4不存在
import edu.princeton.cs.algs4.StdOut;
^
J02BinarySearch.java:34: 错误: 找不到符号
int[] whitelist = In.readInts(args[0]);
^
符号: 变量 In
位置: 类 J02BinarySearch
J02BinarySearch.java:36: 错误: 找不到符号
while (!StdIn.isEmpty()) {
^
符号: 变量 StdIn
位置: 类 J02BinarySearch
J02BinarySearch.java:37: 错误: 找不到符号
int key = StdIn.readInt();
^
符号: 变量 StdIn
位置: 类 J02BinarySearch
J02BinarySearch.java:39: 错误: 找不到符号
StdOut.println(key);
^
符号: 变量 StdOut
位置: 类 J02BinarySearch
7 个错误
而将包放入正确位置就可编译成功
运行文件
得到如下结果,与网站例子给出结果一致
值得一提的是,对数据量大的文件使用命令行的时候,那个more与前面的命令是用 | 隔开的,而不是左右斜线,当时脑子糊涂,忘记linux命令中常用的管道了,也没在windows用过这种命令。。要学的还多
而且本来我是把BinarySearch.java相关的文件放在Chapter1_base里的,在这个路径可编译,但是编译后的文件不能运行,会报找不到或无法加载主类的问题,但是将相关文件全部放到src下进行编译就可运行,且在将包括class文件的整体移回Chapter1_base后也可运行,就很奇怪,希望以后能找到原因。
使用IDEA直接传参问题
想方便一点,直接用IDEA运行,但遇到了问题,传入相对路径
会在In的,判断文件是否存在这里出问题,导致后面报错
传入文件的绝对路径
会在进入while循环的时候,在StdIn文件里空转,不知道什么原因。
—————————————————————————————
更新,今天找到了解决方案,看了后续的一些程序发现
java J02BinarySearch tinyAllowlist.txt < tinyText.txt
代码中的 < 表示后面的tinyText.txt文件是整个程序的输入文件,不过猜测这是其大概意思,想找找对该符号的描述却没找到,不知道是java程序的命令参数还是命令行的参数。
然后在IDEA中发现可进行如下配置便能达到不使用命令行运行数据的目的,首先贴出我目前的结构:
为了看起来舒服,先将需要的文件整体放到resources文件夹下,然后对J02BinarySearch.java的运行参数进行配置。l两种进入配置页面的方法:
然后选中需要配置的java文件,进行配置给main传入的参数与输入文件
最后运行,可得到结果
不过这种方法在针对argeText.txt运行时,无法使用more进行查看,就在窗口直接全部输入了。