Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
cmake_minimum_required(VERSION 3.16.6)

set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 16)
set(PROJECT_VERSION_PATCH 1) # delete endsWith strs when master merge dev
set(PROJECT_VERSION_MAJOR 2026)
set(PROJECT_VERSION_MINOR 09)
set(PROJECT_VERSION_PATCH 19)

project(algorithm_template
VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
DESCRIPTION "Template for Algorithm Based on C++11 and Modern CMake"
HOMEPAGE_URL "https://github.com/Certseeds/algorithm-template"
LANGUAGES CXX)
Expand Down
155 changes: 113 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
<br />
<div align="center">

<h3 align="center">CS203-DSAA-template</h3>
<h3 align="center">Algorithm-Template</h3>

<p align="center">
An awesome Algorithm Template for IO-Driven Single-File Problem(like Online-Judge Problem) ! </br>
分布式<sup title="由git保证">1</sup> 去中心化<sup title="推荐使用template生成仓库, 不设置主库;没有易受打击的web页">2</sup> 的IO驱动型单文件问题<sup title="包括但不限于OJ平台题目">4</sup>解题模板
分布式<sup title="由git保证">1</sup> 去中心化<sup title="推荐使用template生成仓库, 不设置主库;没有易受打击的web页">2</sup> 的IO驱动型单文件问题<sup title="包括但不限于OJ平台题目">3</sup>解题模板
<br />
<a href="https://github.com/Certseeds/algorithm-template/blob/dev/README.md"><strong>Explore the docs »</strong></a>
<a href="https://github.com/Certseeds/algorithm-template/blob/master/README.md"><strong>Explore the docs »</strong></a>
<br />
<br />
<a href="https://github.com/Certseeds/algorithm-template/tree/release">View Demo</a>
Expand All @@ -44,29 +44,41 @@
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#project-structure">Project Structure</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li>
<a href="#usage">Usage</a>
<ul>
<li><a href="#command-line-build">Command Line Build</a></li>
</ul>
</li>
<li><a href="#test-introduce">Test Introduce</a></li>
<li><a href="#details">Details</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#thanks">Thanks</a></li>
</ol>
</details>

## About The Project

OJ系统存在着一些特殊要求-因此考虑到下面的因素, 设计了一套代码模板, 以适应OJ系统的独特环境.
OJ系统存在着一些特殊要求, 因此考虑到下面的因素, 设计了一套代码模板, 以适应OJ系统的独特环境.

+ 上交题目无需修改类名, 方法名等等内容, 只需复制粘贴.
+ 支持为每个问题撰写测试用例, 并支持用户之间方便的交换测试用例
+ 只依赖于Unix-Like系统, 支持C++20的编译器与仓库本身, 没有依赖包
+ 易于拓展, 提供基本算法接口与实现
+ 支持为每个问题撰写测试用例, 并支持用户之间方便的交换测试用例.
+ 只依赖 Unix-Like 系统与一个支持 C++20 的编译器, 外部依赖仅有 Google Test.
+ 易于拓展, 提供基本算法接口与实现.

### Built With

[![Google Test][gtest_image]](https://github.com/google/googletest)
+ 语言: [C++](https://isocpp.org/) — 提交用源码按 C++11 编译, 测试按 C++20 编译, 因此需要支持 C++20 的编译器.
+ 构建: [CMake](https://cmake.org/) (>= 3.16.6) 与 [ccache](https://ccache.dev/).
+ 测试: [Google Test](https://github.com/google/googletest) / [Google Mock](https://github.com/google/googletest).
+ 可选: [Podman](https://podman.io/) 容器开发环境, 见 [script/container.sh](./script/container.sh).

<p align="right">(<a href="#top">back to top</a>)</p>

Expand All @@ -84,11 +96,9 @@ OJ系统存在着一些特殊要求-因此考虑到下面的因素, 设计了一

### Prerequisites

This is an example of how to list things you need to use the software and how to install them.

#### Windows
#### 环境准备

推荐使用 windows subsystem linux 2, 换好apt源之后只需要
推荐使用 windows subsystem linux 2 Ubuntu-26.04, 换好 apt 源之后只需要

``` bash
yes | sudo apt-get update
Expand Down Expand Up @@ -133,19 +143,62 @@ git clone https://github.com/${YOUE_GITHUB_USER_NAME}/algorithm-template.git
使用命令行, 进入`./script`下, 编辑`file_template`的`labs` & `problem_orders`,
`python3 ./file_template.py`, 出现`produce files finish`提示, 即为创建成功.

### Project Structure

``` text
.
├── CMakeLists.txt # 顶层构建入口, 自动发现 lab_* 目录
├── cmake/ # 构建配置: 编译类型 / 跨平台 / 并行 / ccache / policy
├── include/ # 公共头文件, 以 Interface Library 提供给各题目
│ ├── gtest_main.hpp # 测试入口, 引入 gtest/gmock 与 public.hpp
│ ├── include/ # CS203_redirect / CS203_sequence / CS203_timer 等工具
│ ├── class_helper/ # nonable 等基类
│ ├── list/ tree/ # 链表 / 树 / Trie 等数据结构
│ └── magic_macro/ # 手动开优化用的宏
├── lab_00/ # 一个 lab, 内含若干题目
│ ├── CMakeLists.txt # 声明本 lab 下的题目列表
│ └── A/ # 一道题目
│ ├── main.cpp # 将要提交的源文件, 含 read()/处理函数/output()
│ └── test.cpp # Google Test 测试
├── script/ # 模板生成 / 一键构建 / 容器脚本
└── .github/workflows/ # CI(提交触发) 与 CD(Tag 触发 Release)
```

+ `include/` 通过 CMake Interface Library 暴露, 各题目用 `target_link_libraries` 链接.
+ `lab_*/` 由顶层 CMake 用 `file(GLOB ...)` 自动发现, 新增 lab 后重新 configure 即可.

<p align="right">(<a href="#top">back to top</a>)</p>

## Usage: 执行代码和测试
## Usage

执行代码和测试:

使用clion打开文件夹, 配置好C++环境的基础上, 会自动识别`CmakeList.txt`.
### 在 CLion 中

产生`CS203_lab${order}_${ques_Order}`, `CS203_lab${order}_${ques_Order}_test` 形式的复数个可以运行的可选项.
使用 CLion 打开文件夹, 配置好 C++ 环境后会自动识别 `CMakeLists.txt`, 并生成若干可运行项:

`lab${order}_${ques_Order}`为对应题号, 比如`lab07_01`对应lab_07的C1题.
+ `ALGORITHM_lab_00_A`: 调用 `lab_00/A/main.cpp`, 即将要提交的源文件.
+ `ALGORITHM_lab_00_A_test`: 调用 `lab_00/A/test.cpp`, 对其进行测试.

可运行项命名规则为 `ALGORITHM_lab_{lab 编号}_{题号}`, 其中 lab 编号为两位数字、题号为字母, 例如 `ALGORITHM_lab_00_A` 对应 `lab_00` 的 A 题.

### Command Line Build

仓库提供 [`script/test.sh`](./script/test.sh), 在仓库根目录执行即可完成配置、编译与 `ctest`.

``` bash
bash script/test.sh
```

脚本会在临时目录中基于 CMake 构建并运行全部测试, 结束后自动清理. 也可手动执行:

``` bash
cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug
cmake --build cmake-build-debug --parallel "$(nproc)"
cd cmake-build-debug && ctest --output-on-failure
```

+ `CS203_lab07_01`将调用`lab_07\lab_07_C1\main.cpp`, 为将要提交的源文件.
+ `CS203_lab07_01_test`将调用`lab_07\lab_07_C1\test.cpp`, 对其进行测试.
+ `lab_*\lab_*_*\test.cpp`目的为方便测试, 同时便于分享测试用例.
> 若需要在容器内开发, 可使用 [`script/container.sh`](./script/container.sh) 启动预配置好的镜像.

<p align="right">(<a href="#top">back to top</a>)</p>

Expand All @@ -158,6 +211,30 @@ git clone https://github.com/${YOUE_GITHUB_USER_NAME}/algorithm-template.git
3. 可以互相分享少量代码而不触及核心逻辑, 方便协作.
4. 便于使用测试.

### 约定: `read()` / 处理函数 / `output()`

每道题的 `main.cpp` 按同一套签名组织, 使读取、处理、输出彼此独立:

``` cpp
using input_type = ...; // 输入数据的类型
using output_type = ...; // 输出数据的类型

input_type read(); // 从 cin 读入
output_type solve(const input_type &); // 处理函数, 名称随题目而定
void output(const output_type &); // 写到 cout

int main() {
const auto input_data = read();
const auto output_data = solve(input_data);
output(output_data);
return 0;
}
```

+ 处理函数名随题目而定 (如 `isBipartite`), 但签名约定一致, 便于测试直接调用.
+ `test.cpp` 通过 `#include "main.cpp"` 复用这些函数, 并用 `CS203_redirect` 重定向 IO.
+ 每个 `test.cpp` 需实现 `getFilePath()` 并据此定义 `CS203_redirect::file_paths`, 详见下文重定向部分.

### 基本测试用例展示 A+B: lab_00_A , 测试样例

+ 这个问题较为简单, 见[A+B](./lab_00/A/main.cpp) 解决起来不复杂.
Expand All @@ -168,7 +245,7 @@ git clone https://github.com/${YOUE_GITHUB_USER_NAME}/algorithm-template.git
+ 在本repo, 使用 `Google Test` 测试框架.
+ 比如, 我们有四组数据, 第一组, 第二组测试边界值, 第三组使用随机数测试对偶性与正确性, 第四组测试几个手动的随机值.
+ 参见[test_for_lab00_A](./lab_00/A/test.cpp)
+ 这样一来, 我们只需要每次修改完主文件之后, run `algorithm-template_test`, 对其进行调用, 就能验证其在所有的测试用例上的正确性.
+ 这样一来, 我们只需要每次修改完主文件之后, run `ALGORITHM_lab_00_A_test`, 对其进行调用, 就能验证其在所有的测试用例上的正确性.

### 多个输出值的检查: `EXPECT_EQ`

Expand Down Expand Up @@ -206,11 +283,16 @@ TEST(lab_00_C, test_case_1) {
+ test case with tuple 则最优雅, 修改起来的难度最小.
+ test case with sequence 比tuple更优雅, 输入, 输出全为自动产生.

PS: 此处注意, 引用文件的相对路径, 不是直接的`test/lab_00/C/resource/01.data.in`,
PS: 此处注意, `01.data.in` 这类路径是相对于**编译产物所在目录**解析的, 而非相对于 `test.cpp`.

每个 `test.cpp` 中的 `getFilePath()` 返回资源目录相对编译产物目录的路径, 例如 [lab_00/C/test.cpp](./lab_00/C/test.cpp):

而是编译出的文件相对于测试数据的相对路径.
``` cpp
std::string getFilePath() noexcept { return "./../../../lab_00/C/resource/"; }
const std::string CS203_redirect::file_paths = getFilePath();
```

在样例中, 编译出的文件在`algorithm-template/cmake-build-debug`下, 所以需要加`./../`
以 `cmake-build-debug` 为例, 测试产物位于 `cmake-build-debug/lab_00/C/` 下, 因此需要 `./../../../` 回到仓库根目录, 再拼接 `lab_00/C/resource/`. 换用其它构建目录时, 相对层级可能不同, 需相应调整 `getFilePath()`.

### 输入输出重定向-Stage 2: 从文件中读取输入, 将输出定向到文件中

Expand Down Expand Up @@ -238,30 +320,20 @@ PS: 至于比较文件之间的差异, 可以使用内置的`compareFiles(string

### 为什么要选择C++做题?

1. C++是dalao们的选择
直接去
[dalao1](https://acm.sustech.edu.cn/onlinejudge/status.php?user_id=11710724&jresult=4)
[dalao2](https://acm.sustech.edu.cn/onlinejudge/status.php?user_id=11612908&jresult=4)
[dalao3](https://acm.sustech.edu.cn/onlinejudge/status.php?user_id=11712510&jresult=4)
等等dalao的解题页面看看, 会发现在排行榜榜首的人, 绝大多数题目使用的都是C++.

1. C++ 参考用例更多, 相关资源更丰富
2. 速度.

+ oj内一般java的最大运行时间都会是c++的2倍, 显然是暗示速度之间的差别.
+ 其次, C++可以通过一些魔法操作, 比如下文的优化等操作再获取一些时间上的优势.

3. 对数据结构的友好性

DSAA既然内含Data structure, 就势必涉及到类似Node, Tree, Graph等等数据结构, 这类数据结构使用C++写, 比较方便理解.
涉及到类似Node, Tree, Graph等等数据结构, 这类数据结构使用C++写, 比较方便理解.

4. 对算法友好的性能:

之前写树和图相关的题目时, 最头疼的就是Java的爆栈, 有一段时间只要用递归就爆栈, 相同算法修改为C++之后问题就消失了.

5. 相关资源的丰富程度

不管怎么说, c++是dalao的选择, 所以在网络上搜索题目, 得到的大多数答案都是C/C++, java的数量很少.

### 如何手动开优化

1. 将[magic_optimize](./include/magic_macro/magic_macro.hpp)内的内容粘贴到代码最上方.
Expand All @@ -281,7 +353,7 @@ static const auto faster_streams = [] {
}();
```

已放置在源文件最下方, 注意**不要混用**C风格输入输出(`scanf`, `printf`)与c++风格输入输出(`cin`, `cout`)
关闭同步的代码已放在每道题 `main.cpp` 的最下方, 注意**不要混用**C风格输入输出(`scanf`, `printf`)与c++风格输入输出(`cin`, `cout`)

通常情况下, 可以将运行时间缩短到1/2甚至更少.

Expand All @@ -303,11 +375,9 @@ yes | sudo apt-get install libgtest-dev libgmock-dev
+ [x] CI-CD
+ [x] CI: GitHub-Actions提交触发
+ [x] CD: Tag触发的自动Release
+ [x] ~~leetcode题目~~
+ [x] ~~预编译头文件~~ccache加速编译
+ [x] ~~basic文件夹添加CS205内容, 方便入门C++~~
+ [x] ~~以及一部分rust代码~~
+ [ ] ~~Cyaron测试数据生成~~
+ [x] 某一学期的完整题目 (见 [2021fall 分支](https://github.com/Certseeds/algorithm-template/tree/2021fall))
+ [x] ccache 加速编译
+ [ ] ~~Cyaron 测试数据生成~~
+ [ ] ~~WiKi Page~~

<p align="right">(<a href="#top">back to top</a>)</p>
Expand Down Expand Up @@ -339,6 +409,7 @@ Don't forget to give the project a star! Thanks again!

+ 由于本仓库设计只包括"上交"源码这一种场景, 因此实际上不存在二进制分发以及被云服务使用这种场景.
+ 具体内容请看[`LICENSE_AGPL_V3_0.md`](./LICENSE_AGPL_V3_0.md)

some code is based on this license

### CC-BY-NC-SA-4.0+ LICENSE
Expand Down
Loading