本repo的目的: 提供一个
- 开箱即用
- 带有测试
- LLM 友好
- 针对 OJ 需要单文件提交设计的
- 使用 JDK11 语法的
- 提供一些基本的算法框架
代码模板仓库, 供大家在 SUSTech 的各类算法课程中使用
为每一个题目分配独立的编译单元, 专有路径放置测试用例, 并提供重定向读写功能, 可以一键运行多组测试用例
下载最新 LTS 版本的 JDK, 推荐使用 JDK21
$ java -version
openjdk version "21" LTS
OpenJDK Runtime Environment Temurin-21 (build 21-LTS)
OpenJDK 64-Bit Server VM Temurin-21 (build 21-LTS, mixed mode, sharing)
或者在 IDEA 中下载
下载最新版本的 maven
$ mvn --version
Apache Maven 3.9.11
Maven home: ~\scoop\apps\maven\current
Java version: 21, vendor: Eclipse Adoptium, runtime: ~\scoop\apps\temurin21-jdk\current
Default locale: zh_CN, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"
或者使用 IDEA 捆绑的 maven
- 本地开发与测试: 推荐使用 JDK 21(IDEA 运行/调试更舒适)
- 构建与提交: 项目使用 Maven 以 Java 11 为编译目标(
--release 11
), 确保与远程 OJ(JDK 11)兼容 - 说明: 即使本地安装的是 JDK21, Maven 根据
release=11
仍会按照JDK11的API对源文件进行约束, 不用担心用了新的API, OJ上无法编译
- 首先请到release_latest下载
script_no_need.zip
- 将其解压, 放到您的代码库中
- 也可以直接使用 GitHub 的 "Use this template" 或 Fork 仓库开始
- 使用 IDEA 打开仓库, 等待 Maven 依赖下载完成
- 打开
lab_welcome/lab_welcome_a/test/MainTest.java
直接运行测试 - 修改
lab_welcome/lab_welcome_a/src/Main.java
的cal
实现, 重新运行测试验证 - 提交到 OJ 时, 复制该题目的
Main.java
全文(包含嵌入的快读类)进行提交
命令行操作:
# 运行根项目所有测试
mvn -q test
# 仅运行某一题(例如 lab_welcome_a)的测试
mvn -q -pl lab_welcome/lab_welcome_a -am test
-
这个问题较为简单, 见A+B 解决起来不复杂
-
虽然手工一个一个输入, 然后肉眼观察输出.但是如果我们希望严谨的测试, 要100组测试数据, 难道每次出新版本都要手动输入100次?
显然, 有更好的解决方式: 使用测试框架 -
在本repo, 使用
Junit
比如, 我们有四组数据, 第一组, 第二组测试边界值, 第三组使用随机数测试对偶性与正确性, 第四组测试几个手动的随机值
- 这样一来, 我们只需要每次修改完主文件之后, run
lab_welcome_a/test/MainTest.java
, 对其进行调用, 就能验证其在所有的测试用例上的正确性.
测试的结果也会出现在输出中
-
常见于tree, graph类的问题, debug需要的数据集都比较大, 不方便直接写在代码中
-
比如判断二分图, 一张图可以有几十上百个node, 写在内部占用空间太大
-
而在这里, 使用
Redirect
对象, 便可以省去手动输入的方式try (Redirect redirect = Redirect.from(DATA_PATH, "01.data.in", "01.test.out");) {// 设定目录 DATA_PATH在文件里有定义 Main.output(Main.cal(Main.read())); // 执行 final Pair<String, String> p = redirect.compare_double("01.data.out", "01.test.out"); // 获取两个文件中的字符串 assertEquals(p.getFirst().length(), p.getSecond().length()); // 比较长度 assertEquals(p.getFirst(), p.getSecond()); // 比较文本 }
只需要准备好输入的数据与结果, 就可以从文件中读取, 执行后判断结果是否符合预期
- test_1 为最简单的逐个判断, 最简单, 代码量最大
- test_2 则优化了一些, 但是还是比较麻烦, for循环还需要了解测试样例的个数
- test_3 with tuple 则最优雅, 修改起来的难度最小
- PS: 此处注意, 引用文件的相对路径
- PS2: 模版文件中已经将前面
resources/
预置好, 只需要填写文件名
-
一般来说, 题目的输出不会太复杂, 但是反例也不是没有: 比如专门考输出的立体图
-
这种情况下, 使用 Java 的标准输入/输出重定向就可以较为方便地处理输入, 同时保存输出便于调试
try (Redirect redirect = Redirect.from(DATA_PATH, "01.data.in", "01.test.out");) {// 设定目录 DATA_PATH在文件里有定义 Main.main(init_String); final Pair<String, String> p = redirect.compare_double("01.data.out", "01.test.out"); assertEquals(p.getFirst().length(), p.getSecond().length()); assertEquals(p.getFirst(), p.getSecond()); }
这样就将标准输出重定向到了
01.test.out
中, 并与01.data.out
比对- 这里需要考虑的是, 谨慎使用
println()
, 因为println()
的输出与平台有关; 推荐使用System.out.print('\n')
来对齐与 data.out 的比较
- 这里需要考虑的是, 谨慎使用
- 一般来说, 题目不会卡读入
- 但是, 当数据量上来之后, 读取时间不容小看
- 所以可以使用每个文件中自带的 Reader / FastReader 类来进行快读
- 注意: 多数 OJ 仅允许单文件提交, 因此快读类需嵌入到
Main.java
中, 不能抽到外部文件依赖
- 使用两层子模块来抽象 lab-question , 给每个 question 一个独立文件夹, 有利于在 README.md 里面撰写文档, 梳理思路
- 使用子模块来实现, 每一个类内不需要加入
package ...
路径, 这样可以直接复制 Main.java 全文到 OJ内, 方便实现
- 便于理清思路, 读完题目之后, 不管别的, 先把数据读入, 输出的函数写好, 方便后续写作
- 交流代码逻辑的时候不会受到无关逻辑的影响
- 可以互相分享少量代码而不触及核心逻辑, 方便协作
- 便于使用测试
- 便于使用替换快读与scanner
- SUSTech 大一默认用 Java 教学
- Java 对字符串处理有一些预置方法, 挺好用
- 可以在 Windows 环境下开发, 完全不需要安装 MSVC/gcc 环境
- 没了, 欢迎补充
- C++是dalao们的选择: 直接去
等等dalao的解题页面看看, 会发现在排行榜榜首的人, 绝大多数题目使用的都是C++
- 速度
- OJ 内一般 Java 的最大运行时间都会是 C++ 的 2 倍, 显然是暗示速度之间的差别
- 其次, C++可以通过一些优化技巧, 比如下文的优化等操作再获取一些时间上的优势
DSAA既然内含Data structure, 就势必涉及到类似Node, Tree, Graph等等数据结构, 这类数据结构使用C++写, 比较方便理解
作者写树和图相关的题目时, 最头疼的就是Java的爆栈, 有一段时间只要用递归就爆栈, 相同算法修改为C++之后问题就消失了
不管怎么说, C++是 dalao 的选择, 所以在网络上搜索题目, 得到的大多数答案都是 C/C++, Java 的数量很少
C++的CS203库:CS203_DSAA_template
TODO: 介绍使用 Cyaron 生成数据
-
提示找不到Jar包 请安装maven作为依赖管理的工具.然后在IDEA中
文件
-打开
-选择algorithm-template-java\pom.xml
-确定-作为项目打开 -
maven下载包很慢 需要给maven 换源 (
pom.xml
中已有换源操作)
-
所有代码(*.java, etc) 基于AGPL-3.0-or-later协议: 限制最强的主流开源协议,
- 从设计上只为了源码交付
- 具体内容请看
LICENSE_AGPL-3.0-or-later.md
-
所有其他文件(主要是*.md)基于CC-BY-NC-SA-4.0(或以后版本)协议
- 相同方式共享-署名-非商业性使用的知识共享协议4.0或任何以后版本
- 署名(BY)-使用到相应内容的其他地方, 应该加以注释, 保留来源
- 非商业性使用(NC)-默认情况下, 只要署名, 可以在不盈利的情况下使用.(并不是指商业情况不能用, 而是需要和原作者沟通)
- 相同方式共享(SA)-使得协议具有传染性, 只要其他内容采用了本repo的内容, 就需要在署名的同时, 保证其协议也是CC-BY-NC-SA-4.0 or later version
- 具体内容请看
LICENSE_CC_BY_NC_SA_V4_0.md