Skip to content

Certseeds/algorithm-template-java

algorithm-template-java

本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

Java 版本策略(重要)

  • 本地开发与测试: 推荐使用 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 仓库开始

快速上手(5 分钟)

  1. 使用 IDEA 打开仓库, 等待 Maven 依赖下载完成
  2. 打开 lab_welcome/lab_welcome_a/test/MainTest.java 直接运行测试
  3. 修改 lab_welcome/lab_welcome_a/src/Main.javacal 实现, 重新运行测试验证
  4. 提交到 OJ 时, 复制该题目的 Main.java 全文(包含嵌入的快读类)进行提交

命令行操作:

# 运行根项目所有测试
mvn -q test

# 仅运行某一题(例如 lab_welcome_a)的测试
mvn -q -pl lab_welcome/lab_welcome_a -am test

实际场景

A+B: lab_00_A , 测试样例

  • 这个问题较为简单, 见A+B 解决起来不复杂

  • 虽然手工一个一个输入, 然后肉眼观察输出.但是如果我们希望严谨的测试, 要100组测试数据, 难道每次出新版本都要手动输入100次?
    显然, 有更好的解决方式: 使用测试框架

  • 在本repo, 使用 Junit

比如, 我们有四组数据, 第一组, 第二组测试边界值, 第三组使用随机数测试对偶性与正确性, 第四组测试几个手动的随机值

参见test_for_lab00_A

  • 这样一来, 我们只需要每次修改完主文件之后, run lab_welcome_a/test/MainTest.java, 对其进行调用, 就能验证其在所有的测试用例上的正确性.
    测试的结果也会出现在输出中

文件输入输出重定向 part1

  • 常见于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/预置好, 只需要填写文件名

文本输入输出重定向 part2

  • 一般来说, 题目的输出不会太复杂, 但是反例也不是没有: 比如专门考输出的立体图

  • 这种情况下, 使用 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 中, 不能抽到外部文件依赖

实现细节

  1. 使用两层子模块来抽象 lab-question , 给每个 question 一个独立文件夹, 有利于在 README.md 里面撰写文档, 梳理思路
  2. 使用子模块来实现, 每一个类内不需要加入 package ...路径, 这样可以直接复制 Main.java 全文到 OJ内, 方便实现

为什么要将 读取 数据处理 输出 分开?

  • 便于理清思路, 读完题目之后, 不管别的, 先把数据读入, 输出的函数写好, 方便后续写作
  • 交流代码逻辑的时候不会受到无关逻辑的影响
  • 可以互相分享少量代码而不触及核心逻辑, 方便协作
  • 便于使用测试
  • 便于使用替换快读与scanner

为什么要选择Java做题

  1. SUSTech 大一默认用 Java 教学
  2. Java 对字符串处理有一些预置方法, 挺好用
  3. 可以在 Windows 环境下开发, 完全不需要安装 MSVC/gcc 环境
  4. 没了, 欢迎补充

为什么要选择C++做题

  1. C++是dalao们的选择: 直接去

等等dalao的解题页面看看, 会发现在排行榜榜首的人, 绝大多数题目使用的都是C++

  1. 速度
  • 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 生成数据

可能遇到的问题

  1. 提示找不到Jar包 请安装maven作为依赖管理的工具.然后在IDEA中文件-打开-选择algorithm-template-java\pom.xml-确定-作为项目打开

  2. maven下载包很慢 需要给maven 换源 (pom.xml中已有换源操作)

copyleft 选择

  1. 所有代码(*.java, etc) 基于AGPL-3.0-or-later协议: 限制最强的主流开源协议,

  2. 所有其他文件(主要是*.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

About

template for algorithm problem based on JDK21 and maven-submodel

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks