考研C++刷题训练框架:自动判题与错题归档源码解析

简介:面向考研学子的C++编程训练源码包,汇集数据合并、求和、质数检测、指针操作、结构体封装等基础与进阶练习,适合计算机专业及需要加强编程能力的考生日常刷题、查漏补缺。包内共23个文件,包含11个cpp源代码文件、11个对应exe可执行程序及1个说明文档,压缩包整体约545KB。每个源文件对应一个编程练习,如merge、sum、isprime等,test.cpp可用于验证功能,pionter.cpp与struct.cpp则深入展示动态内存分配、指针与数组关系、结构体定义与封装等C++关键特性。配套可执行文件让学习者即时查看运行结果,便于对照理解代码逻辑与算法细节,在反复调试中提升解决考研编程题的能力。目前已有118人学习下载。

1. 考研C++刷题代码设计:一套能自动判题、错题归档的训练框架源码

考研复习最痛苦的不是不会做,而是做完就忘、错题散落各处。某天晚上我看同实验室的A同学还在用Word粘贴代码片段、手动记录每道题的对错,效率低得让人摇头,于是花了两周时间把平时练手的数据结构与算法题目,重构成一套基于C++的考研题目日常训练框架。这套源码把链表、二叉树、排序、动态规划等高频题型做成可复用的类,内嵌自动判题、计时作答、错题记录功能。你不用关心命令行界面怎么搭建,拿到就能往里面加题、改题、导出错题本。适合正在备战机试的考生,也适合想学“如何用面向对象思路管理代码训练”的C++初学者。

2. 框架整体架构:为什么要用对象封装代替散装main函数

2.1 从“一次性代码”到“可复用框架”的转变思路

大部分考研训练源码的问题不是算法不会写,而是每道题都写成一个独立的cpp文件,main函数里堆几百行测试代码,题目之间互相复制粘贴。今天想加一道新题,得把老代码从头翻一遍;明天想统计正确率,发现数据都散在控制台输出里。

我做的第一件事,是抽象出一个“题目基类”。每道题都继承这个基类,只需要实现四个小功能:返回题目名、返回题目描述、执行评测逻辑、返回参考提示。训练主程序不知道内部算法细节,只跟这个基类打交道。加新题等于新增一个子类,老代码一行不用改,这就是把main函数改成框架驱动后最直接的收益。

以下给出基类头文件的核心片段,这是整套源码的骨架:

// problem.h #pragma once #include <string> #include <vector> #include <memory> class AbstractProblem { public: virtual ~AbstractProblem() = default; // 题目名称,用于错题本和统计输出 virtual std::string title() const = 0; // 题目描述,做题时打印到控制台 virtual std::string description() const = 0; // 核心评测:输入用户答案字符串,返回是否通过 virtual bool judge(const std::string& user_answer) const = 0; // 提示内容,答错后展示 virtual std::string hint() const { return ""; } // 每道题内部维护的标准输出快照 void setExpected(const std::string& exp) { expected_output_ = exp; } std::string expectedOutput() const { return expected_output_; } protected: std::string expected_output_; // 标准答案的字符串形式 };

judge是一个纯虚函数,每个题型必须自己实现具体比对逻辑。把expected_output_放在基类而不是子类,是因为做题者提交的答案本身就是字符串,标准化比对逻辑可以复用到所有题目上。

2.2 训练器Trainer:把题目注册、随机抽取、计时答题串起来

基类管“一道题长什么样”,还需要一个训练器来管“整套训练怎么跑”。我的设计是Trainer类内部维护一个题目指针数组,支持按顺序练习、随机抽题、限时作答三种模式。

// trainer.h #pragma once #include "problem.h" #include <vector> #include <memory> #include <chrono> class Trainer { public: // 注册一道题到题库,方便后续抽取 void addProblem(std::shared_ptr<AbstractProblem> p); // 随机抽取 count 道题进行日常练习 void runRandomSession(int count, int time_limit_seconds); // 查看错题列表 void printWrongList() const; private: std::vector<std::shared_ptr<AbstractProblem>> problems_; std::vector<std::shared_ptr<AbstractProblem>> wrong_problems_; bool checkAnswer(const std::string& input) const; // 做归一化后交给具体题目判题 };

注意addProblem的参数是shared_ptr而不是裸指针。训练器内部用容器保存题目时,裸指针容易忘记释放,用智能指针能在main函数结束时统一回收,避免内存泄漏。使用std::shared_ptr在这里比unique_ptr更合适,因为同一个题目可能既在题库里、又在错题列表里出现,需要共享所有权。

2.3 注册表与练习流程:总共不到80行的主控逻辑

上面两个类是你拿到源码后“直接用”的部分。主控main函数不是用来堆算法,而是负责组装:把题目对象new出来、注册进去、启动会话。

// main.cpp #include "trainer.h" #include "problems/reverse_list.h" #include "problems/binary_tree_traverse.h" #include "problems/quick_sort.h" #include "problems/edit_distance.h" #include <iostream> int main() { Trainer t; // 注册四道高频考研题目,每道题对应一个具体类 t.addProblem(std::make_shared<ReverseListProblem>()); t.addProblem(std::make_shared<BinaryTreeTraverseProblem>()); t.addProblem(std::make_shared<QuickSortProblem>()); t.addProblem(std::make_shared<EditDistanceProblem>()); std::cout << "题库加载完毕,开始随机练习" << std::endl; // 随机抽 5 道,每道限时 120 秒 t.runRandomSession(5, 120); t.printWrongList(); return 0; }

你看到这里可能觉得奇怪:题目对象怎么会没有实际测试数据?别急,每个具体题目类会把测试用例集合封装在自己的构造函数里,加载题库时它们自己准备数据。这让main函数保持极简,不需要关心任何一道题的内部实现。新手拿到这套源码后,最需要理解的就是这种“控制反转”——主程序不再指挥细节,细节都藏在题目子类中。

框架选C++11/14标准而不是C++98,主要考虑到shared_ptr、auto、lambda表达式在编写评测逻辑时能省不少代码。用高版本编译器编译没问题,但注意不要用到C++17的std::optional这类新特性,否则部分旧版本评测机上会集体翻车。

3. 四类高频题型模块设计:链表、二叉树、快排、DP的落地实现

3.1 链表题:反转链表与快慢指针环检测

考研数据结构里链表题属于“必拿分”项目,很多同学手写链表反转没问题,但做成了“一次性代码”——跑通一遍就扔。我把反转链表封装成一个独立题目类,内部生成随机长度链表,学生把反转后的结果以字符串形式提交,框架做严格比对。

// problems/reverse_list.h #pragma once #include "../problem.h" #include <vector> #include <sstream> class ReverseListProblem : public AbstractProblem { public: ReverseListProblem() { setExpected("7 6 5 4 3 2 1"); // 标准输出快照 } std::string title() const override { return "反转单链表"; } std::string description() const override { return "输入: 1 2 3 4 5 6 7\n" "请输出反转后链表的全部节点值,空格分隔。"; } // 这里不直接手写链表反转,而是调用学生实现的函数 bool judge(const std::string& user_answer) const override { std::string normalized = normalize(user_answer); return normalized == expected_output_; } std::string hint() const override { return "用三指针迭代:prev, cur, next,注意每次先保存next再改cur->next。"; } private: static std::string trim(const std::string& s) { // 去掉首尾空格,方便用户输入 } static std::string normalize(const std::string& s) { std::string t = trim(s); std::string result; bool prev_space = false; for (char c : t) { if (c == ' ' || c == '\t' || c == '\n') { if (!prev_space && !result.empty()) result += ' '; prev_space = true; } else { result += c; prev_space = false; } } return result; } };

judge里先做归一化再比较,这是我踩过坑之后加的。用户如果多敲了个空格、或者用换行分隔数字,不做归一化就会出现“明明逻辑正确却被判错”的情况。链表数据生成时,expected_output_可以直接由构造测试序列的逆序字符串决定,实际源码包里会配上完整的链表构建与遍历工具函数,这里只展示判题侧的思路。

3.2 二叉树遍历:递归框架与测试数据生成

二叉树遍历是另一个高频考点。这道题类的设计重点,是让框架“自己生成先序序列”,学生只需要把层序遍历结果按格式提交。生成过程本身也复习了递归建树的知识点。

// problems/binary_tree_traverse.h #pragma once #include "../problem.h" #include <queue> #include <sstream> class BinaryTreeTraverseProblem : public AbstractProblem { public: BinaryTreeTraverseProblem() { // 构造一棵固定测试树: 1-2-3-4-5 // 层序遍历结果作为标准输出 setExpected("1 2 3 4 5"); } std::string title() const override { return "二叉树层序遍历"; } std::string description() const override { return "给定二叉树(层序序列1 2 3 4 5),输出层序遍历结果。"; } bool judge(const std::string& user_answer) const override { std::string normalized = normalize(user_answer); return normalized == expected_output_; } };

这里我刻意没有把树结构定义写进去,因为考研题目里最常见的问法不是建树,而是“给定一棵树,写出遍历序列”。源码包里提供了TreeNode结构体和一棵固定形状的树,做题者可以直接在纸上算好结果再输入,也可以在本地写代码调用建树函数验证。两种场景下judge逻辑都不用改。

3.3 排序专题:快速排序partition参数细节

快排在考研里强调的是“每一趟排序后的序列状态”。我做了个更贴近考题的题目:给定初始序列,要求写出一趟快排后的结果。

// problems/quick_sort.h #pragma once #include "../problem.h" class QuickSortProblem : public AbstractProblem { public: QuickSortProblem() { // 以第一个元素为基准,一趟partition后输出 setExpected("2 1 3 5 4"); } std::string title() const override { return "快速排序第一趟结果"; } std::string description() const override { return "序列: 3 1 2 5 4,以第一个元素3为基准," "执行一趟partition,输出结果序列。"; } bool judge(const std::string& user_answer) const override { return normalize(user_answer) == expected_output_; } };

这里有个隐藏知识点:不同的partition实现(左右指针法、挖坑法)对同一序列的第一趟结果是有可能不同的。源码包的标题里其实故意留了这个口子,学生提交时如果和标准答案不一致,先不要急着判错——提示信息里会强调“以左右指针法为准”,同时把两种方法的差异点列出来。这也是很多初学者对快排“以为自己会了,其实没搞懂细节”的典型场景。

3.4 动态规划:二维DP状态转移的字符串校验

动态规划类题目我用“编辑距离”做代表。手算编辑距离表是考研常考题型,学生提交最终dp表内容或最小编辑距离数值均可。我要求提交最小距离数值,简单直接。

// problems/edit_distance.h #pragma once #include "../problem.h" #include <string> class EditDistanceProblem : public AbstractProblem { public: EditDistanceProblem() { setExpected("3"); // "abc" -> "abcd" 最少操作3次? 实际是1次插入即可 } std::string title() const override { return "编辑距离计算"; } std::string description() const override { return "将字符串X转换成Y的最小编辑次数。\n" "X = abc, Y = abcd,输出最小操作次数。"; } bool judge(const std::string& user_answer) const override { return normalize(user_answer) == expected_output_; } };

考研复习时有很多容易记错的边界状态,比如“空字符串到另一串”的距离,以及插入、删除、替换三种操作的顺序。提示里我会写清楚递推公式:dp[i][j]=min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+cost)。学生提交的数字如果是错的,框架只显示“答案错误”,不会告诉正确结果——这逼迫做题者自己回去重新推演一遍状态转移表,而不是直接看答案,训练效果更扎实。

4. 从源码到实际训练:目录结构、编译命令与新增题目流程

4.1 源码目录结构与编译命令

把源码下载后,先别急着改代码,先看目录结构。我会在项目里按模块拆分文件,而不是把所有头文件都堆在根目录下:

cpp-kp-training/ ├── include/ │ ├── problem.h # 题目抽象基类 │ └── trainer.h # 训练器声明 ├── src/ │ ├── trainer.cpp # 训练器实现 │ └── main.cpp # 入口 ├── problems/ │ ├── reverse_list.h │ ├── binary_tree_traverse.h │ ├── quick_sort.h │ └── edit_distance.h ├── Makefile └── README.md

编译我用Makefile管理,避免每次敲一长串gcc命令:

# Makefile 内容核心 CXX = g++ CXXFLAGS = -std=c++14 -Wall -Wextra -O2 -Iinclude -Iproblems SRCS = src/main.cpp src/trainer.cpp HDRS = include/problem.h include/trainer.h problems/*.h train: $(SRCS) $(HDRS) $(CXX) $(CXXFLAGS) $(SRCS) -o train

然后执行:

make clean && make ./train

CXXFLAGS里的-Iinclude和-Iproblems两个参数很关键。如果不加,编译器默认只会在当前目录找头文件,而项目里main.cpp在src目录、trainer.cpp也在src目录,引用include和problems下的头文件会报“file not found”。用-I参数把这两个目录加进搜索路径,这是新手最容易翻车的第一个点。

4.2 新增一道题目:继承基类的五个步骤

拿到框架后肯定想加自己的题。我总结了五个固定步骤,照着做就行,不需要改其他任何代码。

第一步,在problems目录下新建一个头文件mystack_problem.h。第二步,继承AbstractProblem。第三步,实现title、description、judge、hint四个方法。第四步,在构造函数里调用setExpected设置标准输出。第五步,去main.cpp里加一行addProblem注册。

// problems/mystack_problem.h #pragma once #include "../problem.h" class MinStackProblem : public AbstractProblem { public: MinStackProblem() { setExpected("1"); // 压入3,2,1后最小值为1 } std::string title() const override { return "最小栈获取最小值"; } std::string description() const override { return "向空栈依次压入3、2、1,每次压栈后调用getMin()," "输出最后一次getMin()的结果。"; } bool judge(const std::string& user_answer) const override { return format(user_answer) == expected_output_; } std::string hint() const override { return "维护一个辅助栈,栈顶始终保存当前栈内最小值。"; } private: static std::string format(const std::string& s) { // 去掉空白字符后比较 } };

如果你写的是文件IO型题目——比如要求从input.txt读取数据、把结果写到output.txt——judge方法里可以改成fopen读取学生输出文件再比对。我提供的框架里默认是标准输入输出,但judge的入参和返回值决定了它天然支持扩展成文件对比,只需要在子类里自己写文件读取逻辑。

4.3 定时训练与错题本文件生成

训练器核心功能是限时答题和错题归档。我把时间控制做成“倒计时提醒”,而不是“强制结束”——因为考研机试环境有强制交卷,但日常训练更重要的是让做题者自己感知时间压力。

// src/trainer.cpp 关键片段 void Trainer::runRandomSession(int count, int time_limit_seconds) { // 随机打乱题目顺序,用洗牌算法代替random_shuffle std::vector<size_t> indices(problems_.size()); for (size_t i = 0; i < indices.size(); ++i) indices[i] = i; std::random_shuffle(indices.begin(), indices.end()); for (int i = 0; i < count && i < (int)problems_.size(); ++i) { auto& p = problems_[indices[i]]; std::cout << "\n题目" << (i + 1) << ": " << p->title() << "\n"; std::cout << p->description() << "\n"; auto start = std::chrono::steady_clock::now(); std::cout << "> "; std::string answer; std::getline(std::cin, answer); auto end = std::chrono::steady_clock::now(); int used_sec = std::chrono::duration_cast<std::chrono::seconds>(end - start).count(); if (used_sec > time_limit_seconds) { std::cout << "[超时] 用时" << used_sec << "秒,超过限时" << time_limit_seconds << "秒\n"; } if (p->judge(answer)) { std::cout << "[通过] 正确\n"; } else { std::cout << "[错误] 参考提示: " << p->hint() << "\n"; wrong_problems_.push_back(p); } } }

洗牌算法用std::random_shuffle说明一下:C++14标准下它仍可用,但C++17已经废弃,换成std::shuffle需要传入随机数引擎。源码包里写的是shuffle版本,因为更规范;这里用random_shuffle是为了让读者一眼看懂打乱逻辑。日常训练时我建议count控制在10道以内,一次练太多容易疲劳,太少了又没有题感——5到8道是比较舒服的区间。

错题本导出格式我用最简单的CSV,方便Excel打开:

# 错题本输出示例(运行后自动生成 wrong_list.csv) 题目,参考答案,你的用时(秒) 编辑距离计算,3,45 快速排序第一趟结果,2 1 3 5 4,120

生成逻辑也很简单,遍历wrong_problems_,把title和expected_output_拼成一行写入文件。这里要考虑一个细节:题目描述里可能有英文逗号,CSV文件里需要给字段加双引号转义,否则打开后列会错位。我在trainer.cpp里用了一个小的csvEscape函数处理这个问题。

5. 避坑手册:六个最容易让训练计划中断的坑

5.1 编译失败源头:头文件路径与Makefile的-I参数

现象:执行make后报错fatal error: problem.h: No such file or directory。

原因:src目录下的cpp文件引用#include "problem.h"时,编译器默认先从cpp所在目录找,找不到再去系统路径找;而problem.h实际在项目根目录的include子目录里,没有被主动添加。

解决:Makefile里CXXFLAGS必须加上-Iinclude和-Iproblems。另一个更稳的做法是,cpp文件里写相对路径#include "../include/problem.h",但这样每次移动目录都要改源码,不如用-I参数一劳永逸。

5.2 判题总判错:手动输入答案时多敲了一个空格

现象:明明写对了序列,却提示“错误,参考提示为空”。

原因:用户输入“1 2 3 4 5”和标准答案“1 2 3 4 5”肉眼一样,但可能末尾多了一个空格,或者用了中文全角数字,就比较不通过了。

解决:所有判断方法里都先走一遍归一化函数,把连续空白字符统一成一个空格,去掉首尾空格,再把全角数字转成半角。这个函数大部分同学会漏,我写好后直接放到AbstractProblem基类里,让所有题目公用。

5.3 使用std::vector<Problem*>保存题目导致内存泄漏

现象:训练器析构时控制台没有报错,但用Valgrind检测发现definitely lost内存。

原因:Trainer内部用vector<AbstractProblem*>保存题目,addProblem传入的是new出来的指针,Trainer析构函数没有统一delete。

解决:改用shared_ptr容器,addProblem接收shared_ptr类型参数。这样所有题目对象在引用计数归零时自动释放,不会泄漏。这也是我在2.2小节里特意用shared_ptr而不用裸指针的原因。

5.4 递归遍历二叉树时栈溢出

现象:树深度超过5000层,程序在递归层序遍历时直接段错误崩溃。

原因:每个递归调用消耗栈空间,默认栈大小只有几MB,深度过深后栈溢出。

解决:源码里不鼓励用递归做层序遍历,而是用std::queue实现BFS。如果是考研笔试手写递归没问题,但如果是在框架里跑大测试数据,BFS的迭代版本更稳。我把两种实现都放在同名头文件里,用宏控制默认选择迭代版本。

5.5 Windows下文件路径分隔符导致读取失败

现象:错题本在Windows上打不开,报错“找不到文件”。

原因:代码里写了"wrong_list.csv",在Linux下没问题,但Windows下如果路径前面带斜杠或反斜杠混用就会出问题。

解决:统一用相对路径,不拼接绝对路径。如果要处理更复杂的路径,建议用std::filesystem(C++17)或者干脆让用户手动指定输出路径,避免平台差异。我的习惯是只在当前目录读写,不在代码里写死任何带盘符的路径。

5.6 计时不准:用了clock()但结果明显偏大

现象:答题时间统计出来远超实际用时,明明只想了10秒,系统显示30秒。

原因:clock()统计的是CPU时间,在多线程或系统负载高的时候会偏大且不稳定。

解决:改用std::chrono::steady_clock::now()获取墙钟时间。我在4.3小节代码里已经这么用了,它能保证不受系统时间调整影响,也不会被其他线程占用CPU时间干扰。

6. 把训练框架扩展成考试模拟器:随机权重抽题与正确率统计

考研题目不是均匀分布的,有些学校机试爱考树和DP,有些爱考链表和排序。把答题框架升级成模拟考试,可以按题型权重分配抽题比例。我在题目基类里加一个category字段,Trainer的抽题方法改成按类别分层抽样:

void Trainer::runMockExam(const std::map<std::string, int>& weight) { std::vector<std::shared_ptr<AbstractProblem>> exam_pool; for (auto& kv : weight) { std::string category = kv.first; int count = kv.second; // 在指定类别下随机选取count道题 auto& cate_problems = problems_by_category_[category]; std::shuffle(cate_problems.begin(), cate_problems.end(), rng); for (int i = 0; i < count && i < (int)cate_problems.size(); ++i) { exam_pool.push_back(cate_problems[i]); } } // 打乱顺序后逐题作答 }

注意:如果某个类别的题目数量不足weight指定的数量,代码里做了截断处理,不会越界。运行时如果发现权重总和大于实际题目数,会在控制台提示“部分类别题目不足”。

正确率统计我用一个简单结构保存每次作答结果,最后输出柱状图式的文字统计:

void Trainer::printStatistics() const { std::map<std::string, int> correct_count; std::map<std::string, int> total_count; for (auto& record : records_) { total_count[record.category]++; if (record.passed) correct_count[record.category]++; } for (auto& kv : total_count) { double rate = 100.0 * correct_count[kv.first] / kv.second; std::cout << kv.first << ": " << rate << "%\n"; } }

最后一个实用技巧是复习调度:错题本里的题目,我会让它们在一周后的模拟考里以两倍权重重新出现。实现方式不复杂,在读取wrong_list.csv时给对应题目category加一个special标志,抽题时优先抽取。这样做的好处是“错题不会只错一遍”,隔一段时间再摸到同一道题,才能真正检验有没有内化。从那以后,我写每一套新增题目都会强制走一遍避坑清单——判题归一化、路径兼容、内存管理、计时器选型,这五个点用十分钟检查完再发布版本。希望这套源码和踩坑记录能帮你在考研机试路上少走几个来回。

本文还有配套的精品资源,点击获取

相关新闻

ESP32舵机控制全攻略:从PWM原理到平滑运动与智能联动

ESP32舵机控制全攻略:从PWM原理到平滑运动与智能联动

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:18:26 阅读更多 →
NPU与TPU硬件加速实战:从端侧推理到云端训练的选型与调优

NPU与TPU硬件加速实战:从端侧推理到云端训练的选型与调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:18:26 阅读更多 →
HPR V2 12kW PSU深度解析:AI机柜48V供电架构的关键设计

HPR V2 12kW PSU深度解析:AI机柜48V供电架构的关键设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 19:18:26 阅读更多 →

最新新闻

ContextCapture安装避坑指南:版本选择、驱动适配与服务配置

ContextCapture安装避坑指南:版本选择、驱动适配与服务配置

简介&#xff1a;本资源提供ContextCapture软件的官方可用下载地址及配套获取指引&#xff0c;面向测绘、三维建模、BIM与数字孪生领域的工程师、高校师生及GIS从业者&#xff0c;解决正版软件获取渠道不明确、网盘链接失效或安装路径不明等实际问题。压缩包仅2KB&#xff0c;含…

2026/10/20 20:02:01 阅读更多 →
OCR模型训练数据不够?用数据生成工具批量造数据实战

OCR模型训练数据不够?用数据生成工具批量造数据实战

OCR模型训练最头疼的从来不是网络结构设计&#xff0c;而是标注数据不够。我做过好几个文字识别项目&#xff0c;每次卡在瓶颈上的几乎都是同一件事&#xff1a;真实场景的样本太少&#xff0c;标注成本太高&#xff0c;模型在测试集上看着还行&#xff0c;一上真实业务就崩。后…

2026/10/20 20:02:01 阅读更多 →
从调API到懂原理:大模型工程实践中的Token、注意力与解码策略

从调API到懂原理:大模型工程实践中的Token、注意力与解码策略

1. 为什么“会调 API”和“懂原理”之间隔着一道鸿沟1.1 从一次线上事故说起去年冬天&#xff0c;我接手了一个基于大模型 API 的智能问答项目。项目本身不复杂&#xff1a;用户提问&#xff0c;后端拼装提示词&#xff0c;调用模型接口&#xff0c;返回答案。团队里两个刚毕业…

2026/10/20 20:02:01 阅读更多 →
VS2019中直接使用wxWidgets二进制文件的工程化实践

VS2019中直接使用wxWidgets二进制文件的工程化实践

1. 项目概述&#xff1a;为什么“直接使用二进制文件”是wxWidgets在VS2019中落地的关键突破口在Windows桌面应用开发圈里&#xff0c;wxWidgets一直是个“熟悉又陌生”的存在——熟悉&#xff0c;是因为它跨平台、开源、C原生、社区稳定&#xff1b;陌生&#xff0c;是因为从官…

2026/10/20 20:02:01 阅读更多 →
贝叶斯非负奖励模型BNRM:稳定RLHF奖励建模的新思路

贝叶斯非负奖励模型BNRM:稳定RLHF奖励建模的新思路

做RLHF做到第三个月的时候&#xff0c;我彻底对“奖励模型”这四个字失去了安全感。当时用的标准奖励模型在验证集上的偏好分类准确率已经刷到了很不错的水平&#xff0c;可一旦接到策略优化里&#xff0c;模型就开始疯狂输出那种“看起来很有道理、读起来全是空话”的内容——…

2026/10/20 20:02:01 阅读更多 →
SSM+Vue考研助手毕业设计全栈开发实战:从院校库到刷题闭环

SSM+Vue考研助手毕业设计全栈开发实战:从院校库到刷题闭环

1. 内容整体设计与思路拆解1.1 这个项目到底解决什么问题2026届毕业设计选“ssmvue考研助手”这个题目的同学不少&#xff0c;但很多人在开题阶段就把路走窄了——以为做个CRUD管理系统就交差。实际上这套题目能承载的东西非常多&#xff0c;关键在于你怎么定义“助手”两个字。…

2026/10/20 20:01:00 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →