[{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/tags/example/","section":"Tags","summary":"","title":"Example","type":"tags"},{"content":" ","date":"2026-06-18","externalUrl":null,"permalink":"/","section":"lyrumu's site","summary":"","title":"lyrumu's site","type":"page"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/tags/meta/","section":"Tags","summary":"","title":"Meta","type":"tags"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/categories/site/","section":"Categories","summary":"","title":"Site","type":"categories"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/tags/test/","section":"Tags","summary":"","title":"Test","type":"tags"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/topics/","section":"Topics","summary":"","title":"Topics","type":"topics"},{"content":" 01 · /notes/ 学习笔记 Notes · code snippets / resources Some notes based on Obsidian\n进入 02 · /works/ 作品 Works · 项目集 Some vibe coding projects for practice and some ideas\n进入 03 · /life/ 生活 hi,can we make a friend? somewhere for the Existentialists\n进入 04 · /about/ 关于我 About me Maybe im leaking my privacy(hahaha)\n进入 ✦ 📌 这是网站的大厅 — 上面四个模块卡对应顶部分类的四个入口。 想直接翻最近的文章？去分类页里看就行：学习笔记 · 作品 · 生活 · 关于我\n模板使用说明 # 改模块卡：编辑 data/modules.yaml 改大厅文案：编辑 content/start/_index.md 想删模块：删 yaml + hugo.toml 里的 menu 即可 ","date":"2026-06-18","externalUrl":null,"permalink":"/start/","section":"Welcome","summary":" 01 · /notes/ 学习笔记 Notes · code snippets / resources Some notes based on Obsidian\n进入 02 · /works/ 作品 Works · 项目集 Some vibe coding projects for practice and some ideas\n","title":"Welcome","type":"start"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/series/%E5%85%B3%E4%BA%8E%E6%9C%AC%E7%AB%99/","section":"Series","summary":"","title":"关于本站","type":"series"},{"content":"","date":"2026-06-18","externalUrl":null,"permalink":"/topics/%E6%A0%B7%E5%BC%8F%E6%B5%8B%E8%AF%95/","section":"Topics","summary":"","title":"样式测试","type":"topics"},{"content":"这一篇是\u0026quot;测试样章\u0026quot;，不是教程。 它存在的意义是：看一眼长什么样 — 文字 / 标题 / 列表 / 表格 / 代码 / 图 / 折叠 / 公式 / 链接 …… 改样式时优先对照这一篇。\n1. 文字 # 普通文字，粗体，斜体，删除线，inline code，内链，外链。\n行内公式：$E = mc^2$。\n按 Ctrl + K 搜索。\n这是 ==高亮文字== (mark)。\n下面是脚注示例1。\n2. 标题层级 # 2.1 三级标题 # 2.2 四级标题 # 2.3 五级标题 # 3. 列表 # 无序：\n第一项 第二项 嵌套 A 嵌套 B 再嵌一层 第三项 有序：\n第一步 第二步 第三步 任务列表：\n已完成 待办 1 待办 2 定义列表：\nHugo 静态网站生成器 Blowfish 一个 Hugo 主题 4. 引用 # 一段引用文字。 可以多行。\n—— 某个人\n5. 表格 # 模块 状态 路径 notes OK /notes/ works TBD /works/ life TBD /life/ about TBD /about/ 6. 代码块 # Go：\n1package main 2 3import \u0026#34;fmt\u0026#34; 4 5func main() { 6 fmt.Println(\u0026#34;Hello, Hugo!\u0026#34;) 7} Python：\n1def fib(n: int) -\u0026gt; int: 2 a, b = 0, 1 3 for _ in range(n): 4 a, b = b, a + b 5 return a Bash：\n1hugo --minify --themesDir themes --theme blowfish JavaScript：\n1const greet = (name) =\u0026gt; `Hi, ${name}!`; 2console.log(greet(\u0026#39;lyrumu\u0026#39;)); 7. 流程图 # 1graph LR 2 A[Obsidian] --\u0026gt; B[GitHub] 3 B --\u0026gt; C[Actions] 4 C --\u0026gt; D[public/] 5 D --\u0026gt; E[Cloudflare] 8. 提示框（用 blockquote + emoji） # ℹ️ INFO 普通信息提示。\n⚠️ WARNING 注意事项 / 警告。\n✅ DONE 完成事项。\n💡 TIP 小贴士。\n9. 链接与下载 # 示例 zip （占位） 示例 mp3 （占位） GitHub 仓库\n10. 图片 # 11. 折叠 # 点击展开 里面什么都能放。\n1print(\u0026#34;hello\u0026#34;) 12. Emoji # :joy: 直接出，或者字符 🎉。\n13. 数学公式 # 行内：$a^2 + b^2 = c^2$\n块级：\n$$ \\int_{0}^{\\infty} e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2} $$\n14. 测试清单 # 文字（粗 / 斜 / 删 / 内联码 / 内链 / 外链） 脚注 标题层级 列表（无序/有序/任务/嵌套/定义） 引用 / 提示框 表格 代码块（多语言） Mermaid 链接与下载 图片 details 折叠 kbd / mark / Emoji 公式（行内 / 块级） Tag / Category / Series Hero 背景 / 面包屑 / TOC / 相关文章 对，就是这条。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-06-18","externalUrl":null,"permalink":"/start/style-test/","section":"Welcome","summary":"这一篇是\"测试样章\"，不是教程。 它存在的意义是：看一眼长什么样 — 文字 / 标题 / 列表 / 表格 / 代码 / 图 / 折叠 / 公式 / 链接 …… 改样式时优先对照这一篇。\n1. 文字 # 普通文字，粗体，斜体，删除线，inline code，内链，外链。\n行内公式：$E = mc^2$。\n按 Ctrl + K 搜索。\n这是 ==高亮文字== (mark)。\n下面是脚注示例1。\n2. 标题层级 # 2.1 三级标题 # 2.2 四级标题 # 2.3 五级标题 # 3. 列表 # 无序：\n","title":"样式测试 · Style Test","type":"start"},{"content":" ==Clash_verge== # windows代理软件\n下载使用 # 直接浏览器搜索引擎搜索,或者去github上搜索都可以下载; （如果打不开github可以下载watt加速器加速github） (Clashverge的github主页也有很多机场的推荐)\n可能的问题 # Wrong1:若刷新ip信息显示\u0026quot;所有ip检测服务失败:undefined\u0026quot;;但是节点正常,只不过流量上传和下载始终是0,无法使用; 可能就是系统把端口预留了,比如一开始端口是7897,\n修改代理软件和系统代理端口(一般可以直接改混合端口)重试,比如改成10808等;\n==Shadowrocket== # ios代理软件\n首先需要给Appstore注册一个美区账号\n然后才能在商店购买正版Shadowrocket\n或者使用网上的共享账号登录App Store（千万别登录系统账号） 搜索shadowrocket进行下载后 登录回自己的账号\n注册美区账号 # 参考教程：[[https://www.bilibili.com/video/BV1zHtmzDEVY/?spm_id_from=333.337.search-card.all.click\u0026amp;vd_source=04d755a57294157b6417db0ec31c1460]] （我用Google创建了新的美区账号一样可以）\n==OBS== # 录屏直播软件\n游戏录制 # 推荐选择添加窗口采集源,比游戏采集源更加稳定;\n在设置中打开回放缓存:\n可以在精彩内容出现后按下快捷键保存前几十秒的游戏内容\n在设置中调整视频编码器: 选择最好的编码器,尽量避免录屏时游戏卡顿\n在设置中调整分辨率: 基础分辨率必须和设备一样,如果卡顿可以适当降低输出分辨率\n如果后期发现没有录制整个游戏屏幕,在主界面依次点击\n编辑-变换-比例适配屏幕可能能解决问题\n==Ollama\u0026amp;LMstudio== # 管理本地大模型\nOllama # Download Ollama on Windows\nDownload Ollama on Linux\nDownload Ollama on macOS\n不开梯子下载会很慢,暂时没有梯子可以选择复制上面链接后,\n进入minecraft启动器PCL2进行多线程下载;\nLMstudio # ==Windows== # 记录一些系统设置操作\n分盘 # (分盘时最好给C盘预留至少100G的空间)\nwin+x-磁盘管理-右键windows(C盘);\n点击压缩卷,稍作等待,修改要分出去的存储空间大小;\n例如分出去100G 就修改为102400(MB);\n后续配置无需修改 一直点下一步即可;\n最后再右键未分配的区域进行分配即可;\n浏览器 # 关闭最后标签页但不关闭浏览器 # edge 目前可以直接在浏览器设置里搜索关键词“标签页”来手动设置 右键桌面edge图标-属性 在目标一栏的最后加上 --enable-features=msSpawnNtpOnLastTabClose 再次进入edge测试即可 firefox 在浏览器地址栏输入about:config 搜索browser.tabs.closeWindowWithLastTab 改为false即可 网络 # VMware+WSL+Clash # Windows系统在这三者共存的情况下 可能会出现WLAN驱动问题 如果右下角网络选项突然消失 尝试:\n重启 Win+R输入ncpa.cpl 查看WLAN驱动是否被系统关闭 重新开启即可 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/apps/app-notes/","section":"学习笔记","summary":"==Clash_verge== # windows代理软件\n下载使用 # 直接浏览器搜索引擎搜索,或者去github上搜索都可以下载; （如果打不开github可以下载watt加速器加速github） (Clashverge的github主页也有很多机场的推荐)\n可能的问题 # Wrong1:若刷新ip信息显示\"所有ip检测服务失败:undefined\";但是节点正常,只不过流量上传和下载始终是0,无法使用; 可能就是系统把端口预留了,比如一开始端口是7897,\n修改代理软件和系统代理端口(一般可以直接改混合端口)重试,比如改成10808等;\n==Shadowrocket== # ios代理软件\n首先需要给Appstore注册一个美区账号\n然后才能在商店购买正版Shadowrocket\n或者使用网上的共享账号登录App Store（千万别登录系统账号） 搜索shadowrocket进行下载后 登录回自己的账号\n","title":"","type":"notes"},{"content":" 安装配置Docker # windows\n首先安装最新版本的WSL2 win键搜索启用或关闭windows功能;\n(以下是win11家庭版 如果有\u0026quot;虚拟机平台\u0026quot; 也勾选上)\n安装Hyper-V\n新建文本文件-打开-将以下内容复制进去-保存退出-\n将文本文件后缀改为cmd-右键管理员身份运行-安装完后重启计算机\n1pushd \u0026#34;%~dp0\u0026#34; 2dir /b %SystemRoot%\\servicing\\Packages\\*Hyper-V*.mum \u0026gt;hyper-v.txt 3for /f %%i in (\u0026#39;findstr /i . hyper-v.txt 2^\u0026gt;nul\u0026#39;) do dism /online /norestart /add-package:\u0026#34;%SystemRoot%\\servicing\\Packages\\%%i\u0026#34; 4del hyper-v.txt 5Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL 6pausepause win键搜索powershell-右键管理员身份打开-输入wsl --install --no-distribution;(安装不带任何发行版的Linux虚拟机);\n后续查看版本输入:\nwsl --list --verbose;\n安装Ubuntu:\nwsl --install Ubuntu-22.04;\n最后换原:\n1sudo su 2bash \u0026lt;(curl -sSL https://linuxmirrors.cn/main.sh) (这样基本能装好wsl2 剩余内容待更新)\n根据系统信息选择docker安装包 win键打开设置-系统-系统信息:\n如果跟图示一样就选择AMD64的docker安装包;(大部分都是这个)\n否则选择下载ARM64的安装包;\n双击下载好的安装包-安装过程中如果有提示 选择WSL\n其他问题可以访问Docker Docs解决\nDocker配置： 右上角设置-Resources-可以修改Disk image location(C盘空间足够的话可以不修改);\n设置-Docker Engine:\n1{ 2 \u0026#34;builder\u0026#34;: { 3 \u0026#34;gc\u0026#34;: { 4 \u0026#34;defaultKeepStorage\u0026#34;: \u0026#34;20GB\u0026#34;, 5 \u0026#34;enabled\u0026#34;: true 6 } 7 }, 8 \u0026#34;experimental\u0026#34;: false, 9 \u0026#34;features\u0026#34;: { 10 \u0026#34;buildkit\u0026#34;: true 11 }, 12 \u0026#34;registry-mirrors\u0026#34;: [ 13 \u0026#34;https://docker.m.daocloud.io\u0026#34;, 14 \u0026#34;https://docker.nju.edu.cn\u0026#34;, 15 \u0026#34;https://docker.mirrors.ustc.edu.cn\u0026#34;, 16 \u0026#34;https://hub-mirror.c.163.com\u0026#34;, 17 \u0026#34;https://mirror.baidubce.com\u0026#34;, 18 \u0026#34;https://mirror.aliyuncs.com\u0026#34;, 19 \u0026#34;https://docker.mirrors.sjtug.sjtu.edu.cn\u0026#34;, 20 \u0026#34;https://dockerproxy.com\u0026#34;, 21 \u0026#34;https://dockerhub.icu\u0026#34;, 22 \u0026#34;https://mirror.iscas.ac.cn\u0026#34;, 23 \u0026#34;https://docker.rainbond.cc\u0026#34; 24 ] 25} 部署Dify # 在想要存放dify文件夹的目录右键打开终端; 网络不好的话就修改一下git配置如下:(需要先装好git)\n选择浅克隆;(即不包含历史提交文件 只有最新文件)\n1git config --global http.postBuffer 524288000 2git config --global core.compression 9 3git clone --depth 1 https://github.com/langgenius/dify.git 等待下载完毕\n打开dify文件夹/Docker/.env.example 将.env.example重命名为.env;\n(目的是让dokcer能够读取配置文件)\n在当前Docker文件夹打开终端运行:\n1docker compose up -d#启动dify容器 此时由于还没有拉取(pull)相关镜像 会先进行拉取;\n如果中途失败多半是网络问题;\n可以再次输入上述命令重试 直到全部下载完成;\n更推荐的则是逐条镜像拉取(按照大小从小到大逐个pull);\n全部拉取完成后能在docker-images中看到以上镜像;(版本仅供参考)\n打开DIfy网页 确保镜像全部拉取完毕 并且docker处于后台运行状态下;\n选择用docker compose up -d启动dify;\n然后浏览器URL输入http://localhost/signin;\n就能进入dify页面了 初次进入需要注册;\n连接本地ollama大模型 进入页面后点击右上角头像-设置;\n左侧栏-模型供应商-选择安装ollama供应商;\n安装完成后点击上图右下角-添加模型;\n模型名称填写-本地已部署的大模型名称(需完全一样);\n模型类型-LLM;\n基础URL-http://host.docker.internal:11434;\n其他可以暂时保持默认 然后点击添加 就可以用了;\n可以在工作区创建一个聊天助手类型的空白应用进行测试;\n关闭dify以及docker 在dify/docker目录下的终端输入docker compose down(会停止并删除容器 但会保留数据和配置)\n后可再输入docker ps;若只输出表头 说明容器都已经关闭;\n然后右下角退出docker就好了(Quit Docker Desktop);\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/docker/docker-dify/","section":"学习笔记","summary":"安装配置Docker # windows\n首先安装最新版本的WSL2 win键搜索启用或关闭windows功能;\n(以下是win11家庭版 如果有\"虚拟机平台\" 也勾选上)\n安装Hyper-V\n新建文本文件-打开-将以下内容复制进去-保存退出-\n将文本文件后缀改为cmd-右键管理员身份运行-安装完后重启计算机\n1pushd \"%~dp0\" 2dir /b %SystemRoot%\\servicing\\Packages\\*Hyper-V*.mum \u003ehyper-v.txt 3for /f %%i in ('findstr /i . hyper-v.txt 2^\u003enul') do dism /online /norestart /add-package:\"%SystemRoot%\\servicing\\Packages\\%%i\" 4del hyper-v.txt 5Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL 6pausepause win键搜索powershell-右键管理员身份打开-输入wsl --install --no-distribution;(安装不带任何发行版的Linux虚拟机);\n后续查看版本输入:\nwsl --list --verbose;\n安装Ubuntu:\nwsl --install Ubuntu-22.04;\n最后换原:\n1sudo su 2bash \u003c(curl -sSL https://linuxmirrors.cn/main.sh) (这样基本能装好wsl2 剩余内容待更新)\n","title":"","type":"notes"},{"content":" Dart # 配置 # 下载DartSDK;\n下载完成后 打开cmd输入dart --version;\n若配置成功应该会出现类似下面的结果\n1PS C:\\Users\\lyrumu\\Desktop\u0026gt; dart --version 2 3Dart SDK version: 3.11.4 (stable) (Tue Mar 24 01:02:20 2026 -0700) on \u0026#34;windows_x64\u0026#34; ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/flutter/flutter-dart-trae/","section":"学习笔记","summary":"Dart # 配置 # 下载DartSDK;\n下载完成后 打开cmd输入dart --version;\n若配置成功应该会出现类似下面的结果\n1PS C:\\Users\\lyrumu\\Desktop\u003e dart --version 2 3Dart SDK version: 3.11.4 (stable) (Tue Mar 24 01:02:20 2026 -0700) on \"windows_x64\"","title":"","type":"notes"},{"content":" Git安装 # 首先cmd打开终端输入\n1where git 判断一下系统有无安装git 没有的话去官网安装即可 Redirecting… 安装过程还挺麻烦的 可以一步步问AI该选择哪些选项\u0026hellip;\u0026hellip;\n网站选择 # 首选Github 也可以先用国内的Gitee练手\n仓库创建 # 以下操作在github/gitee内进行.\n初始化仓库： (1)选择语言: 按需或不选，主要是给仓库打上一个“主要编程语言”的标签 (2)添加.gitigore: 一般推荐添加，用于告诉git哪些文件不需要管理 (3)添加开源许可证： 一般选择MIT-license(开源) （以上内容后期应该都是可以再添加的，可以先不选） 设置模板： (1)readme文件: 仓库的门面和说明书，按需选择，后期可再添加 (2)issue模板文件: 便于别人给你的仓库提交bug或功能建议 (3)pull request模板文件: 当别人想为你贡献代码时用这个模板来请求 选择模型分支： 可以先默认选择“main”或“master”分支 本地文件上传 # 本地已有仓库 将其上传github 利于备份和版本管理；\n适合个人项目；\n即先本地建立文件 再上传； 不过一般是先创建仓库再clone到本地进行开发； 注：选择本地已有的文件上传时 新建仓库不要勾选readme和license 因为会导致仓库和本地的初始化内容不统一； 如果已经勾选了 建议之后使用强制推送，使用本地内容覆盖仓库；\n1#首先在github新建仓库 2#再在文件资源管理器中进入所需上传的文件 3#然后右键文件空余处，点击在终端中打开 4#然后确保终端中显示的目录就是当前想要上传的文件，then： 5git init 6#个人开发者的话可以用global全局设置 即所有项目用同一个身份 7git config user.name \u0026#34;你的用户名\u0026#34; 8git config user.email \u0026#34;你的邮箱@example.com\u0026#34; 9#以下具体内容在gitee中复制即可 10git remote add origin https://gitee.com/你的用户名/仓库名.git 11#上传 12git add . 13git commit -m \u0026#34;初始提交：上传项目文件\u0026#34; 14git push -u origin master -f #\u0026#34;强制推送(只在个人仓库初始化时使用)\u0026#34; 15#注意，上传github最好别用master分支，要用main 16#git push --force-with-lease适合多人开发时使用，防止覆盖他人提交 push前最好git branch查看当前所在分支以及所有本地分支，避免推送到其他分支上，当前所在分支会在前面显示*符号 如果分支不匹配，用git branch -M main移动到正确分支上 关于获取自己github邮箱： 点击头像-\u0026gt;settings-\u0026gt;email； 后续在本地编辑更新完项目后 再更新上传到git：\n1git add . 2git commit -m \u0026#34;更新内容给介绍\u0026#34; 3git push 后期git配置状态检查：\n1git config --list 2#或者 3git config --global --list 同步本地和仓库 # 首先进入本地对应文件 在此打开终端:\n1git fetch origin#获取远程最新状态（安全，不合并本地文件） 2git status#查看本地与远程差异 3git diff#查看具体文件内容差异 git status后的几种可能状态:\nup to date with 'origin/master'\u0026mdash;已同步，无需操作 behind 'origin/master' by X commit\u0026mdash;本地落后，执行git pull ahead of 'origin/master' by X commit\u0026mdash;本地领先，执行git push GitCommit优化 # 通常每次 git commit 只能有一个提交信息，这个信息会附加到整个提交上，而不是单个文件夹或文件上，以下尝试优化\n推荐办法: 每次想要提交前,先git status;(也可结合git diff) 查看当前哪些文件需要被提交; 然后依次:\n1git add filename1/ 2git commmit -m \u0026#34;该文件的修改内容\u0026#34; 3git add filename2/ 4git commit -m \u0026#34;该文件修改内容\u0026#34; 5#最后统一进行git push 6git push origin 7#这样就能在github上看到对每个文件不同的提交信息了 .Gitignore # 被gitignore的文件,在本地依然会随着修改而变化,但每次提交不会被上传到github,即只在本地变化;\n创建.gitignore文件: 在根目录右键新建文本文件-将整个文件重命名为.gitignore(后缀也要一起删掉!) 在文件内写入需要忽略的文件的路径,比如.obsidian/workspace.json,这样该文件就会被忽略,不会被同步到仓库; 检查:\n1#输入 2ls .gitignore* 3#理想输出类似 4Mode LastWriteTime Length Name 5---- ------------- ------ ---- 6-a---- 2026/4/18 13:36 109 .gitignore 7#若输出文件名显示\u0026#34;.gitignore.txt\u0026#34; 那是不正确的 使用.gitignore: 先提交更新后的.gitignore文件至github; 然后通过git status检查是否有已经被GIT跟踪但是需要ignore的文件; ⚠️.gitignore 只能忽略未被跟踪的文件,如果文件已经被 Git 跟踪过,需要先 git rm --cached 再忽略;\n所以如果有,通过git rm --cached config/secret.json让git忽略这个文文件,之后就可以正常add-commit-push了;\nGit多分支page部署 # 添加.github/workflow/deploy/yml文件(创建github Actions) 修改仓库page部署分支为gh-pages\n多平台同步 # 首先进入本地需要同步的文件夹，右键在终端中打开； (后续操作均需在此环境下进行)\n1git remote -v#查看当前文件夹关联的所有远程仓库 需要将同一本地文件同步到不同远程仓库时，建议使用相同的仓库名（仓库名即为-v后显示的“仓库名.git”）在平台先建立相同名称的仓库，不要设置readme等文件； 以下以已经同步到gitee的文件，再同步到github为例：\n1git remote add github https://github.com/用户名/仓库名.git 然后根据分支名推送：\n1git push github master 最后再用git remote -v检查一下，应该会多出origin之外的仓库； 后续更新时，用以下命令推送到两个仓库：\n1git add . 2git commit -m \u0026#34;内容\u0026#34; 3git push origin master#第一个一般都为origin吧 4git push github master 后期若要定期检查本地和两个仓库同步状态：\n1git status#仅用来检查本地和origin的同步状态 （up to date 就说明本地和origin是正确同步的）；\n1git fetch --all#用来检查三方是否都正确同步，以下一步步执行 2git log --oneline HEAD#本地最新提交 3git log --oneline origin/master#gitee最新提交 4git log --oneline github/master#github最新提交 检查三个输出内容是否相同即可；\ndetails # GIT REMOTE 若在github上rename了仓库名称 下一次在本地git add-commit-push之前记得先检查 git remote -v,应该还是旧仓库的地址.因此推荐先配置git remote set-url origin YOUR_NEW_URL.git后再提交代码; Wrong1 # wrong: 由于在gitee上给仓库添加了license文件； 此时仓库有license文件 但本地并没有； and 我并未记得； 直接更新了新的本地内容； 于是乎： 在进行git push时出现报错； 处理方法：\n1git pull origin master#拉取远程仓库的变化更新文件，并合并到本地 此时终端可能会进入另一个界面，叫做\u0026quot;vim编辑器\u0026quot;； 此时要先按一下Esc键，再输入:wq,最后按一下Enter 应该就会恢复正常了； 最后再输入：\n1git push origin master 2#或者这里直接用git push更好 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/git/git-basics/","section":"学习笔记","summary":" Git安装 # 首先cmd打开终端输入\n1where git 判断一下系统有无安装git 没有的话去官网安装即可 Redirecting… 安装过程还挺麻烦的 可以一步步问AI该选择哪些选项……\n网站选择 # 首选Github 也可以先用国内的Gitee练手\n仓库创建 # 以下操作在github/gitee内进行.\n初始化仓库： (1)选择语言: 按需或不选，主要是给仓库打上一个“主要编程语言”的标签 (2)添加.gitigore: 一般推荐添加，用于告诉git哪些文件不需要管理 (3)添加开源许可证： 一般选择MIT-license(开源) （以上内容后期应该都是可以再添加的，可以先不选） 设置模板： (1)readme文件: 仓库的门面和说明书，按需选择，后期可再添加 (2)issue模板文件: 便于别人给你的仓库提交bug或功能建议 (3)pull request模板文件: 当别人想为你贡献代码时用这个模板来请求 选择模型分支： 可以先默认选择“main”或“master”分支 本地文件上传 # 本地已有仓库 将其上传github 利于备份和版本管理；\n","title":"","type":"notes"},{"content":"首先正常安装好VScode(Visual Studio Code) Visual Studio Code - The open source AI code editor | Your home for multi-agent development\n安装MinGW # 推荐官网:MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net\n一步到位:https://zjnu.qingyandark.top:88/userfiles/programs/mingw64_12.2.0.zip\n下载好之后 右键压缩包全部解压缩到一个路径没有中文且容易管理的地方\n添加环境变量: 在Path系统变量中添加你下载好的MinGW路径,类似图中即可;\n配置文件 # c_cpp_properties.json # tasks.json # launch.json # 插件 # ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/vscode/vscode-cpp-env/","section":"学习笔记","summary":"首先正常安装好VScode(Visual Studio Code) Visual Studio Code - The open source AI code editor | Your home for multi-agent development\n安装MinGW # 推荐官网:MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net\n一步到位:https://zjnu.qingyandark.top:88/userfiles/programs/mingw64_12.2.0.zip\n下载好之后 右键压缩包全部解压缩到一个路径没有中文且容易管理的地方\n添加环境变量: 在Path系统变量中添加你下载好的MinGW路径,类似图中即可;\n配置文件 # c_cpp_properties.json # tasks.json # launch.json # 插件 # ","title":"","type":"notes"},{"content":"直接扩展商店里搜索python-安装microsoft官方插件即可；\n基础版本管理 # Python多版本: 系统已经将py3.14安装并写进系统PATH，但是flask目前更适合3.10-3.12的python 因此再去官网安装python3.12 此时注意几点: 1.不要再添加进系统环境变量 2.参考的安装选项: (只需要pip就行了 其他都是多余的 因为已经安装过3.14的py) (推荐给所有用户安装 其后按照图示配置即可)\n之后创建项目: 可以先检查py的安装 1py -0 应该会输出3.14和3.12两个py版本\n然后创建并激活虚拟环境venv\n1py -3.12 -m venv .venv 2.venv\\Scripts\\Activate.ps1 最后pip install flask\npy开发 # (示例)可用结构\n1myproject/ 2├── pyproject.toml 3├── README.md 4├── LICENSE 5├── .gitignore 6├── tests/ #用于pytest测试 7│ └── test_xxx.py 8└── src/ #项目核心源码 9 └── myproject/ 10 ├── __init__.py #必须 11 ├── main.py 12 └── utils.py 首先创建pyproject.toml:(示例)\n1[build-system] 2requires = [\u0026#34;setuptools\u0026gt;=61\u0026#34;] 3build-backend = \u0026#34;setuptools.build_meta\u0026#34; 4 5[project] 6name = \u0026#34;myproject\u0026#34; 7version = \u0026#34;0.1.0\u0026#34; 8description = \u0026#34;Example project\u0026#34; 9readme = \u0026#34;README.md\u0026#34; 10requires-python = \u0026#34;\u0026gt;=3.11\u0026#34; 11 12dependencies = [ 13 \u0026#34;requests\u0026gt;=2.32\u0026#34;, 14 \u0026#34;rich\u0026gt;=14.0\u0026#34; 15] 16 17[project.optional-dependencies] 18dev = [ 19 \u0026#34;pytest\u0026#34;, 20 \u0026#34;ruff\u0026#34; 21] 22 23[tool.setuptools.packages.find] 24where = [\u0026#34;src\u0026#34;] 25 26[tool.ruff] 27line-length = 88 然后运行以下命令:(前提是已有pyproject.toml和__init__.py)\n1pip install -e \u0026#34;.[dev]\u0026#34; Python会将当前项目以Editable模式安装到当前虚拟环境中 之后修改/src中的代码会立即生效 无需重新执行pip install 基础测试:\n1pytest #运行/tests中的自动化测试 检查功能有没有坏 2ruff check . --fix #检查代码有没有明显问题 3ruff format . #统一代码格式 pip install -e \u0026quot;.[dev]\u0026quot;之后无论在哪个目录都可以通过\n1import myprojext 2from myproject import main #等等 来直接读取使用项目的代码\n最后构建包\n1python -m build 会生成dist/文件 供本地安装或上传到PyPI\n发布包到PyPI\n1twine upload dist/* 可能的问题 # Powershell脚本权限 windows的powershell默认没有执行脚本权限 导致无法自动激活虚拟环境 可以通过执行(管理员) 1Set-ExecutionPolicy -Scope CurrentUser RemoteSigned 然后选择“Y”来激活权限-从而顺利地使用venv虚拟环境\n同时可以通过(管理员)\n1Set-ExecutionPolicy -Scope CurrentUser Undefined 来还原Powershell设置\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/vscode/vscode-python-env/","section":"学习笔记","summary":"直接扩展商店里搜索python-安装microsoft官方插件即可；\n基础版本管理 # Python多版本: 系统已经将py3.14安装并写进系统PATH，但是flask目前更适合3.10-3.12的python 因此再去官网安装python3.12 此时注意几点: 1.不要再添加进系统环境变量 2.参考的安装选项: (只需要pip就行了 其他都是多余的 因为已经安装过3.14的py) (推荐给所有用户安装 其后按照图示配置即可)\n之后创建项目: 可以先检查py的安装 1py -0 应该会输出3.14和3.12两个py版本\n然后创建并激活虚拟环境venv\n1py -3.12 -m venv .venv 2.venv\\Scripts\\Activate.ps1 最后pip install flask\npy开发 # (示例)可用结构\n","title":"","type":"notes"},{"content":" 核心原则 # 先易后难：从重启设备开始，逐步深入到系统配置\n对比测试：通过控制变量，大致确定是路由器的问题，还是电脑的问题，是个例问题还是全局问题\n保持记录：记录修复的每一步，避免重复劳动\n无线WLAN修复步骤 # 重启电脑 # 不要关机再开机 而是直接点击开始菜单中的重启哦\n重启路由器 # 如果是新电脑 或者确定没有什么不当操作 即使他人能够连接网络 依然可以相信是网络 而非电脑的问题\n重启路由器 然后等待一下 重新连接\n查看网页认证 # 有些网络需要经过网络认证才能真正进行使用\n忽略网络 # 忽略所连接的网络 再重新连接\n运行网络诊断工具 # 可能运行后问题会直接解决 若没有解决 也能获得一些有利信息\n检查IP和DNS # 确保所连接的无线网IP和DNS都是“自动获取”状态\n检查代理和VPN # 为了防止代理的影响 可以ctrl+shift+esc进入任务管理器\n完全结束代理软件的运行进程\n再尝试连接网络\n命令行修复软件问题 # 在开始菜单输入“cmd”\n右键命令提示符 选择“以管理员方式运行”\n依此输入以下命令后回车（不是全部输入再回车哦 是要一个个来）\n最后重启电脑再尝试\n1ipconfig /release # 释放当前IP 2ipconfig /renew # 重新获取IP 3ipconfig /flushdns # 清除DNS缓存 4netsh winsock reset # 重置网络套接字（修复VPN/代理残留） 网络重置 # 右键网络的图标 进入网络的设置界面\n找到网络重置\n最后重启再尝试\n卸载无线网卡驱动程序 # 开始菜单进入设备管理器 卸载无线网卡驱动程序 重启\n类似intel(R) Wi-Fi 6E AX211 160MHz之类的一个驱动程序\n卸载时记得点击“尝试删除此设备的驱动程序”\n系统会自动安装新的干净的驱动程序\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wifi-dorm-fix/","section":"学习笔记","summary":"核心原则 # 先易后难：从重启设备开始，逐步深入到系统配置\n对比测试：通过控制变量，大致确定是路由器的问题，还是电脑的问题，是个例问题还是全局问题\n保持记录：记录修复的每一步，避免重复劳动\n无线WLAN修复步骤 # 重启电脑 # 不要关机再开机 而是直接点击开始菜单中的重启哦\n重启路由器 # 如果是新电脑 或者确定没有什么不当操作 即使他人能够连接网络 依然可以相信是网络 而非电脑的问题\n重启路由器 然后等待一下 重新连接\n查看网页认证 # 有些网络需要经过网络认证才能真正进行使用\n","title":"","type":"notes"},{"content":" VMware 导致关机挂起修复 # 问题 # Trae / VS Code 连接 WSL 后关机/重启：屏幕熄灭，风扇转，电源灯常亮，需强制关机。\n根因（两个） # 1. vmx86 内核驱动（主因） # VMware 的核心驱动 vmx86.sys 开机自动加载，且带 IGNORES_SHUTDOWN 标志 → 关机时阻塞系统断电。\n2. VMnet 网卡 + VMware 服务（次要） # VMnet1/VMnet8 虚拟网卡和 VMware 服务在关机时也可能阻塞。\n修复 # 第一步：禁用 vmx86 驱动 # 1# 管理员 PowerShell 2sc.exe stop vmx86 3sc.exe config vmx86 start= demand 4# 或用: Set-Service vmx86 -StartupType Manual 下次重启后，不跑 VMware 虚拟机时不加载。开 VMware 会自动加载，不影响使用。\n第二步：禁用 VMware 服务 # 1Stop-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; -Force 2Set-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34;, VmwareAutostartService -StartupType Disabled 第三步：禁用虚拟网卡 # 1Disable-NetAdapter -Name \u0026#34;VMware Network Adapter VMnet8\u0026#34; -Confirm:$false 2Disable-NetAdapter -Name \u0026#34;VMware Network Adapter VMnet1\u0026#34; -Confirm:$false 验证（立即执行后） # 1sc.exe query vmx86 2# → STATE: 1 STOPPED（刚跑过 sc stop 的结果） 3 4Get-NetAdapter | Where-Object Name -match \u0026#39;VMware|VMnet\u0026#39; 5# → 应为 Disabled 或 Not Present 6 7Get-Service | Where-Object DisplayName -match \u0026#39;VMware\u0026#39; | Select Name,Status,StartType 8# → 全部 Stopped + Disabled 验证（重启后） # 1# 重启后打开管理员 PowerShell 2 3sc.exe query vmx86 4# → STATE: 1 STOPPED ← 正确，驱动未加载 5# → STATE: 4 RUNNING ← 说明没生效，重跑 sc.exe config vmx86 start= demand 6 7Get-NetAdapter | Where-Object Name -match \u0026#39;VMware|VMnet\u0026#39; 8# → 不出任何结果 ← 正确，网卡已禁用 9 10Get-Service | Where-Object DisplayName -match \u0026#39;VMware\u0026#39; | Select Name,Status,StartType 11# → 全部 Stopped, Disabled ← 正确 12 13# 关机测试 14wsl --shutdown 15shutdown /s /t 0 16# → 电源灯应在 30 秒内熄灭，无需强制关机 恢复 VMware 使用 # 1# 网卡 2Enable-NetAdapter \u0026#34;VMware Network Adapter VMnet8\u0026#34; 3Enable-NetAdapter \u0026#34;VMware Network Adapter VMnet1\u0026#34; 4 5# 服务 6Set-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; -StartupType Automatic 7Start-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; 8 9# 驱动（vmx86 会在开 VMware 时自动加载） 效果 # 指标 修复前 修复后 重启耗时 ~3 分钟或卡死 ~38 秒 Trae WSL 后关机 挂起 ✅ 正常 BSOD 0x9f 5 月 3 次 无 备注 # VMware 17.6.4 未卸载，仅禁用网络组件和驱动 如果 Clash 卡死导致网络断 + 关机挂起，先关 Clash 再重启 与 Hyper-V、WSL 本身无关 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/fix/wsl2-vmware-fix-2/","section":"学习笔记","summary":"VMware 导致关机挂起修复 # 问题 # Trae / VS Code 连接 WSL 后关机/重启：屏幕熄灭，风扇转，电源灯常亮，需强制关机。\n根因（两个） # 1. vmx86 内核驱动（主因） # VMware 的核心驱动 vmx86.sys 开机自动加载，且带 IGNORES_SHUTDOWN 标志 → 关机时阻塞系统断电。\n","title":"","type":"notes"},{"content":" VMware 导致关机挂起修复 # 环境 # 项目 值 操作系统 Windows 11 (Hyper-V / WSL2) VMware Workstation 17.6.4 (F:\\VMware) IDE Trae (ByteDance) / VS Code — WSL Remote 模式 WSL wsl2, memory=6GB, processors=8 问题 # Trae / VS Code 连接 WSL 后关机/重启：屏幕熄灭，风扇转，电源灯常亮，需强制关机。\n根因（两个） # 1. vmx86 内核驱动（主因） # VMware 的核心驱动 vmx86.sys 开机自动加载，且带 IGNORES_SHUTDOWN 标志 → 关机时阻塞系统断电。\n2. VMnet 网卡 + VMware 服务（次要） # VMnet1/VMnet8 虚拟网卡和 VMware 服务在关机时也可能阻塞。\n修复 # 第一步：禁用 vmx86 驱动 # 1# 管理员 PowerShell 2sc.exe stop vmx86 3sc.exe config vmx86 start= demand 4# 或用: Set-Service vmx86 -StartupType Manual 下次重启后，不跑 VMware 虚拟机时不加载。开 VMware 会自动加载，不影响使用。\n第二步：禁用 VMware 服务 # 1Stop-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; -Force 2Set-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34;, VmwareAutostartService -StartupType Disabled 第三步：禁用虚拟网卡 # 1Disable-NetAdapter -Name \u0026#34;VMware Network Adapter VMnet8\u0026#34; -Confirm:$false 2Disable-NetAdapter -Name \u0026#34;VMware Network Adapter VMnet1\u0026#34; -Confirm:$false 验证（立即执行后） # 1sc.exe query vmx86 2# → STATE: 1 STOPPED（刚跑过 sc stop 的结果） 3 4Get-NetAdapter | Where-Object Name -match \u0026#39;VMware|VMnet\u0026#39; 5# → 应为 Disabled 或 Not Present 6 7Get-Service | Where-Object DisplayName -match \u0026#39;VMware\u0026#39; | Select Name,Status,StartType 8# → 全部 Stopped + Disabled 验证（重启后） # 1# 重启后打开管理员 PowerShell 2 3sc.exe query vmx86 4# → STATE: 1 STOPPED ← 正确，驱动未加载 5# → STATE: 4 RUNNING ← 说明没生效，重跑 sc.exe config vmx86 start= demand 6 7Get-NetAdapter | Where-Object Name -match \u0026#39;VMware|VMnet\u0026#39; 8# → 不出任何结果 ← 正确，网卡已禁用 9 10Get-Service | Where-Object DisplayName -match \u0026#39;VMware\u0026#39; | Select Name,Status,StartType 11# → 全部 Stopped, Disabled ← 正确 12 13# 关机测试 14wsl --shutdown 15shutdown /s /t 0 16# → 电源灯应在 30 秒内熄灭，无需强制关机 恢复 VMware 使用 # 1# 网卡 2Enable-NetAdapter \u0026#34;VMware Network Adapter VMnet8\u0026#34; 3Enable-NetAdapter \u0026#34;VMware Network Adapter VMnet1\u0026#34; 4 5# 服务 6Set-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; -StartupType Automatic 7Start-Service VMAuthdService, VMnetDHCP, VMUSBArbService, \u0026#34;VMware NAT Service\u0026#34; 8 9# 驱动（vmx86 会在开 VMware 时自动加载） 效果 # 指标 修复前 修复后 重启耗时 ~3 分钟或卡死 ~38 秒 Trae WSL 后关机 挂起 ✅ 正常 BSOD 0x9f 5 月 3 次 无 备注 # VMware 17.6.4 未卸载，仅禁用网络组件和驱动 如果 Clash 卡死导致网络断 + 关机挂起，先关 Clash 再重启 与 Hyper-V、WSL 本身无关 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/fix/wsl2-vmware-fix/","section":"学习笔记","summary":"VMware 导致关机挂起修复 # 环境 # 项目 值 操作系统 Windows 11 (Hyper-V / WSL2) VMware Workstation 17.6.4 (F:\\VMware) IDE Trae (ByteDance) / VS Code — WSL Remote 模式 WSL wsl2, memory=6GB, processors=8 问题 # Trae / VS Code 连接 WSL 后关机/重启：屏幕熄灭，风扇转，电源灯常亮，需强制关机。\n","title":"","type":"notes"},{"content":" WinNAT 端口冲突修复 # 环境 # 项目 值 操作系统 Windows 11 (Hyper-V / WSL2) WSL wsl2, appendWindowsPath=false 常用服务 LM Studio (端口 1234)、Hermes (端口 8888)、Trae 问题 # 服务报 EACCES: permission denied 0.0.0.0:PORT，端口被 WinNAT（Hyper-V NAT）随机保留占用。\n排查 # 1# 1. 查进程占用 2netstat -ano | findstr :PORT 3 4# 2. 查 WinNAT 保留范围 5netsh interface ipv4 show excludedportrange protocol=tcp 端口出现在排除范围中 → WinNAT 随机保留。\n修复 # ⚠️ 必须按顺序，先停 WSL 再动 WinNAT\n1# 管理员 PowerShell 2wsl --shutdown 3net stop winnat 4net start winnat 先动 WinNAT 后执行 wsl \u0026ndash;shutdown 会损坏 WSL2 网络，必须重启 Windows 才能恢复。\n验证 # 重启后打开 WSL 终端，启动服务，确认端口可正常绑定。\n原理 # WinNAT 每次开机随机申请一段端口（如 1139-1238），1234 正好落在范围内即报错。重启 WinNAT 重新随机分配，可能避开 1234。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/fix/wsl2-winnat-fix/","section":"学习笔记","summary":"WinNAT 端口冲突修复 # 环境 # 项目 值 操作系统 Windows 11 (Hyper-V / WSL2) WSL wsl2, appendWindowsPath=false 常用服务 LM Studio (端口 1234)、Hermes (端口 8888)、Trae 问题 # 服务报 EACCES: permission denied 0.0.0.0:PORT，端口被 WinNAT（Hyper-V NAT）随机保留占用。\n排查 # 1# 1. 查进程占用 2netstat -ano | findstr :PORT 3 4# 2. 查 WinNAT 保留范围 5netsh interface ipv4 show excludedportrange protocol=tcp 端口出现在排除范围中 → WinNAT 随机保留。\n","title":"","type":"notes"},{"content":"Hermes Agent Documentation | Hermes Agent 以上是官方文档 内容很多\nHermes-Agent安装步骤 # 文档强调：原生 Windows 不支持，必须在 WSL2 中运行。 (现在桌面版渐渐成熟)\n基础安装 # 一、前置条件 唯一硬性要求：git 已安装 git \u0026ndash;version # 确认 git 可用 其余所有依赖（Python 3.11、Node.js v22、ripgrep、ffmpeg、uv）均由安装器自动检测并安装，无需手动预装。\n二、一键安装\n1curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash 安装器自动完成：\n检测系统，设置依赖 克隆仓库到 ~/.hermes/hermes-agent/ 创建 Python 虚拟环境 安装 Python 依赖 创建 ~/.local/bin/hermes 软链接 写入 PATH 到 ~/.bashrc 可选：LLM provider 配置引导 三、安装后的文件结构变化\n1~/.hermes/ 2├── **config.yaml # 配置（模型、终端、工具等）** 3├── **.env # API 密钥和 secrets** 4├── auth.json # OAuth 凭据 5├── SOUL.md # agent 人格定义 6├── hermes-agent/ # 代码仓库 7├── memories/ # 持久记忆 8├── skills/ # 技能 9├── cron/ # 定时任务 10├── sessions/ # 会话 11└── logs/ # 日志 12~/.local/bin/hermes # 可执行文件软链接 13与 OpenCode 零冲突：OpenCode 在 ~/.opencode/ 和 ~/.config/opencode/，Hermes 在 ~/.hermes/，二进制名也不同。 四、安装后首次配置 步骤 1：重新加载 shell source ~/.bashrc # 或 source ~/.zshrc 步骤 2：配置 LLM Provider（最关键的一步） hermes model 支持的 provider（文档中列出的部分）：\n1Provider 认证方式 2Nous Portal OAuth 登录 3OpenAI Codex Device code OAuth 4Anthropic OAuth 或 API key 5OpenRouter API key 6DeepSeek DEEPSEEK_API_KEY 7GitHub Copilot OAuth 8Custom Endpoint base URL + API key（支持 Ollama/vLLM 等） 9Alibaba Cloud / DashScope DASHSCOPE_API_KEY 文档特别提示：模型至少需要 64K tokens 上下文窗口。\n步骤 3：运行首次对话验证 hermes # 经典 CLI hermes --tui # 推荐，现代 TUI 界面 或者通过以下配置 以后默认使用TUI： 步骤 4：验证会话持久化 hermes --continue # 恢复最近会话 hermes -c # 简写\n五、后期配置建议（按优先级排列） 第一优先级：基础可用性 命令 作用 hermes model 更换/添加 LLM provider 和模型 hermes tools 配置启用的工具集（terminal、web、skills 等） hermes config set terminal.backend local 终端后端（默认 local，可换 docker/ssh/modal 等） hermes setup 完整配置向导 第二优先级：安全加固（文档强制建议）\n设置 .env 文件权限 chmod 600 ~/.hermes/.env\n配置危险命令审批模式（~/.hermes/config.yaml） approvals: mode: manual # manual | smart | off timeout: 60\n如果你以后用 gateway（消息平台），文档强调必须配置 allowlist，否则默认全部拒绝：\n~/.hermes/.env\nTELEGRAM_ALLOWED_USERS=你的用户ID\n生产部署 checklist（文档原文）：\n设置明确的 allowlist 使用 Docker 后端做容器隔离 设置资源限制（CPU/内存/磁盘） API 密钥放 .env 并 chmod 600 不要以 root 运行 gateway 定期更新：hermes update 第三优先级：进阶功能 场景 命令/配置 接入消息平台 hermes gateway setup（文档建议 CLI 跑通后再搞） Docker 隔离 hermes config set terminal.backend docker 定时任务 hermes cron create \u0026ldquo;每天上午9点发日报\u0026rdquo; 安装技能 hermes skills search kubernetes → hermes skills install ... MCP 集成 编辑 ~/.hermes/config.yaml 加 mcp_servers 段 语音模式 pip install \u0026quot;hermes-agent[voice]\u0026quot; 然后 /voice on 编辑器集成 (ACP) pip install -e '.[acp]' → hermes acp，支持 VS Code/Zed/JetBrains 配置自动压缩 默认已启用，compression.threshold: 0.50，到 50% 上下文时自动压缩 故障排查工具（文档推荐顺序） hermes doctor # 诊断一切 hermes model # 重新配置 provider hermes setup # 全量配置向导 hermes sessions list # 列出所有会话 hermes --continue # 恢复会话测试 hermes gateway status # gateway 状态 六、更新与卸载 操作 命令 更新 hermes update（文档说会自动拉代码、更新依赖、跑 config migrate、重启 gateway） 预览更新 hermes update --check（只检查不更新，可用于脚本） 查看版本 hermes version 卸载 hermes uninstall（可选保留 ~/.hermes/ 配置）\n基础命令 # 1 /help # 查看所有命令列表 2 /title 我的会话 # 给当前会话起名字，方便以后恢复 3 /new # 开始新会话（工具变更后需要这个才能生效） 4 /retry # 重新发送上一条消息 5 /undo # 撤销上一轮对话 6 /resume # 恢复之前命名的会话 7 /compress # 手动压缩对话历史（省 token） 8 /stop # 停止正在运行的进程 9 /model grok-4 # 切换模型（不用退出） 10 /reasoning medium # 设置推理深度（none/low/medium/high） 11 /clear # 清屏 12 ⚙️ 配置相关 13 终端操作 14 hermes config # 查看当前配置 15 hermes config edit # 用编辑器打开配置文件 16 hermes config set key val # 设置某个值 17 工具管理 18 hermes tools # 交互式启用/禁用工具 19 hermes tools list # 查看所有工具状态 20 技能管理 21 hermes skills list # 查看已安装技能 22 hermes skills search 关键词 # 搜索技能市场 23 hermes skills install 名称 # 安装技能 24 MCP 服务器 25 hermes mcp add 名称 --command \u0026#34;npx ...\u0026#34; 26 hermes mcp list 27 🔍 诊断 28 hermes doctor # 健康检查 29 hermes doctor --fix # 自动修复能修的问题 30 hermes setup # 交互式配置向导 快捷键\u0026amp;\u0026amp;指令 # Alt Enter 或Ctrl j\u0026mdash;-换行 hermes gateway setup 配置远程平台 hermes dashboard打开网页端配置端口(目前网页端也能对话) hermes --tui sessions browse以TUI方式选择一个历史对话打开 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/hermes/wsl2-hermes-agent/","section":"学习笔记","summary":"Hermes Agent Documentation | Hermes Agent 以上是官方文档 内容很多\nHermes-Agent安装步骤 # 文档强调：原生 Windows 不支持，必须在 WSL2 中运行。 (现在桌面版渐渐成熟)\n基础安装 # 一、前置条件 唯一硬性要求：git 已安装 git –version # 确认 git 可用 其余所有依赖（Python 3.11、Node.js v22、ripgrep、ffmpeg、uv）均由安装器自动检测并安装，无需手动预装。\n二、一键安装\n1curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash 安装器自动完成：\n检测系统，设置依赖 克隆仓库到 ~/.hermes/hermes-agent/ 创建 Python 虚拟环境 安装 Python 依赖 创建 ~/.local/bin/hermes 软链接 写入 PATH 到 ~/.bashrc 可选：LLM provider 配置引导 三、安装后的文件结构变化\n","title":"","type":"notes"},{"content":" Hermes API 网络连接修复记录 (APIConnectionError) # 环境 # OS: Windows 11 + WSL2 (Ubuntu) WSL2 IP: 172.30.30.3 Windows Host (网关): 172.30.16.1 Proxy: Clash Verge Rev (allow-lan: true, mixed-port: 7890) API Provider: DeepSeek (https://api.deepseek.com/v1) Hermes Agent: 源码安装 (~/.hermes/hermes-agent/) 问题 # hermes 会话中频繁出现：\n1API call failed (attempt 1/3): APIConnectionError 2🔌 Provider: deepseek Model: deepseek-v4-flash 3🌐 Endpoint: https://api.deepseek.com/v1 4📝 Error: Connection error. 5⏳ Retrying in 2.3s (attempt 1/3)... 间歇性发生，有时能连上，有时超时重试。\n根因分析 # 1. WSL2 DNS 不稳定（主要原因） # WSL2 默认 DNS 为 10.255.255.254（由 Windows/WSL 自动生成），该 DNS 对 api.deepseek.com 的解析间歇性超时。\n验证过程：\n测试 结果 结论 nslookup api.deepseek.com ✅ 返回 112.13.211.83 / 086 DNS 有时正常 dig +short api.deepseek.com ❌ \u0026ldquo;communications error, timed out\u0026rdquo; 但仍返回结果 DNS 不稳定 curl --resolve 直连（跳过 DNS） ✅ HTTP 401, 0.13s API 服务本身正常 curl 正常解析 DNS 后连接 ❌ 超时 10s, exit 28 问题在 DNS 解析环节 api.deepseek.com 解析到中国移动 IP（112.13.x.x），但 WSL2 默认 DNS 解析该域名不可靠。\n2. 未配置代理 # WSL2 内无 HTTP_PROXY / HTTPS_PROXY 环境变量，Python 的 httpx 库直连 DeepSeek 时，如果恰好 DNS 解析失败就会连接超时。\n3. Clash 网关 IP 识别错误 # 早期记录中 WSL 网关 IP 被误记为 172.30.30.1。正确网关 IP 需从 ip route 获取：\n1default via 172.30.16.1 dev eth0 正确网关为 172.30.16.1，属于 172.30.16.0/20 子网。\n修复清单 # # 修复项 操作 影响范围 1 固定 WSL2 DNS 修改 /etc/wsl.conf + /etc/resolv.conf + wsl --shutdown 全局 2 配置代理环境变量 手动设置 HTTP_PROXY / HTTPS_PROXY 当前 Shell 会话 修复 1：固定 WSL2 DNS # 步骤：\n1# Step 1: 修改 /etc/wsl.conf，阻止 WSL 自动覆盖 DNS 2sudo tee -a /etc/wsl.conf \u0026lt;\u0026lt;\u0026lt; $\u0026#39;\\n[network]\\ngenerateResolvConf = false\u0026#39; 3 4# Step 2: 删除旧的 resolv.conf，新建 DNS 配置 5sudo rm /etc/resolv.conf 6sudo tee /etc/resolv.conf \u0026lt;\u0026lt; \u0026#34;EOF\u0026#34; 7nameserver 223.5.5.5 # 阿里 DNS（国内快速稳定） 8nameserver 114.114.114.114 # 114DNS（备用） 9EOF 10 11# Step 3（关键！）：在 Windows PowerShell 重启 WSL，使 wsl.conf 生效 12# 在 Windows 终端执行： 13# wsl --shutdown 14# 然后重新打开 Ubuntu WSL 15 16# Step 4: 验证 17cat /etc/resolv.conf 18# 输出应为： 19# nameserver 223.5.5.5 20# nameserver 114.114.114.114 为什么一定要 wsl --shutdown？ /etc/wsl.conf 的修改需要 WSL 实例完全重启后才能生效。如果不执行这一步，WSL 会继续自动覆盖 /etc/resolv.conf，自定义 DNS 会在几分钟内被还原回 10.255.255.254。\n选择这两个 DNS 的原因：\n223.5.5.5 — 阿里公共 DNS，国内速度快，对国内域名解析准确 114.114.114.114 — 114DNS，老牌国内 DNS，作为备用 修复 2：手动配置代理（按需） # 进入 WSL 后临时设置：\n1export HTTP_PROXY=http://172.30.16.1:7890 2export HTTPS_PROXY=http://172.30.16.1:7890 3export NO_PROXY=localhost,127.0.0.1,::1,.local 启动 Hermes 后 Python 的 httpx / requests / openai 库会自动使用该代理。\n为什么不写入配置文件？ 用户选择手动控制，灵活可控，避免某些场景下代理影响预期外的流量。\n修复后验证 # DNS 稳定性 # 1getent hosts api.deepseek.com 2→ 112.13.211.83 api.deepseek.com.eo.dnse1.com api.deepseek.com 3→ 112.13.210.86 api.deepseek.com.eo.dnse1.com api.deepseek.com 走代理后的连接速度 # 目标 耗时 路由规则 百度 (国内) 0.11s Clash 识别 → DIRECT 淘宝 (国内) 0.08s Clash 识别 → DIRECT DeepSeek 0.11s Clash 识别 → DIRECT（国内 IP） Google (国外) 0.78s Clash 识别 → 代理节点转发 国内网站完全不受影响，Clash 规则引擎自动分流。\n经验教训 # WSL2 网关 IP 不是固定的 — 每次 ip route 确认 default via 的地址。之前 172.30.30.1 是错的，实际是 172.30.16.1。IP 末尾通常是 .1，但前缀（172.30.16 还是 172.30.30）不一定。 DNS 优先排查 — 遇到 APIConnectionError 先测 curl --resolve 跳过 DNS 确认 API 本身是否可达，再查 DNS。 Clash allow-lan 配置 — 确认 allow-lan: true 和 bind-address: '*' 在订阅配置中生效，否则 WSL 连不上 Windows 的 Clash 代理端口。 确认子网范围 — WSL2 的子网是 172.30.16.0/20，即 172.30.16.1 ~ 172.30.31.254 都在同一个子网。 参考命令速查 # 1# 查看 WSL2 网关 IP 2ip route | grep default 3 4# 查看 WSL2 自身 IP 5hostname -I 6 7# 测试 API 连通性（跳过 DNS） 8curl --connect-timeout 5 --resolve api.deepseek.com:443:112.13.211.83 \\ 9 https://api.deepseek.com/v1/models \\ 10 -H \u0026#34;Authorization: Bearer YOUR_KEY\u0026#34; 11 12# 测试代理是否可用 13export HTTP_PROXY=http://172.30.16.1:7890 14curl -s -o /dev/null -w \u0026#34;%{http_code} (%{time_total}s)\\n\u0026#34; https://www.google.com ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/hermes/wsl2-hermes-api/","section":"学习笔记","summary":"Hermes API 网络连接修复记录 (APIConnectionError) # 环境 # OS: Windows 11 + WSL2 (Ubuntu) WSL2 IP: 172.30.30.3 Windows Host (网关): 172.30.16.1 Proxy: Clash Verge Rev (allow-lan: true, mixed-port: 7890) API Provider: DeepSeek (https://api.deepseek.com/v1) Hermes Agent: 源码安装 (~/.hermes/hermes-agent/) 问题 # hermes 会话中频繁出现：\n","title":"","type":"notes"},{"content":" Hermes Dashboard WSL2 修复记录 # 环境 # OS: Windows 11 + WSL2 (Ubuntu) WSL IP: 172.30.30.3 Proxy: Clash Verge Rev（系统代理模式） Hermes Agent: 源码安装（~/.hermes/hermes-agent/） .wslconfig: localhostForwarding=true 问题 # hermes dashboard 启动后，Windows 浏览器无法正常加载页面。\n根因分析 # 1. 默认端口 9119 在 WSL2 下不可用 # 现象：dashboard 绑定 127.0.0.1:9119，在 WSL 内 curl 127.0.0.1:9119 正常，但 Windows 浏览器访问 http://localhost:9119 无响应。\n原因：WSL2 的 localhost 自动转发机制在系统长时间运行、休眠/唤醒后可能失效。Windows Hyper-V 虽然不保留 9119 端口，但 WSL2 的转发代理（wslrelay / localhostForwarding）可能出现状态异常。\n修复：换用 --port 8888。实测 8888 端口可以通过 WSL2 localhost 转发正常访问。如果 8888 也不通，可用 wsl --shutdown 重启 WSL2 恢复转发。\n注：Windows Hyper-V 保留端口范围 7991-8090，其中 8020 已被占用。8888 不在保留范围内。\n2. 示例插件 404 导致 React 无限渲染卡死 # 现象：页面能打开但内容空白，浏览器 Console 报错：\n1GET http://172.30.30.3:9119/dashboard-plugins/example/dist/index.js net::ERR_ABORTED 404 (Not Found) 2[plugins] Failed to load example from /dashboard-plugins/example/dist/index.js 伴随大量 bx → Vn → bx → Vn 递归调用栈（React 错误边界循环）。\n原因：plugins/example-dashboard/dashboard/manifest.json 中 \u0026quot;entry\u0026quot;: \u0026quot;dist/index.js\u0026quot; 引用了不存在的文件。该插件由 monorepo 的测试套件使用，未被构建到 web_dist 中。\n修复：创建空桩文件 plugins/example-dashboard/dashboard/dist/index.js（仅含注释），消除 404 即可。\n3. Clash 代理干扰（非主要原因） # 现象：即使关闭 Clash 系统代理，问题依然存在。\n原因：Clash Verge Rev 的系统代理 bypass 存在已知 bug（#1243），localhost;127.0.0.1;::1 绕过规则未生效。但这不是主要问题——关闭系统代理后仍不可用，说明根本原因在其他地方（见 #1）。\n结论：Clash 问题为次要因素，换端口后自动绕过。\n4. WSL2 NAT 安全性说明 # --host 0.0.0.0 --insecure 在 WSL2 内实际上只对 Windows 本机开放：\n1[Windows 本机] ──┬── 可访问 172.30.30.3:9119 ✅ 2 │ 3 └── [WSL2: 172.30.30.3] ← NAT 隔离 4 5[局域网其他机器] ── 到不了 172.30.30.3 ❌ WSL2 使用 NAT 虚拟交换机，172.30.30.x 是内部私有 IP，外部不可路由。因此 --insecure 的\u0026quot;暴露风险\u0026quot;在 WSL2 环境下微乎其微。\n修复清单 # # 修复项 文件 操作 1 默认端口改为 8888 hermes_cli/main.py:13556 default=9119 → default=8888 2 示例插件桩文件 plugins/example-dashboard/dashboard/dist/index.js 新建空桩文件 最终可用命令 # 1# 方案 A（推荐）—— 默认端口 8888，localhost 访问 2hermes dashboard --no-open 3# → 浏览器打开 http://127.0.0.1:8888 4 5# 方案 B —— 直连 WSL IP（绕过 localhost 转发） 6hermes dashboard --host 0.0.0.0 --insecure --no-open 7# → 浏览器打开 http://172.30.30.3:9119 --no-open 在 WSL2 中用于跳过自动打开浏览器（WSL2 无图形界面），不加也不会报错，只是多一次无用尝试。\n未来建议 # 持久化配置：可将 dashboard.port 加入 config.yaml 的 DEFAULT_CONFIG，让用户通过 hermes config set dashboard.port 8888 配置，无需改源码。 插件构建：CI 流程中应确保所有 manifest.json 中引用的 entry 文件实际存在，或构建脚本覆盖所有插件。 WSL2 健康检查：hermes doctor 可增加 WSL2 localhost 转发检测。 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/hermes/wsl2-hermes-dashboard/","section":"学习笔记","summary":"Hermes Dashboard WSL2 修复记录 # 环境 # OS: Windows 11 + WSL2 (Ubuntu) WSL IP: 172.30.30.3 Proxy: Clash Verge Rev（系统代理模式） Hermes Agent: 源码安装（~/.hermes/hermes-agent/） .wslconfig: localhostForwarding=true 问题 # hermes dashboard 启动后，Windows 浏览器无法正常加载页面。\n根因分析 # 1. 默认端口 9119 在 WSL2 下不可用 # 现象：dashboard 绑定 127.0.0.1:9119，在 WSL 内 curl 127.0.0.1:9119 正常，但 Windows 浏览器访问 http://localhost:9119 无响应。\n","title":"","type":"notes"},{"content":" OpenCode 全局 MCP 配置笔记 # 环境要求 # Node.js ≥ 18 OpenCode ≥ 1.14 1. 创建配置文件 # 1mkdir -p ~/.config/opencode ~/.config/opencode/opencode.json：\n1{ 2 \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, 3 \u0026#34;mcp\u0026#34;: { 4 \u0026#34;shadcn\u0026#34;: { 5 \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, 6 \u0026#34;command\u0026#34;: [\u0026#34;npx\u0026#34;, \u0026#34;-y\u0026#34;, \u0026#34;shadcn@latest\u0026#34;, \u0026#34;mcp\u0026#34;], 7 \u0026#34;enabled\u0026#34;: true 8 } 9 } 10} 2. 预热 npx 缓存 # 避免首次启动时下载失败：\n1npx -y shadcn@latest mcp \u0026amp; 2sleep 2 \u0026amp;\u0026amp; kill %1 3. 验证 # 重启 OpenCode，检查日志确认加载成功：\n1rg \u0026#34;mcp.*shadcn\u0026#34; ~/.local/share/opencode/log/$(ls -t ~/.local/share/opencode/log/ | head -1) 应出现 service=mcp key=shadcn type=local found，且无 Connection closed 报错。\n使用 # Prompt 中加上 use shadcn 即可调用 shadcn MCP 工具。\n添加其他 MCP # 同目录 opencode.json 中追加即可，格式：\n1{ 2 \u0026#34;mcp\u0026#34;: { 3 \u0026#34;another-mcp\u0026#34;: { 4 \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, 5 \u0026#34;command\u0026#34;: [\u0026#34;npx\u0026#34;, \u0026#34;-y\u0026#34;, \u0026#34;some-mcp-server\u0026#34;], 6 \u0026#34;enabled\u0026#34;: true 7 } 8 } 9} 远程 MCP 示例：\n1{ 2 \u0026#34;mcp\u0026#34;: { 3 \u0026#34;sentry\u0026#34;: { 4 \u0026#34;type\u0026#34;: \u0026#34;remote\u0026#34;, 5 \u0026#34;url\u0026#34;: \u0026#34;https://mcp.sentry.dev/mcp\u0026#34;, 6 \u0026#34;oauth\u0026#34;: {} 7 } 8 } 9} 参考 # OpenCode MCP 文档 OpenCode 配置文档 shadcn MCP ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/opencode/wsl2-opencode-mcp/","section":"学习笔记","summary":"OpenCode 全局 MCP 配置笔记 # 环境要求 # Node.js ≥ 18 OpenCode ≥ 1.14 1. 创建配置文件 # 1mkdir -p ~/.config/opencode ~/.config/opencode/opencode.json：\n1{ 2 \"$schema\": \"https://opencode.ai/config.json\", 3 \"mcp\": { 4 \"shadcn\": { 5 \"type\": \"local\", 6 \"command\": [\"npx\", \"-y\", \"shadcn@latest\", \"mcp\"], 7 \"enabled\": true 8 } 9 } 10} 2. 预热 npx 缓存 # 避免首次启动时下载失败：\n","title":"","type":"notes"},{"content":"官方docs:Windows (WSL) | OpenCode\nSettings # Proxy # 打开WSL运行直接curl -fsSL https://opencode.ai/install | bash来安装opencode;\n如果网络不好,可以临时配置WSL代理端口,然后重新输入: curl -fsSL https://opencode.ai/install | bash\n我使用的是windows clashverge的混合端口; 要查看Clash Verge端口 比如是7890; 先运行ip route，获取your_host_ip; 然后执行:\n1export http_proxy=\u0026#34;http://your_host_ip:7890\u0026#34; 2export https_proxy=\u0026#34;http://your_host_ip:7890\u0026#34; 用curl ipinfo.io检查是否配置成功后 重新安装opencode 显示下载完成后; 先刷新一下配置source ~/.bashrc ,然后运行opencode --help; 如果有输出就是安装成功啦;\n为了解决网络问题 可以考虑给WSL永久配置上Windows的代理;(其实临时更好) 先检查Clash Verge里的端口，比如混合端口是7890：\n1nano ~/.bashrc # 进入配置页面 在配置页面最后加上如下内容\n1# 自动获取 Windows Host IP 2HOST_IP=$(ip route | awk \u0026#39;/default/ {print $3}\u0026#39;) 3# HTTP / HTTPS Proxy 4export http_proxy=\u0026#34;http://$HOST_IP:7890\u0026#34; 5export https_proxy=\u0026#34;http://$HOST_IP:7890\u0026#34; 6# SOCKS5 Proxy（按 Clash 实际端口修改） 7export all_proxy=\u0026#34;socks5://$HOST_IP:7898\u0026#34; 加载配置\n1source ~/.bashrc 简单测试:\n1env | grep proxy # 有输出对应变量即可 重装Ubuntu # 出现难以解决的问题可以考虑\n重装第一步 # 彻底删除旧的Ubuntu;\n1wsl --unregister Ubuntu 重新安装Ubuntu: 可以直接点击任务栏Ubuntu图标 很快就会自动重装 需要重新设置用户名和密码 然后先更新软件包\n1sudo apt update 2sudo apt upgrade -y 3sudo apt autoremove -y 换源 # 个人认为不必要切换root用户,先换源就好\n先备份配置文件\n1sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 再更改国内镜像源:(参考) 先打开配置文件\n1sudo nano /etc/apt/sources.list 将编辑器内内容替换为下面的内容(仅供参考)\n1# 清华大学开源软件镜像站 - Ubuntu 22.04 LTS (Jammy) 2# 官方帮助文档：https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ 3deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse 4# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse 5deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse 6# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse 7deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse 8# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse 9deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse 10# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse 11# 以下为可选：Proposed（预发布更新，一般不建议启用） 12# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse 13# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse 注意自己Ubuntu的版本 版本不同源也不同; 最后运行;\n1sudo apt update 输出没有报错即可; 也可以使用脚本bash \u0026lt;(curl -sSL https://linuxmirrors.cn/main.sh)直接完成换源配置 但是是黑盒;\nenv # 优化环境变量,运行下图命令,(可选)\n在echo $PATH测试后 发现我的WSL由于继承windows环境变量后污染严重; 决定关闭继承; 因此:\n1sudo nano /etc/wsl.conf 在最后写入:\n1[interop] 2enabled = true 3appendWindowsPath = false 然后按Ctrl+O写入,再按Enter,最后按Ctrl+X退出即可 最后可以运行source ~/.bashrc让配置立即生效 或者在windows的Powershell里输入;\n1wsl --shutdown 再重启WSL; 再在WSL内测试echo $PATH 就干净很多了;\n安装nodejs # 推荐先装nvm:\n1curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash 然后source ~/.bashrc加载配置，检测nvm --version; 接着安装稳定版nodejs:\n1nvm install --lts 最后用nvm ls,node -v,npm -v检测是否安装成功;\n备份Ubuntu # 在确认当前Ubuntu环境配置相对干净后,可以导出一个备份;\n在windows打开终端:\n1wsl -l -v #复制输出的完整Ubuntu名称 2wsl --shutdown #先关闭wsl 然后先建立好你想保存备份的文件夹; 最后运行下面指令即可\n1wsl --export YOUR_UBUNTU_NAME D:\\wsl_backup\\ubuntu_snapshot.tar #示例路径 备份时若出现U盘不支持单次大文件的传输：右键U盘-属性-查看是否为FAT32; 如果是的话，先对U盘内已有文件进行备份，准备格式化; 右键U盘-格式化-格式一般选择exFAT-分配单元文件大小:保持默认即可; 完成后重新将Ubuntu备份复制进去就行;\nUse # project area # 在WSL终端操作Windows项目:\n1cd /mnt/c/Users/YourName/project 2opencode 全部在WSL内工作:(性能更好)\n1cd ~ 2mkdir opencode_projects 3cd opencode_projects 4mkdir test 5cd test 6opencode opencode functions # /timeline-选择对话记录-revert undo messages and file changes; 将对话和代码回退到当时状态重新修改;(WSL内文件不可回退); /share-对话链接自动进入粘贴板-浏览器打开链接可分享,/unshare关闭链接; /export将对话导出为文件; /undo撤销操作 可多次进行 这个可能比较有用; /session管理当前文件下的历史会话记录 AGENTS.md # 按上图配置AGENTS.md即可; 不过优先考虑通过改变工程架构来提升agent能力;\nskills # 全局skill user/.config/opencode/skills/各个skill文件 项目skill project/.opencode/skills/各个skill文件 可以在opencode中输入/skill检查有无安装成功 优质社区:SkillHub-专为中国用户优化的Skills社区 MCP # 具体配置一般写在user/.config/opencode/opencode.json中 示例:(shadcn,context7)\n1{ 2 \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, 3 \u0026#34;mcp\u0026#34;: { 4 \u0026#34;shadcn\u0026#34;: { 5 \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, 6 \u0026#34;command\u0026#34;: [ 7 \u0026#34;npx\u0026#34;, 8 \u0026#34;-y\u0026#34;, 9 \u0026#34;shadcn@latest\u0026#34;, 10 \u0026#34;mcp\u0026#34; 11 ], 12 \u0026#34;enabled\u0026#34;: true 13 }, 14 \u0026#34;context7\u0026#34;: { 15 \u0026#34;type\u0026#34;: \u0026#34;remote\u0026#34;, 16 \u0026#34;url\u0026#34;: \u0026#34;https://mcp.context7.com/mcp\u0026#34;, 17 \u0026#34;enabled\u0026#34;: true, 18 \u0026#34;headers\u0026#34;: { 19 \u0026#34;CONTEXT7_API_KEY\u0026#34;: \u0026#34;YOUR_API_KEY\u0026#34; 20 } 21 } 22 } 23} 来源1:Context7 - Up-to-date documentation for LLMs and AI code editors; 来源2:MCP Server - shadcn/ui\nLCP # plugins # Oh My Opencode: (如果有claude订阅，codex，Go等订阅 更加推荐)\n1Install and configure oh-my-opencode by following the instructions here: 2https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/refs/heads/dev/docs/guide/installation.md 将以上prompt发给opencode 按照提示安装即可; 来源:code-yeongyu/oh-my-openagent: omo; the best agent harness - previously oh-my-opencode\nOpenCode 会话记录与目录绑定 # 现象 # 如果： cd 某个子目录\nopencode 则当前 session 很可能绑定到：\n当前工作目录（cwd） absolute path（绝对路径） workspace path 当你之后：\n修改子目录名称 移动目录 更换挂载路径 会导致： 进入新目录后找不到旧会话 但在上级目录还能看到旧 session 推荐开发习惯 # 不要在深层子目录启动 opencode # 错误示例：\n1cd project/backend 2opencode 推荐：\n1cd project_root 2opencode 之后：\nagent 操作子目录 terminal 自己 cd 内部结构随便改 这样 session 更稳定。\n先想好项目结构再开发 # 后期再修改项目结构就会使opencode会话记录与结构绑定失效\n最佳实践 # 固定 project root # 例如： my_project/ 尽量：\n不改名 不移动 但内部： src/\nbackend/\nfrontend/\ndocs/ 都可以自由修改。 如果已经改名导致 session 丢失 # 方法1 # 改回原目录名。 session 通常会恢复。\n方法2 # 从项目根目录启动：\n1cd project_root 2opencode 不要直接进入改名后的子目录启动。\n总结 # 推荐固定： project_root/ 然后永远： cd project_root\nopencode\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/opencode/wsl2-opencode/","section":"学习笔记","summary":"官方docs:Windows (WSL) | OpenCode\nSettings # Proxy # 打开WSL运行直接curl -fsSL https://opencode.ai/install | bash来安装opencode;\n如果网络不好,可以临时配置WSL代理端口,然后重新输入: curl -fsSL https://opencode.ai/install | bash\n我使用的是windows clashverge的混合端口; 要查看Clash Verge端口 比如是7890; 先运行ip route，获取your_host_ip; 然后执行:\n1export http_proxy=\"http://your_host_ip:7890\" 2export https_proxy=\"http://your_host_ip:7890\" 用curl ipinfo.io检查是否配置成功后 重新安装opencode 显示下载完成后; 先刷新一下配置source ~/.bashrc ,然后运行opencode --help; 如果有输出就是安装成功啦;\n","title":"","type":"notes"},{"content":" C++/C算法n0t3 # \u0026laquo;算法\u0026raquo; # qsort快排(c语言) # 1.qsort函数原型\n1void qsort(void *base, size_t nmemb, size_t size, 2 int (*compar)(const void *, const void *)); 2.具体写法 （1）先写比较函数 （返回的是整形）\n1// 升序排序（从小到大） 2int cmp_asc(const void *a, const void *b) { 3 return (*(int*)a - *(int*)b); 4} 5// 降序排序 （从大到小） 6int cmp_desc(const void *a, const void *b) { 7 return (*(int*)b - *(int*)a); 8} 解释：因为排序的类型可能是int,double等各种，所以用const voida表示可以指向任何类型的指针，然后在return中先将a转化成对应题目类型的指针例如（int） ，再在前面加* 表示指针所指的具体值 （2）再在主函数中调用\n1qsort(a,n,sizeof(int),cmp); a表示要排序的数组的首地址 n表示数组长度 sizeof（int）表示这个数组类型的数据长度 cmp是提前写好的比较函数的名称 3.原理 比较函数cmp中，（有点难理解但很重要！！） 若返回负值\u0026mdash;\u0026gt;将参数a排在参数b前面 若返回0\u0026mdash;\u0026gt;参数a，参数b顺序不变 若返回正值\u0026mdash;\u0026gt;将参数a排在参数b后面 依此可以写各种其他不同排序：（待开发）\nGCD\u0026amp;LCM # 最大公约数函数(gcd):\n1int gcd(int a,int b){ 2 if(b==0){ 3 return a; 4 } 5 return gcd(b,a%b);//欧几里得算法,辗转相除法,递归版 6}//以上参数顺序不可以调换！ 最小公倍数函数(lcm):\n1int lcm(int a,int b){ 2 if(a==0 || b==0){ 3 return 0; 4 } 5 //return (a*b)/gcd(a,b);为了防止溢出，先除以gcd，再乘： 6 return a/gcd(a,b)*b;//*** 7} 两两乘积之和化简 # eg:一个数组a[n];计算数组中所有不同的两个元素的乘积之和（前后顺序相反的算同一组）\n即a1​⋅a2​+a1​⋅a3​+⋯+a1​⋅an​+a2​⋅a3​+⋯+a(n−2)​⋅a(n−1)​+a(n−2)​⋅an​+a(n−1)​⋅an\n算法思维：\n​ 具体代码：\n1ll a[n];//ll 表示long long 2ll total_sum = 0; 3ll square_sum = 0; 4for(ll i = 0;i\u0026lt;n;i++){ 5 cin\u0026gt;\u0026gt;a[i]; 6 total_sum = total_sum+a[i]; 7 square_sum = square_sum+a[i]*a[i]; 8} 9ll sum = (total_sum*total_sum-square_sum)/2; 一维前缀和 # 1.为何诞生？ Runtime Error： 个人是因为，在计算数组的各个子数组，各个元素之和时复杂度太大 前缀和算法能够帮助提高效率，处理更大更复杂的数据 2.定义前缀和 数组a[n]; 令sum[i] = a1​+a2​+⋯+ai​（其中sum[0] = 0） 3.具体用法 计算一维数组的各个前缀和：\n1int a[n];//先定义一个大小乱序的数组 2//这里省略数组初始化... 3long long presum[n+1] = {0};//初始化前缀和先都为0,大小为n+1防止越界(一定要开足空间！！) 4for(int i = 1;i\u0026lt;=n;i++){//i从1开始，更符合人类习惯，\u0026#34;前i个的和...\u0026#34; 5 presum[i] = a[i-1]+presum[i-1];//第i个元素+前i-1个 6} 4.结合例题 题目（一）：利用前缀和，计算数组的各个子数组中的各个元素之和 解法：\n1int a[n]; 2//这里省略初始化数组，省略前缀和公式 3for(int l = 0;l\u0026lt;n;l++){ 4 for(int r = l;r\u0026lt;n;r++){ 5 //a[r]是第r+1个元素，a[l]是第l+1个元素*** 6 int sum = presum[r+1]-presum[l];//*** 7 } 8} 二维前缀和 # 1.定义二维前缀和\n一个n*m的二维数组矩阵a【n】【m】； 令sum【i】【j】 = $\\sum_{i=1}^{n} \\sum_{j=1}^{m} \\text{a}[i][j]$;\n2.具体用法\n计算二维数组的各个前缀和\n1//注意！为了后续方便，若要计算二维数组前缀和 2//初始化赋值时下标从1开始！！*** 3int a[n+5][m+5]; 4for(int i = 1;i\u0026lt;=n;i++){ 5 for(int j = 1;j\u0026lt;=m;j++){ 6 cin\u0026gt;\u0026gt;a[i][j]; 7 } 8} 9//计算前缀和 10vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; presum(n+5,vector\u0026lt;int\u0026gt;(m+5,0)); 11for(int i = 1;i\u0026lt;=n;i++){ 12 for(int j = 1;j\u0026lt;=m;j++){ 13 presum[i][j] = a[i][j]+presum[i-1][j]+presum[i][j-1]-presum[i-1][j-1];//*** 14 } 15} 3.结合例题\n题目（一）：一个二维矩阵，计算其各个子矩阵的各个元素之和 解法：\n1//先枚举所有子矩阵 2for(int r1 = 1;r1\u0026lt;=n;r1++){ 3 for(int r2 = r1;r2\u0026lt;=n;r2++){//r1,r2分别表示上下边 4 for(int c1 = 1;c1\u0026lt;=m;c1++){ 5 for(int c2 = c1;c2\u0026lt;=m;c2++){//c1，c2表示左右边 6 //计算子矩阵元素和 7 int sum = presum[r2][c2]-presum[r1-1][c2]-presum[r2][c1-1]+presum[r1-1][c1-1];//*** 8 } 9 } 10 } 11} 1//若子矩阵是边长为len的正方形 2//以(i,j)坐标为子矩阵右下角 3for(int i = len;i\u0026lt;n;i++){ 4 for(int j = len;j\u0026lt;n;j++){ 5 int sum = presum[i][j]-presum[i-len][j]-presum[i][j-len]+presum[i-len][j-len]; 6 } 7} 题目（二）：\n滑动窗口 # 适用题型：\n固定长度的，或长度有限制的区间和等\n假设所需求求和的窗口区间长度为len\n1//初始化第一个窗口[0,len-1]的和 2int window_sum = 0; 3for(int i = 0;i\u0026lt;len;i++){ 4 window_sum += arr[i]; 5} 6max_sum = window_sum; 7//用i表示窗口左边界，逐个移动 8//每移动一格，window_sum减去左边一个元素，加上右边一个元素哦 9for(int i = 1;i+len-1\u0026lt;=n-1;i++){//理解限制条件 10 window_sum = window_sum-arr[i-1]+arr[i+len-1]; 11 max_sum = (max_sum,window_sum); 12} 上面为什么是i+len-1\u0026lt;=n-1呢？？？\n因为len表示整个窗口的元素数量，\n例如i=0，若直接i+len,则最后整个窗口会包含len+1个元素.所以应该是i+len-1\u0026lt;=n-1（这很重要！！！）\neg： 解法：（只是为了拓展介绍此算法，实际仍是超时哦，还是需要用特殊的前缀和算法）\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 int n,a,b; 5 cin\u0026gt;\u0026gt;n,a,b; 6 vector\u0026lt;char\u0026gt; s(n); 7 for(int i = 0;i\u0026lt;n;i++){ 8 cin\u0026gt;\u0026gt;s[i]; 9 } 10 int cnt = 0;//计数，表示满足条件的（l，r）的个数 11 for(int l = 0;l\u0026lt;n;l++){//以下展现了滑动窗口思想*** 12 int cnta = 0; 13 int cntb = 0;//在l固定的时候就初始化计数a，b的个数 14 for(int r = l;r\u0026lt;n;r++){ 15 //扩展右边界时更新计数 16 //即，r每更新一次，就假设此时的（l，r）为一组，立刻测试本组的cnta，cntb是否满足条件。 17 //依此，可以省去第三重for循环（原本是要确定l，r后再遍历的） 18 if(s[r]==\u0026#39;a\u0026#39;) cnta++; 19 else if(s[r]==\u0026#39;b\u0026#39;) cntb++; 20 if(cnta\u0026gt;=a \u0026amp;\u0026amp; cntb\u0026lt;b){//每次都要判断哦 21 cnt++; 22 } 23 } 24 } 25 cout\u0026lt;\u0026lt;cnt; 26 return 0 冒泡排序 # 1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int a[n]; 4//这里省略对数组a的输入 5for(int i = 0;i\u0026lt;n-1;i++){//n个数，则进行n-1次交换 6 for(int j = 0;j\u0026lt;n-1-i;j++){//每一次的交换（因为已经完成了i次交换） 7 if(a[j]\u0026gt;a[j+1]){//从小到大排序 8 swap(a[j],a[j+1]);//交换 9 } 10 } 11} 选择排序 # 核心思想：每次选择最大或最小的元素，将其排在正确位置。\n1using namespace std; 2int arr[n]; 3for(int i = 0;i\u0026lt;n-1;i++){//n个元素交换n-1次，这次寻找第i小的元素 4 int minindex = i;//假设当前i就是最小的索引 5 for(int j = i+1;j\u0026lt;n;j++){//在之后的索引，寻找更小的元素 6 if(arr[j]\u0026lt;arr[minindex]){ 7 minindex = j;//找到的话改变minindex 8 } 9 } 10 if(minindex!=i){//优化一下 11 swap(arr[i],arr[minindex]);//将第i小的元素放在相应位置 12 } 13} 插入排序 # 我认为相对选择排序和冒泡排序，插入排序较难理解嗯.\n核心思想：将一个元素按顺序插入到已经排好序的序列中！！\nSteps:\n你左手一开始是空的（已排序区）。\n你用右手从桌上（未排序区）拿起一张牌。\n将这张牌与左手中从右向左的牌依次比较，找到它应该插入的位置。\n将比它大的牌都向右挪一个位置，然后把它插入到空位。\n重复步骤2-4，直到所有牌都拿到左手。\nCode:\n1int a[n]; 2for(int i = 1;i\u0026lt;n;i++){//从1开始，默认第一个是排序好的 3 int key = a[i];//存储当前需要排序的元素 4 int j = i-1;//与其前面的元素一一比较 5 while(j\u0026gt;=0 \u0026amp;\u0026amp; a[j]\u0026gt;key){//只要j没有超出数组初始下标并且a[j]还是大于key 6 a[j+1] = a[j];//向右移动 7 j--;//比较下一个元素 8 } 9 //此时找到第一个小于等于key的元素下标 10 a[j+1] = key;//所以在那个元素的下一个地方插入key元素 11} Kadane最大子数组和 # 属于一种动态规划算法\n1int a[n]; 2for(int i = 0;i\u0026lt;n;i++){ 3 cin\u0026gt;\u0026gt;a[i];//初始化数组（包含负数） 4} 5int max_endhere = a[0]; 6int max_sum = a[0]; 7for(int i = 1;i\u0026lt;n;i++){ 8 max_endhere = max(a[i],max_endhere+a[i]);//精髓 9 //即，如果当前值a[i]比前面局部最大值加上当前值还要大 10 //则直接从当前值重新开始计算 11 max_sum = max(max_sum,max_endhere); 12} 13cout\u0026lt;\u0026lt;max_sum; 对于每个位置i，需要决定是继续扩展前面的子数组；\n还是从这里重新开始一个新的子数组！\nmax_endhere表示以元素a[i]结尾的子串中的最大字串和\n拓展：环形最大子数组和(最小值法)\n写成函数的形式（）嗯\n环形数组时，若最大子数组和是跨越首位的情况，用总和减去最小子数组和就是答案\n1int max_sub_sum_circular(int *nums,int nums_size){ 2 if(nums==NULL || nums_size==0)return 0; 3 int maxsum = nums[0]; 4 int max_endhere = nums[0]; 5 int minsum = nums[0]; 6 int min_endhere = nums[0]; 7 int total = nums[0]; 8 for(int i = 1;i\u0026lt;nums_size;i++){ 9 total += nums[i]; 10 max_endhere = max(nums[i],max_endhere+nums[i]); 11 min_endhere = min(nums[i],min_endhere+nums[i]); 12 maxsum = max(maxsum,max_endhere); 13 minsum = min(minsum,min_endhere); 14 } 15 if(maxsum\u0026lt;0){ 16 return maxsum;//必要的判断！防止数组全是负数时的bug 17 //全是负数时，总和-最小和=0，但是数组中子数组和此时不可能为0对吧！ 18 } 19 return max(maxsum,total-minsum); 20} LIS # (LIS指longest increasing subsequencec,即最大上升子序列)\n一.最大上升子序列(O(n^2))\n1int a[n];//初始化完一个随意的数字序列 2int lis[n];//表示以第i个元素作为LIS最后一个元素时，的最长序列长度 3int max_lis = 1;//全局最长LIS 4for(int i = 0;i\u0026lt;n;i++){ 5 lis[i] = 1;//长度包含自己 至少为1 6 for(int j = 0;j\u0026lt;i;j++){//每一个i，在i前逐一寻找 7 if(a[j]\u0026lt;a[i]){//指如果满足升序 8 lis[i] = max(lis[i],lis[j]+1); 9 } 10 } 11 max_lis = max(max_lis,lis[i]); 12} 13cout\u0026lt;\u0026lt;max_lis\u0026lt;\u0026lt;endl; 二.合唱队型（先升序后降序）\n策略是：单独求最大升序列和最大降序列\n1int tall[n];//初始化n个同学身高 2//最大升序 3int lis[n]; 4for(int i = 0;i\u0026lt;n;i++){ 5 lis[i] = 1; 6 for(int j = 0;j\u0026lt;i;j++){ 7 if(tall[j]\u0026lt;tall[i]){ 8 lis[i] = max(lis[i],lis[j]+1); 9 } 10 } 11} 12//最大降序 13int lds[n];//表示第i个作为LDS最前面的元素时，的最大降序列 14for(int i = n-1;i\u0026gt;=0;i--){ 15 lds[i] = 1; 16 for(int j = n-1;j\u0026gt;i;j--){ 17 if(tall[j]\u0026lt;tall[i]){ 18 lds[i] = max(lds[i],lds[j]+1); 19 } 20 } 21} 22//寻找最合适的“峰值”，LIS和LDS可以以此首位相接哦 23int max_len = 2; 24for(int i = 0;i\u0026lt;n;i++){//遍历所有可能的峰值 25 max_len = max(max_len,lis[i]+lds[i]-1); 26} 27cout\u0026lt;\u0026lt;n-max_len\u0026lt;\u0026lt;endl;//输出最少要抽出的人数 三.Dliworth theory：\n任意有限偏序集，最大反链的长度==最小正链划分数目\neg：一个随机序列a。最大升序子序列的长度，就等于下面问题的答案哦\u0026mdash;\u0026ndash;\u0026gt;\nQ:将全部元素划分为若干个降序列，最少需要划分为多少个？？\nLIS二分优化 # 如果只是求LIS的长度 这个方法O(n log n)比较适合\n核心是 用tail[k]数组维护 LIS长度为k时的结尾最小值(最优结尾值)\n1const int N = 1000005; 2int n; 3int a[N]; 4int tail[N]; 5//tail是递增的 因为len越长 最优结尾值一般也需要更大 6//也正因如此才能用二分查找 7cin\u0026gt;\u0026gt;n; 8for(int i = 0;i\u0026lt;n;i++){ 9 cin\u0026gt;\u0026gt;a[i]; 10 tail[i] = INT_MAX;//别忘了给tail初始化 11} 12int len = 0;//目前LIS的值 13for(int i = 0;i\u0026lt;n;i++){ 14 int x = a[i]; 15 int l = 0;int r = len-1; 16 while(l\u0026lt;=r){//在当前LIS范围内二分查找 17 int mid = (l+r)/2; 18 if(tail[mid]\u0026lt;x){//目标是在tail中找到第一个\u0026gt;=x的 19 //如果序列是非严格上升 改为tail[mid]\u0026lt;=x 20 l = mid+1; 21 }else{ 22 r = mid-1; 23 } 24 } 25 //二分结束后l就是第一个\u0026gt;=x的位置 26 tail[l] = x;//找到后更新 最后为每一个LIS长度找到相应的最优结尾 27 if(l==len)len++; 28} 29cout\u0026lt;\u0026lt;len\u0026lt;\u0026lt;endl; 二分可以用lower_bound,upper_bound等STL来写:\n本质和上面是一样的\n1int len = 0; 2for(int i = 0;i\u0026lt;n;i++){ 3 int x = a[i]; 4 int pos = lower_bound(tail,tail+len,x)-tail;//直接找到第一个\u0026gt;=x的位置 不需要手写二分 5 //注意lower_bound返回的是指针 最后要减去tail 指针相减 6 tail[pos] = x; 7 if(pos==len)len++; 8} 9cout\u0026lt;\u0026lt;len\u0026lt;\u0026lt;endl; 注意 此时若不是严格上升的 改成upper_bound就好了\n最后还有一种更好理解的写法:\n1int a[n]; 2vector\u0026lt;int\u0026gt; tail;//这里为空就好 3for(int i = 0;i\u0026lt;n;i++){ 4 cin\u0026gt;\u0026gt;a[i]; 5} 6for(int i = 0;i\u0026lt;n;i++){ 7 int x = a[i]; 8 auto pos = lower_bound(tail.begin(),tail.end(),x); 9 if(pos==tail.end()){//找不到就追加在已知LIS后面 10 tail.push_back(x); 11 }else{ 12 *pos = x;//找到就更新当前长度更优结尾值 13 } 14} 15cout\u0026lt;\u0026lt;tail.size()\u0026lt;\u0026lt;endl; 编辑距离 # A,B是两个字符串，有三种操作：\n1在A中插入一个字符\n2删除A中的一个字符\n3替换A中的一个字符\n将A字符串变成B字符串所需的最小操作次数，就是A，B的编辑距离\n基础代码实现：（二维数组版，比较好理解）\n1string a;string b; 2int lena = a.size();int lenb = b.size();//先确定两者长度 3vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; dp(lena+1.vector\u0026lt;int\u0026gt;(lenb+1,0)); 4//dp[i][j]表示将a的前i个字符（子字符1）转换为b的前j个字符（子字符2）所需的最少操作次数 5//最终得到的dp[lena][lenb]就是答案 6for(int j = 0;j\u0026lt;=lenb;j++){ 7 dp[0][j] = j;//若a为空字符串，就是要插入j次 8} 9for(int i = 0;i\u0026lt;=lena;i++){ 10 dp[i][0] = i;//若b是空字符串，就需要a删除i次 11} 12for(int i = 1;i\u0026lt;=lena;i++){ 13 for(int j = 1;j\u0026lt;=lenb;j++){//遍历所有子情况 14 if(a[i-1]==b[j-1]){//若两个字符串尾部相同 15 dp[i][j] = dp[i-1][j-1];//当前编辑距离就等于前一次的了哦（即分别去掉两个串相同的那个字符） 16 }else{ 17 dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+1);//在插入，替换，删除三种操作中取最小的 18 } 19 } 20} 21cout\u0026lt;\u0026lt;dp[lena][lenb]\u0026lt;\u0026lt;endl; 进阶代码（优化）：（一维数组版）\n写成函数形式，暂时理解不了就当黑盒先使用吧，最多也只能处理几千字符的文本\n1int EditDistance(string a,string b){ 2 int lena = a.size(); 3 int lenb = b.size(); 4 if(a==b)return 0; 5 if(lena\u0026gt;lenb){//确保a是较短的字符，节省空间 6 swap(a,b); 7 swap(lena,lenb); 8 } 9//dp[j]表示在当前行中，将a的前i个字符转换为b的前j个字符的编辑距离 10 vector\u0026lt;int\u0026gt; dp(lenb+1); 11//初始化第0行，表示空字符串转换为b的前j个字符的编辑距离 12 for(int j = 0;j\u0026lt;=lenb;j++){ 13 dp[j] = j; 14 } 15 for(int i = 1;i\u0026lt;=lena;i++){//表示a的前i个字符 16 //prev表示\u0026#34;上一行左边\u0026#34;，即dp[i-1][j-1] 17 int prev = dp[0]; 18 dp[0] = i;//表示i个字符的a转换为0个字符的b的编辑距离 19 for(int j = 1;j\u0026lt;=lenb;j++){ 20 int temp = dp[j];//保存i个字符的a转换为上一个j的distance，类比dp[i-1][j] 21 if(a[i-1]==b[j-1]){ 22 dp[j] = prev; 23 }else{ 24 dp[j] = min(min(dp[j]+1,dp[j-1]+1),prev+1);//dp[j-1]就类比二维时dp[i][j-1] 25 } 26 prev = temp; 27 } 28 } 29 return dp[lenb]; 30} 二分法查找 # 复杂度：nlog(n)?\n标准二分：用于查找有序序列中的某个target，（是一次查询） 1vector\u0026lt;int\u0026gt; arr; 2int left = 0;int right = arr.size(); 3while(left\u0026lt;=right){ 4 int mid = (left+right)/2; 5 if(arr[mid]==target)return mid;//找到就返回位置 6 if(arr[mid]\u0026lt;target){ 7 left = mid+1;//目标在右边就向右移动左边界 8 }else{ 9 right = mid-1;//反之向左移动右边界 10 } 11} 12return -1;//没找到就返回-1 一般来说，查找整数值时，可以用\n1while(left\u0026lt;=right){ 2 //... 3 if(check(mid)){ 4\tl = mid+1; 5\tans = mid; 6 }else{ 7\tr = mid-1; 8\t} 9} 但是对于浮点数来说，由于精度问题，一般用\n1for(int i = 0;i\u0026lt;100;i++){//不断迭代，控制精度 2 //... 3 if(check(mid)){ 4\tl = mid; 5\tans = mid; 6 }else{ 7\tr = mid;//注意 浮点数的时候不要写 8\t//mid+1或者mid-1 9\t//直接写mid就好 10 } 11} 与导弹例题结合，直接上例题：（对每个导弹多次查询） 由于题目的导弹数量n可能到达1e5，需要用二分法： 首先求最长不上升子序列：\n1int heights[n];//初始化所有导弹的高度； 2vector\u0026lt;int\u0026gt; tail1; 3//tail1[i]表示长度为i+1的不上升子序列的最后一个元素的最大值！ 4//因为若想让整个不上升子序列最长，末尾的元素要尽可能大，这样才可能在后面排更多元素 5//由tail1的定义可知，tail1本身是严格降序的 6for(int i = 0;i\u0026lt;n;i++){//对于heights中的每个元素 7 int left = 0; 8 int right = tail1.size(); 9 while(left\u0026lt;right){ 10 int mid = (left+right)/2;//在tail1中寻找第一个小于heights[i]的元素 11 if(tail1[mid]\u0026lt;heights[i]){ 12 //如果找到，那么再往tail1的左边再看看有没有更大的元素小于heights[i]，因为我们需要找的是第一个小于heights[i]的 13 right = mid; 14 }else{ 15 //如果没找到，往tail1右边更小的地方找 16 left = mid+1; 17 } 18 } 19 if(left==tail1.size()){//左边界到tail1最小值都仍没找到比heights[i]更小的 20 tail1.push_back(heights[i]);//直接附加在后面 21 }else{//若找到tail1中第一个比heights[i]小的元素 22 tail[left] = heights[i];//为了得到最长不上升子序列，让tail1中每一个元素更大！ 23 } 24} 25int max_lis = tail1.size();//得到最长不上升子序列 总结一下上面： 就是遍历heights的所有元素，根据条件，要么直接夹在tail1后面来延长序列，要么替换掉tail1中的元素使其能够在之后延申得更长.\ntail1最后的size就是所求序列的长度\n再依据Dliworth theory算最长上升子序列 1//把tail[mid]\u0026lt;heights[i]改成tail[mid]\u0026gt;=heights[i]即可 贪心 # 差分 # 差分可以先理解为前缀和的逆过程\n前缀和：给定数组a,需我们创建数组presum 其中presum[i]=a[1]+a[2]+..+a[i],用于计算区间和\n差分： 将给定的数组a视为一个presum,创建一个数组b 使得a[i]=b[1]+b[2]+..+b[i],数组b就是a的差分\n定义差分数组：\nchafen[i] = a[i]-a[i-1]\n应用：\n将对一个数组区间修改的操作，转化为对其差分数组两个单点的修改操作\neg：\n需要对数组a的区间[l.r]上的每一个元素都加上c\n1//进行两个单点操作即可 2chafen[l] = chafen[l]+c; 3chafen[r+1] = chafen[r+1]-c; 注意，修改后要对差分数组求一次前缀和，进行还原，作为新的修改后的数组a\n\u0026ldquo;实时\u0026quot;差分 # 传统差分VS实时差分:\n场景 传统差分 \u0026ldquo;实时\u0026quot;差分 需要全部结果 ✅适合 ❌浪费(只关心当前结果) 只需当前结果 ❌多余 ✅完美匹配 需要中途判断 ❌不方便 ✅实时可用 空间使用 需要结果数组 只需差分数组 适用场景：\n需从左到右顺序处理；\n当前影响后续；\n区间修改；\n可能提前结束；\n模板:\n1vector\u0026lt;int\u0026gt; diff(n+2);//差分数组空间稍微开大一点 2int current = 0;//当前累计值(实时值) 3for(int i = 1;i\u0026lt;=n;i++){//遍历每个位置 4 current += diff[i];//current作为全局变量，此时就是当前位置的值！ 5 //使用current作为当前位置的值，做相应判断和处理... 6 //... 7 diff[l] += val; 8 diff[r+1] -= val;//进行对应区间修改 9 if(对当前立即生效){ 10 current += val;//由于diff只对将来位置的值产生影响，有时需要给current也+val 11 } 12} eg:\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 int t; 5 cin\u0026gt;\u0026gt;t; 6 while(t--){ 7 int n,k; 8 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;k; 9 string s; 10 cin\u0026gt;\u0026gt;s; 11 vector\u0026lt;int\u0026gt; condition(n+1); 12 for(int i = 0;i\u0026lt;=n-1;i++){ 13 condition[i+1] = s[i]-\u0026#39;0\u0026#39;; 14 } 15 vector\u0026lt;int\u0026gt; cf(n+1,0);//差分数组 16 int flips = 0;//翻转次数 17 bool possible = true; 18 for(int i = 1;i\u0026lt;=n;i++){ 19 flips += cf[i];//此刻flips就是当前灯的对应累计翻转次数 20 int current = condition[i]^(flips%2);//初次接触位运算哈 21 if(current==1){ 22 if(i+k-1\u0026gt;n){//注意是i+k-1！！！ 23 possible = false; 24 break; 25 } 26 cf[i]++;//进行区间修改 27 if(i+k\u0026lt;=n){ 28 cf[i+k]--; 29 } 30 flips++;//当前结果立即生效 31 } 32 } 33 if(possible){ 34 cout\u0026lt;\u0026lt;1\u0026lt;\u0026lt;endl; 35 }else{ 36 cout\u0026lt;\u0026lt;0\u0026lt;\u0026lt;endl; 37 } 38 } 39 return 0; 40} 二维数组差分 # 标准模板：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 int n,m,q;//n*m的数组，q次操作 5 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m\u0026gt;\u0026gt;q; 6 //原数组 7 vector\u0026lt;vector\u0026lt;long long\u0026gt;\u0026gt; a(n+5,vector\u0026lt;long long\u0026gt;(m+5)); 8 for(int i = 1;i\u0026lt;=n;i++){ 9 for(int j = 1;j\u0026lt;=m;j++){ 10 cin\u0026gt;\u0026gt;a[i][j];//初始化原数组 11 } 12 } 13 //差分数组 14 vector\u0026lt;vector\u0026lt;long long\u0026gt;\u0026gt; di(n+5,vector\u0026lt;long long\u0026gt;(m+5,0)); 15 for(int i = 1;i\u0026lt;=n;i++){ 16 for(int j = 1;j\u0026lt;=m;j++){ 17 di[i][j] = a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];//初始化差分数组 18 } 19 } 20 while(q--){//进行q次操作 21 int x1,y1,x2,y2; 22 long long k; 23 cin\u0026gt;\u0026gt;x1\u0026gt;\u0026gt;y1\u0026gt;\u0026gt;x2\u0026gt;\u0026gt;y2\u0026gt;\u0026gt;k; 24 di[x1][y1]+=k; 25 di[x2+1][y1]-=k; 26 di[x1][y2+1]-=k; 27 di[x2+1][y2+1]+=k; 28 29 } 30 vector\u0026lt;vector\u0026lt;long long\u0026gt;\u0026gt; re(n+5,vector\u0026lt;long long\u0026gt;(m+5,0));//求一次前缀和，还原差分数组 31 for(int i = 1;i\u0026lt;=n;i++){ 32 for(int j = 1;j\u0026lt;=m;j++){ 33 re[i][j] = di[i][j]+re[i-1][j]+re[i][j-1]-re[i-1][j-1]; 34 } 35 } 36 for(int i = 1;i\u0026lt;=n;i++){ 37 for(int j = 1;j\u0026lt;=m;j++){ 38 cout\u0026lt;\u0026lt;re[i][j]\u0026lt;\u0026lt;\u0026#34; \u0026#34;;//输出操作后的新数组 39 } 40 cout\u0026lt;\u0026lt;endl; 41 } 42 return 0; 43} eg：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 int n,m; 5 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m; 6 //int gezi[n+5][n+5] = {0};//这个只会把第一行第一列初始化为0！！！ 7 vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; gezi(n+5,vector\u0026lt;int\u0026gt;(n+5,0)); 8 for(int i = 0;i\u0026lt;m;i++){//直接将gezi数组视为其自身的差分数组，进行处理 9 int x1,y1,x2,y2; 10 cin\u0026gt;\u0026gt;x1\u0026gt;\u0026gt;y1\u0026gt;\u0026gt;x2\u0026gt;\u0026gt;y2; 11 gezi[x1][y1]++;//*** 12 gezi[x1][y2+1]--;//*** 13 gezi[x2+1][y1]--;//*** 14 gezi[x2+1][y2+1]++;//二维差分的处理 15 } 16 vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; presum(n+5,vector\u0026lt;int\u0026gt;(n+5,0));//进行还原，计算差分数组的前缀和 17 for(int i = 1;i\u0026lt;=n;i++){ 18 for(int j = 1;j\u0026lt;=n;j++){ 19 presum[i][j] = gezi[i][j]+presum[i-1][j]+presum[i][j-1]-presum[i-1][j-1]; 20 } 21 } 22 for(int i = 1;i\u0026lt;=n;i++){ 23 for(int j = 1;j\u0026lt;=n;j++){ 24 cout\u0026lt;\u0026lt;presum[i][j]\u0026lt;\u0026lt;\u0026#34; \u0026#34;; 25 } 26 cout\u0026lt;\u0026lt;endl; 27 } 28 return 0; 29} 细节注意二维数组的初始化哦~\n由于gezi数组初始化全为0，因此不必定义创建差分数组，其本身就可以视为其自身的差分数组\nDFS深度优先搜索 # (Depth-first search)\n回溯算法普通模板：\n1return_type dfs(参数){ 2 //终止条件 3 if(达到终止条件){ 4 处理结果; 5 return 对应结果; 6 } 7 //遍历所有选择 8 for(每个可能的选择){ 9 //做出选择 10 标记状态改变； 11 //递归进入下一层 12 dfs(新的参数); 13 //回溯到之前的状态，来进行其他选择 14 恢复状态; 15 } 16 return 对应结果; 17} eg：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3const int dx[3] = {0,1,-1}; 4const int dy[3] = {1,0,0};//每次可以向上，左，右走一步，此为对应坐标的增加值 5int dfs(int x,int y,int step,int n,vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; visited,int offset){//step表示已经走过的步数，若达到n，dfs就结束了 6//visited前加\u0026#34;\u0026amp;\u0026#34;是因为要在函数内部改变实际的visited的值，要引用一下 7 if(step==n){ 8 return 1;//走到头，记为1种方法 9 } 10 int total = 0; 11 for(int i = 0;i\u0026lt;3;i++){//每次都有三种选择，进行遍历 12 int nx = x+dx[i]; 13 int ny = y+dy[i];//更新进行当前选择后的新坐标 14 if(nx\u0026lt;-n || nx\u0026gt;n || ny\u0026lt;0 || ny\u0026gt;n){ 15 continue;//如果超出边界，跳过并进行下一个选择 16 } 17 if(visited[nx+offset][ny]){ 18 continue;//如果新坐标是塌陷的，不能走，跳过并进行下一个选择 19 } 20 visited[nx+offset][ny] = true;//将能走到的新坐标标记为塌陷，下次不能走了 21 total += dfs(nx,ny,step+1,n,visited,offset);//以这个选择为基点，递归累加所有走法 22 visited[nx+offset][ny] = false;//回溯到基点前的状态，搜索其他选择是否可行 23 } 24 return total; 25} 26int main(){ 27 int n; 28 cin\u0026gt;\u0026gt;n; 29 int offset = n;//偏移法 30 vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; visited(2*n+1,vector\u0026lt;int\u0026gt;(n+1,false));//由于有负数横坐标 31 //利用offset做一个偏移，即将0+offset视为原点，0视为最左边的点 32 visited[0+offset][0] = true;//起始点直接标记为已经走过的状态 33 int result = dfs(0,0,0,n,visited,offset); 34 cout\u0026lt;\u0026lt;result\u0026lt;\u0026lt;endl; 35 return 0; 36} 虽说方格无限大，但是能走的步数是有限的，那么最大方格其实也就确定为有限的了.\n快速幂 # 用来计算类似3^100000000000这种东西\n把3*3*3*3*3.....*3转变成9*9*9*9..9\u0026hellip;..\n总之就是把乘法任务两两打包，指数级减少操作次数\n核心思想：\n能把底数价值翻倍打包就一直先打包（来降低指数次数）\n直到指数变为奇数，就将翻倍后的新底数乘上result\n1long long fastpower(long long base,long long exponent){ 2 //base,exponent分别表示底数和指数 3 long long result = 1; 4 while(exponent\u0026gt;0){ 5 if(exponent%2==1){//不能再直接打包了 6 result *= base;//若指数是奇数就先单独乘上一个底数 7 } 8 base = base*base;//把底数两两打包,能打包就一直打包 9 exponent = exponent/2;//因此指数也要减半 10 } 11 return result; 12} 埃式筛(素数) # 筛到一个素数，那它的倍数就全部都是合数\n筛到合数，直接continue跳过进行下一轮\n1const int n = 1000000;//测试数据范围 2bool st[n+1];//标记每个数，false为素数，true为合数 3vector\u0026lt;int\u0026gt; primes;//存储所有素数 4fill(st,st+n+1,false);//初始全为素数 5for(int i = 2;i\u0026lt;=n;i++){ 6 if(st[i]){ 7 continue; 8 } 9 primes.push_back(i);//不是合数就插入素数里了 10 if((long long)i*i\u0026gt;n)continue;//用ll防止溢出 11 for(long long j = (long long)i*i;j\u0026lt;=n;j += i){ 12 st[j] = true;//该素数的倍数均为合数 13 } 14} 若追求极致高效，可以只处理奇数，因为偶数除了2都不是素数;\n欧拉筛(线性筛) # 基于埃式筛 发现有些合数会被它的不同因子筛去多次\n因此还有优化空间\n让每个合数只被它最小的因数筛去\n达到线性的复杂度\n1vector\u0026lt;int\u0026gt; primes; 2bool st[N];//false为素数 true为合数 3fill(st,st+n+1,false);//初始话全部标记素数 4for(int i = 2;i\u0026lt;=n;i++){ 5 if(st[i])continue; 6 primes.push_back(i); 7 for(auto x:primes){//枚举已经筛出的素数 8 if(i*x\u0026gt;n)break;//超出范围就终止 9 st[i*x] = true;//素数的倍数标记为合数 10 if(i%x==0)break;//代码核心 保证线性性质 11 } 12} 关于i%x==0:\n因为是从小到大枚举所有已经筛出的素数x;\n当i%x=0的时候 x就是最小质因子 此时break就好了;\n区间筛 # 适合找区间[l,r]之间的所有素数\n其中l，r很大 但区间范围其实并不大\n逆康托展开 # 这里用求第m小的排列为例子;\n由不重复的数字1-n组成的所有排列中，按字典序从小到大求出第m小的排列:\n以1,2,3,4组成的排列为例 (字典序)\n1开头的排列\u0026ndash;\u0026gt;(4-1)!=6种 |(小)\n2开头的排列\u0026ndash;\u0026gt;(4-1)!=6种 |\n3开头的排列\u0026ndash;\u0026gt;(4-1)!=6种 |\n4开头的排列\u0026ndash;\u0026gt;(4-1)!=6种 |(大)\nthen，比如求第9小的排列，先转换为0-based=\u0026gt;9-1=8;\n8/6=1:该排列在第2组,也就是一个2开头的排列;\n8%6=2,该排列在2开头的排列中的第2小\n(以此类推递归)\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3#define ll long long 4vector\u0026lt;int\u0026gt; get_permutation(int n,int m){ 5 //预先做一个1-n排列的可用数字 6 vector\u0026lt;int\u0026gt; nums; 7 for(int i = 1;i\u0026lt;=n;i++){//注意索引是从0开始 8 nums.push_back(i); 9 } 10 ll k = m-1;//因此要转换成0-based 11 vector\u0026lt;int\u0026gt; ans;//到时候用来存储结果 12 //接下来从第一位开始,确定排列的每一位 13 for(int i = n;i\u0026gt;=1;i--){ 14 //每确定一个数之前,单独确定阶乘结果(如果直接计算所有阶乘会溢出的) 15 ll fact = 1; 16 bool overflow = false; 17 for(int j = 1;j\u0026lt;=i-1;j++){//计算该位的阶乘 18 if(fact\u0026gt;k/j){//判断是否\u0026#34;溢出\u0026#34;，等价于fact*j\u0026gt;k 19 overflow = true; 20 break; 21 } 22 fact = fact*j; 23 } 24 if(overflow){ 25 ans.push_back(nums[0]);//fact\u0026gt;k,则idx=k/fact=0 26 nums.erase(nums.begin());//去掉当前数组及其索引 27 //确定第一个数字的时候索引和值相等,后续的话,表示的是当下第几小的数 28 }else{ 29 ans.push_back(nums[k/fact]); 30 nums.erase(nums.begin()+k/fact); 31 k %= fact; //更新k 32 } 33 } 34 return ans; 35} 36int main(){ 37 ll n,m; 38 while(cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m){ 39 vector\u0026lt;int\u0026gt; result = get_permutation(n,m); 40 int len = result.size(); 41 for(int i = 0;i\u0026lt;len;i++){ 42 cout\u0026lt;\u0026lt;result[i]; 43 if(i!=len-1){ 44 cout\u0026lt;\u0026lt;\u0026#34; \u0026#34;; 45 } 46 } 47 cout\u0026lt;\u0026lt;\u0026#39;\\n\u0026#39;; 48 } 49 return 0; 50} 计算机一般都是从0开始的,理解不了就记住一般都要转换为0-based\n排序+去重 # 方法一:利用set(边读入边处理)\n1set\u0026lt;int\u0026gt; b;//先创建一个集合 2for(int i = 0;i\u0026lt;n;i++){ 3 int x;cin\u0026gt;\u0026gt;x; 4 b.insert(x); 5} 6vector\u0026lt;int\u0026gt; a(b.begin(),b.end());//这样,a就是一个排序且去重的数组了 方法二:利用unique函数(适合已经有vector的情况)\n1sort(a.begin(),a.end());//先排好序 2a.erase(unique(a.begin(),a.end()),a.end());//再利用unique,并结合erase完成去重 3//此时vector\u0026lt;int\u0026gt; a就完成去重和排序了 \u0026laquo;语法\u0026raquo; # 位运算 # 优先级最低,建议加括号;\n左移:x\u0026lt;\u0026lt;k = x*(2^k);\n右移:x\u0026gt;\u0026gt;k = x/(2^k);(向下取整,取不大于结果的最大整数)\n异或 # 先将数值转换为二进制\n然后对每一位进行异或\n相同为0\n不同为1\n异或符号^是可以直接使用的 不需要自己实现\n1^1=0\n0^0=0\n1^0=1\n性质:\na^b=b^a;(交换律)\n(a^b)^c=a^(b^c);(结合律)\na^b^b=a^(b^b)=a^0=a;(与0异或 结果等于本身)\n应用:\n变量交换 1a=3;b=4; 2a=a^b; 3b=a^b; 4a=a^b; 5cout\u0026lt;\u0026lt;a\u0026lt;\u0026lt;b\u0026lt;\u0026lt;endl; 排除偶次重复 在一个整数数组中 只有一个不重复的数字 其余均出现偶数次 找出不重复的那个数字\n1int ans = 0; 2for(int i = 0;i\u0026lt;arr.size();i++){ 3 ans ^= arr[i];//偶数次的都会被抵消完 ans保持为0 4 //直到遇到不重复的数字 ans保持那个不重复的数 5} 6return ans; cin\u0026amp;cout # 1.输入cin：\n混合输入字符串和数字要注意ignore缓冲区：\n1int a; 2string str; 3cin\u0026gt;\u0026gt;a; 4cin.ignore.();//清空缓冲区，否则无法正常使用getline 5getline(cin,str); 6//注意，cin中不能使用endl换行符； 2.输出cout:\n1int a; 2cin\u0026gt;\u0026gt;a; 3cout\u0026lt;\u0026lt;a; 4int s[n]; 5for(int i = 0;i\u0026lt;n;i++){//在需要高性能的环境中 6 //cout\u0026lt;\u0026lt;s[i]\u0026lt;\u0026lt;endl; 7 cout\u0026lt;\u0026lt;s[i]\u0026lt;\u0026lt;\u0026#39;\\n\u0026#39;;//是循环中更好的换行方式 8} 3.关闭输入输出同步流，提升程序效率\n1ios::sync_with_stdio(false); 2cin.tie(0); 3cout.tie(0); 4.输出小数\n1cout\u0026lt;\u0026lt;fixed\u0026lt;\u0026lt;setprecision(n)\u0026lt;\u0026lt;double_num\u0026lt;\u0026lt;endl;//保留n位小数 类型转换 # 首先方便起见，初学使用using namespace std;\n1//字符串--\u0026gt;数值 2string str = \u0026#34;123\u0026#34;; 3int num1 = stoi(str); 4double num2 = stod(str); 5float num3 = stof(str); 6long long num4 = stoll(str); 7//数值--\u0026gt;字符串 8string str1 = to_string(num1); 注意stoi()这种的参数需要是字符串,不能直接转换单个字符哦.\n对于单个字符的情况：\n1int num = str.back()-\u0026#39;0\u0026#39;;//也能完成对最后一个元素的转换 数学函数 # 数学函数 库中对应函数语法 f(x)=lnx log(x) f(x)=lgx log10(x) f(x)=|x|(int,double) abs(x),fabs(x) f(x)=向下取整 floor(x) f(x)=向上取整 ceil(x) f(x)=$\\sqrt(x)$ sqrt(x) 取大 max(a,b) 取小 min(a,b) 注意：三角函数在库中都以弧度制表示，即传入的参数应该是$\\pi$ 之类的，而不是180°之类的。\n++i\u0026amp;i++的区别 # 注：理解两者的区别对于提高代码效率非常重要！！！\n1.++i：\n先将i的值加一，再返回i.\n2.i++:\n先返回i本身的值，再将i加一.\n\u0026rdquo;\u0026amp;\u0026ldquo;引用 # 引入一个重要的符号：\u0026amp;\n在c++中，\u0026amp;除了有取地址的作用外，还可以表示引用！\n1//\u0026amp;表示引用的基本含义 2//\u0026amp;引用的本质就是给变量取别名 3int a = 10; 4int \u0026amp;b = a;// b是a的引用（别名） 5b = 20;// 现在a也变成了20 6cout \u0026lt;\u0026lt; a;// 输出20 主要用于函数的参数部分：\n1//一.要通过函数修改外部变量 2void func(变量类型 \u0026amp;变量名){}//类似*，但更方便 3//二.不修改外部变量且是简单类型，不考虑性能 4void func(变量类型 变量名){} 5//三.不修改外部变量，但数据类型大，性能要求高 6void func(const 变量类型 \u0026amp;变量名){}//能避免拷贝 总之，\n问自己：我需要修改这个参数吗？\n要修改 → 用 \u0026amp;\n不修改 → 继续问：这个参数大吗？\n大（结构体、字符串、数组）→ 用 const \u0026amp;\n小（int、double、char）→ 什么都不加\nfgets(c语言) # struct结构体 # 是一种自定义数据类型\n基本结构：将多个不同类型变量组合在一起，形成一个逻辑上的整体\n1// 定义结构体 2struct Student {//定义Student是一种数据类型！！ 3 string name;// 姓名 4 int age;// 年龄 5 double score;// 分数 6};//别忘了有分号！！！ 然后，可以在主函数中使用Student这个数据类型\n例如Student Xiaoming;\n那么如何访问一个结构体中的各个成员？\n答案是用“.”来访问.\n1Student Xiaoming; 2Xiaoming.name = Xiaoming; 3Xiaoming.age = 18; 4Xiaoming.score = 100.0; 当然也可以直接按结构体内的顺序初始化：\n1Student a = {Xiaoming,18,100.0}; 或指定成员初始化：\n1Student a = {.name = Xiaoming,.age = 18,.score = 100.0}; bitset # 可以看为更省内存的bool数组 值为0或1\n局限是 编译时大小必须是常量 可以预先开好足够空间\n1bitset\u0026lt;100\u0026gt; b1;//大小为100的bitset 默认值全为0 2b1.set();//将其全部设为1 3b1.reset();//全部设为0 4b1.flip();//0变成1 1变成0 5//括号内加数字i的话 就是对第i位进行相应操作 6b1.count();//返回1的个数 7b1.test(i);//测试第i位是否为1 会检查越界 返回是bool值 fill,memset函数 # memset一般只用于C风格数组或者结构体,或者通过new的动态数组;\nfill可用于STL;\n但两者都不能用于bitset;\n1fill(起始迭代器，结束迭代器，填充值)； 即不管序列原来每个元素的值是多少，fill函数能够将范围内的所有元素值都一律变为填充值.\n1fill(arr.begin(),arr.end(),10);//将arr全部变为10 memset主要用于快速清空或初始化很大的内存空间,比较高效.\n1memmset(需要填充的内存块的指针,int ch,要设置的字节数); 2memset(arr,0,sizeof(arr));//数值全变为0 3memset(str,0,sizeof(str));//字符串全变为空!!! 4memset(str,\u0026#39;a\u0026#39;,sizeof(str));//字符串全变为字符a 5memset(flags,true,sizeof(flags));//布尔值全变为true 6//注意，对于数值型，只能修改为0或-1！！！！ lower_bound/upper_bound函数 # 使用前记得先将范围序列排序哦\n1sort(arr,arr+n); 这两个函数是基于二分的思想写的，可以直接调用\n用于查找序列中的值，区间依旧左闭右开哦\nlower_bound(arr,arr+n,value);返回第一个大于等于value元素的位置;\nupper_bound(arr,arr+n,value);返回第一个大于value元素的位置;\n若找不到，都会返回last这个位置（last是序列最后一个元素的再下一个位置）\n1int a[n];//初始化省略了 2sort(a,a+n);//记住一定要先排序 3auto left = lower_bound(a,a+n,1);//auto可以自动判断表达式的类型哦，此处即为指针类型了 4auto right = upper_bound(a,a+n,1); 5int cnt = right-left;//统计1在a中出现次数 1auto left = lower_bound(a,a+n,1); 2int index = left-a;//获取第一个元素1的具体索引(指针相减) 3int value = *left;//获取指针所指的值 sort函数(c++) # 基本形式：\n1// 基本形式1：使用默认的升序排序 2sort(first, last); 3//更通用的形式：比较函数： 4sort(first,last,cmp); first表示要排序的范围的开始位置，end则是结束位置，区间可理解为左闭右开.\n基本语法\u0026amp;示例：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int a[n]; 4for(int i = 0;i\u0026lt;n;i++){ 5 cin\u0026gt;\u0026gt;a[i];//初始化一个数组，对数组中的元素进行排序 6} 7sort(a,a+n);//升序排列 8//如果是vector 9sort(a.begin(),a.end()); 10//由于要一直排序到索引为n-1的元素，且左闭右开，因此写结束位置为(n-1)+1---\u0026gt;n！ 11return a\u0026lt;b;//升序 12} 降序排序比较器greater\u0026lt;\u0026gt;()\n1#include\u0026lt;functional\u0026gt; 2sort(a,a+n,greater\u0026lt;数组值类型\u0026gt;());//这样就会降序排序 部分排序nth_element\n1nth_element(a,a+k,a+n);//升序，挑出a中前k小的元素 2nth_element(a,a+k,a+n,greater\u0026lt;\u0026gt;());//降序，挑出a中前k大的元素 比较函数：(与c的qsort原理不同)\nbool返回true，sort函数会将参数a排在参数b前面;\n反之bool若返回false则会把参数a排在参数b后面;\n1bool cmp(int a,int b){ 2 return a\u0026lt;b;//升序 3} 4 5bool cmp1(int a,int b){ 6 return a\u0026gt;b;//降序 7} 复杂度：n*log(n);\nswap(交换函数) # 基本语法\u0026amp;示例：\n1#include \u0026lt;bits.stdc++.h\u0026gt;//万能头文件 2using namespace std;//要用swap的话一定要写std库！！ 3 4int x = 5, y = 10; 5swap(x, y);//交换基本类型 6------------------------------ 7string s1 = \u0026#34;Hello\u0026#34;, s2 = \u0026#34;World\u0026#34;; 8swap(s1, s2);//交换字符串 9------------------------------ 10int arr[] = {1,2,3,4,5}; 11swap(arr[0], arr[4]);// 交换第一个和最后一个元素 getline(c++) # 只适用于string类型!主要用于读取需要包括空格的文本.\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3string names; 4getline(cin,names);//基本格式，能读取空格，默认读到换行符为止！！ 自定义分隔符（类似scanf的扫描集）\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3string data; 4getline(cin,data,\u0026#39;,\u0026#39;);//读到逗号为止 cin.ignore()清空混合输入缓冲区.eg:\n1int num; 2string text; 3cin\u0026gt;\u0026gt;num; 4cin.ignora();//必须调用，清除缓冲区的换行符 5getline(cin,text); set容器(c++) # 介绍：\nset是一个有序的关联容器，包含唯一键(元素不允许重复)的集合\n特性：\n元素唯一性；自动排序(升序)；不可修改元素(均为const)；查找效率高(logn)\n用法：\n1set\u0026lt;变量类型\u0026gt; 变量名； 2//eg: 3set\u0026lt;int\u0026gt; myset; 4myset.insert(1); 5myset.insert(2); 6myset.insert(3); 7myset.insert(1);//因为1已经有了，这个1就无效了 8//可用于统计集合的实际元素个数 9int len = myset.size(); 10myset.erase(x)//删除值为x的元素 11myset.find(x)//查找是否存在x元素，返回相应迭代器 12cout\u0026lt;\u0026lt;*myset.begin()\u0026lt;\u0026lt;\u0026#39;\\n\u0026#39;;//输出第一个元素(最小) 13cout\u0026lt;\u0026lt;*myset.rbegin()\u0026lt;\u0026lt;\u0026#39;\\n\u0026#39;;//输出最后一个元素(最大) 1//利用其自动升序排序的原理，我们可以用set同时完成去重和排序！！！ 2set\u0026lt;type\u0026gt; setname(iterator first,iterator last); 3//这个构造函数会遍历[first,last)的所有元素并插入到set中 string(c++) # string是一个封装了字符数组的类，自动管理内存。专门存放字符序列. string类型的变量，下标索引也是从0开始。\n首先注意string和普通数组a[n]的区别：\n空的string最好使用+=或.push_back()来添加元素;\n若想如a[n]一样通过for循环用a[i]赋值，则需要先resize()!!!!\n特性1：变量之间可以直接相加+，自动管理内存哦！ 1string s1 = \u0026#34;Hello\u0026#34;; 2string s2 = \u0026#34;World\u0026#34;; 3string s3 = s1 + \u0026#34; \u0026#34; + s2;//直接使用+运算符，也可以用于循环不断增加！ 特性2：初始化较便利 1string s1 = \u0026#34;Hello\u0026#34;;//C风格字符串字面量 2string s2 = \u0026#39;A\u0026#39;;//错误！不能直接存放单个字符 3string s3(1,\u0026#39;A\u0026#39;);//正确！创建包含1个字符\u0026#39;A\u0026#39;的字符串 4string s3 = \u0026#34;A\u0026#34;;//但可以用字符串字面量 5string s4 = \u0026#34;中文\u0026#34;;//可以存放中文字符（在合适的编码下） 6string s5 = \u0026#34;Hello\\x20World\u0026#34;;//可以包含转义字符 7string s6 = \u0026#34;\u0026#34;; //空字符串 （但注意，（1）string类型也是不能由cin直接输入空格和换行符的！！！需要使用一个getline()哦（2）混合输入时，要在合适位置使用cin.ignore()清空缓冲区）\n特性3：运算符重载，可直接比较字典序大小 1string s1 = \u0026#34;hello\u0026#34;; 2string s2 = \u0026#34;world\u0026#34;; 3if(s1\u0026gt;s2){ 4 //..... 5} 特性4：丰富的成员函数(下面不是所有的哦) 1string str = \u0026#34;Hello World\u0026#34;; 2 3int len = str.size();//len = 11 4cout\u0026lt;\u0026lt;str.find(\u0026#34;World\u0026#34;);//---\u0026gt;6 5str.push_back(\u0026#39;!\u0026#39;);//str = \u0026#34;Hello World!\u0026#34;,用于添加单个字符 6str.pop_back();//删除最后一个字符 7str.append(\u0026#34; world\u0026#34;);//功能更强大，可追加多字符 8str.append(100,\u0026#39;!\u0026#39;);//添加100个感叹号哦 9 10str.front();//访问第一个元素 11str.back();//访问最后一个元素 12str.find_first_of(\u0026#34;aeiou\u0026#34;);//查找第一个出现的元音字母的索引位置 13str.find_last_of(\u0026#34;aeiou\u0026#34;);//查找最后一个出现的元音字母的索引位置 14str.empty();//检查字符串是否为空，空返回true，非空false 15cout\u0026lt;\u0026lt;str.substr(提取的起始索引位置，提取字符数量)；//若提取数量不写，则默认提取到末尾哦 16string str1(str);//将str的内容拷贝到新创建的str1 17 18str.clear()//清空 19str.erase(n,m)//删除从索引为n开始，往后共m个字符 20str.erase(str.begin()+1);//删除单个字符 21str.erase(str.begin()+2,str.begin()+5)//删除一个范围 22 23reverse(str.begin(),str.end());//反转字符串 24str.replace(起始索引，需替换长度，\u0026#34;新内容\u0026#34;)；//新字符串长度可不同 25 26str.reserve(n)//不改变字符串大小，只分配内存容量 27str.resize(n)//分配空间的同时也改变字符串大小 注意： .end()和.begin()是一对：\n表示指向最后一个元素的下一个位置，和指向第一个元素\n.front()和.back()是一对：\n表示第一个和最后一个元素，可直接引用\nmap(c++) # 对插入的键值对自动按键升序排序\n1#include\u0026lt;map\u0026gt; 2map\u0026lt;键类型,值类型\u0026gt; 变量名; 3//添加键值对 4map\u0026lt;int,string\u0026gt; student; 5student[1] = \u0026#34;jaychou\u0026#34;; 6student.insert({2,\u0026#34;neyo\u0026#34;}); 7//查找访问 8//find():若查找发现有这个键，it就是指向该元素的迭代器 9//如果没找到,it会指向.end() 10auto it = student.find(键); 11if(it!=student.end()){ 12 cout\u0026lt;\u0026lt;it-\u0026gt;second;//输出对应值 13} 14//删除元素 15//erase()会将这整个键值对都删掉 16student.erase(键); 利用迭代器遍历map中的键值对: 因为不一定知道起始的键 也不知道键之间的间隔 也不知道末尾的键\n1for(auto it = m.begin(),it!=m.end(),it++){ 2 cout\u0026lt;\u0026lt;it-\u0026gt;first\u0026lt;\u0026lt;\u0026#34; \u0026#34;\u0026lt;\u0026lt;it-\u0026gt;second;//不是成对的值,而是单个值的时候,需要用*it 3} 4//这里it是迭代器 要用-\u0026gt;来表示具体的键和值 5for(const auto\u0026amp; item:m){//总之就是for(const auto\u0026amp; it:container)来遍历 6 cout\u0026lt;\u0026lt;item.first\u0026lt;\u0026lt;\u0026#34; \u0026#34;\u0026lt;\u0026lt;item.second; 7} 8//这里item是一个值,用.来表示具体的键和值 值要用. 迭代器要用-\u0026gt;\n补充：对于频率统计的问题,map和unordered_map都可以直接m[键]++,都会自动初始化该键的值为0;\nunordered_map # 一.语法：\nunordered_map\u0026lt;键类型，值类型\u0026gt; 变量名;\neg:\n1//基本初始化 2unordered_map\u0026lt;int,string\u0026gt; student_id;// 学号→姓名 3unordered_map\u0026lt;string,double\u0026gt; product_price;//产品名→价格 4unordered_map\u0026lt;ll,ll\u0026gt; freq;// 数值→出现次数 5//插入键值对 6scores[\u0026#34;Alice\u0026#34;] = 100;//Alice为键，100为其对应的值 7scores.insert({\u0026#34;Bob\u0026#34;,60});//插入一个键值对 8//访问元素 9cout\u0026lt;\u0026lt;scores[\u0026#34;Alice\u0026#34;];//输出的是100 10cout\u0026lt;\u0026lt;scores[\u0026#34;David\u0026#34;];//自动创建{\u0026#34;David\u0026#34;:0}并输出0 1//函数 2if(scores.count(\u0026#34;Alice\u0026#34;)){ 3 //键存在 4} 5scores.erase(\u0026#34;Alice\u0026#34;);//删除键为Alice的元素 二.特性：\n1.无序性。\n相对map来说，map是有序的键值对，但访问速度没有哈希表快速。元素的存储顺序与插入顺序无关，遍历时顺序也不确定。\n2.自动初始化。\neg：\n1unordered_map\u0026lt;int,int\u0026gt; m; 2cout\u0026lt;\u0026lt;m[5];//输出0,同时自动创建{5:0} 即，即使哈希表的一些键值对还没有被初始化时，此时若直接输出或者访问某个键，会自动创建键值对，并初始化键的值为0。\n三.用法：\n1.统计频率等\npair(c++) # 作用： 可以把两个值打包成一个对象（一个变量名，类似成为一个组合），两个值可以是不同的数据类型\n1pair\u0026lt;类型1，类型2\u0026gt; 变量名； 用法：\n1//方式1:先声明后赋值 2pair\u0026lt;string,int\u0026gt; p1; 3p1.first = \u0026#34;Bob\u0026#34;;//这里first，second是pair专用的访问元素方法 4p1.second = 80; 5// 方式2:声明时直接初始化 6pair\u0026lt;string,int\u0026gt; p2(\u0026#34;Cathy\u0026#34;, 88); 7//方式3:表达一系列pair对，例如n个学生的姓名以及对应成绩 8vector\u0026lt;pair\u0026lt;string,int\u0026gt;\u0026gt; student(n); 9for(int i = 0;i\u0026lt;n;i++){ 10 cin\u0026gt;\u0026gt;student[i].first\u0026gt;\u0026gt;student[i].second;//对其进行输入 11} 12//方式4:初始化pair序列 13vector\u0026lt;pair\u0026lt;int,int\u0026gt;\u0026gt; biggest(m,{0,0});//表示有m个{0，0}对序列 priority_queue # 一种能够随时插入新数据，并且随时知道最大值或者最小值，并且随时删除当下最大值或最小值的容器(优先队列)\n大顶堆(默认):priority_queue\u0026lt;int\u0026gt; pq;(获取,删除最大值)\n小顶堆:priority_queue\u0026lt;int,vector\u0026lt;int\u0026gt;,greater\u0026lt;int\u0026gt;\u0026gt; pq;(获取,删除最小值)\n常用方法:\n1int value = pq.top();//获取最大/小值 2pq.pop();//删除最大/小值 3pq.push(x);//插入新的值x stack栈 # 像一个只有一个开口的管道， 只能从顶部存入或者取出东西, 先进后出\n1#include \u0026lt;stack\u0026gt; 2stack\u0026lt;int\u0026gt; s; 3//新添加的元素始终在栈顶 4s.push(1);//[1] 5s.push(2);//[1,2] 6s.push(3);//[1,2,3] 7int x = s.top();//x=3 8//只能从栈顶逐个删除元素 9s.pop();//[1,2] queue队列 # 像一个有上下开口的管道, 先存入的元素会先出来 先进先出\n1queue\u0026lt;int\u0026gt; q; 2q.push(1);//[1] 3q.push(2);//[1,2] 4q.push(3);//[1,2,3] 5int x = q.front();//x=1 6int y = q.back();//y=3 7//弹出最先插入的元素 8q.pop();//[2,3] \u0026laquo;细节问题\u0026raquo; # 字符串需主动添加\u0026rsquo;\\0\u0026rsquo;(NULL)的情况 # (1)使用循环对逐个字符赋值，构造字符串时：\n1char dest[10]; 2for(int i=0; i\u0026lt;3; i++) { 3 dest[i] = source[i]; 4} 5dest[3] = \u0026#39;\\0\u0026#39;; // 必须手动添加**** (2)手动逐个字符赋值，构造字符串时：\n1char str[10]; 2str[0] = \u0026#39;H\u0026#39;; 3str[1] = \u0026#39;i\u0026#39;; 4str[2] = \u0026#39;\\0\u0026#39;; // 必须手动添加**** (3)使用非字符串函数操作时：\n1char str[10]; 2memcpy(str, \u0026#34;Hello\u0026#34;, 5); // 只复制5个字符，不包括\\0 3str[5] = \u0026#39;\\0\u0026#39;; // 必须手动添加**** 二维数组的初始化 # 目标：初始化a[n][n]的每个元素都为0\n错误示例：\n1int a[n][n] = {0};//这样只会让第一行第一列为0 正确示例：\n1int a[n][n]; 2for(int i = 0;i\u0026lt;n;i++){ 3 for(int j = 0;j\u0026lt;n;j++){ 4 a[i][j] = 0; 5 } 6} 1//或者使用vector 2vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; a(n,vector\u0026lt;int\u0026gt;(n,0)); 栈溢出 # 在oj或者算法竞赛上，数组在合适情况下就开在全局，或者使用vector;防止发生栈溢出(但实际开发中一般不推荐使用)\n1const int MAXN = 200005; 2long long len[MAXN];//开在全局 3int main(){ 4 //... 5 int n; 6 cin\u0026gt;\u0026gt;n; 7 vector\u0026lt;long long\u0026gt; len1(n);//或者使用vector 8} vector # 1vector\u0026lt;int\u0026gt; graph[N];//写图论题的时候,这样写表示N个vector\u0026lt;int\u0026gt; 2vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; graph(N);//上面的写法更好 vector\u0026lt;\u0026gt;是一种数据结构，用[]就表示vector\u0026lt;\u0026gt;这种类型的数组; 用()就表示vector的一种构造元素个数的函数\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/basic-cpp/algo-notes/","section":"学习笔记","summary":"C++/C算法n0t3 # «算法» # qsort快排(c语言) # 1.qsort函数原型\n1void qsort(void *base, size_t nmemb, size_t size, 2 int (*compar)(const void *, const void *)); 2.具体写法 （1）先写比较函数 （返回的是整形）\n1// 升序排序（从小到大） 2int cmp_asc(const void *a, const void *b) { 3 return (*(int*)a - *(int*)b); 4} 5// 降序排序 （从大到小） 6int cmp_desc(const void *a, const void *b) { 7 return (*(int*)b - *(int*)a); 8} 解释：因为排序的类型可能是int,double等各种，所以用const voida表示可以指向任何类型的指针，然后在return中先将a转化成对应题目类型的指针例如（int） ，再在前面加* 表示指针所指的具体值 （2）再在主函数中调用\n1qsort(a,n,sizeof(int),cmp); a表示要排序的数组的首地址 n表示数组长度 sizeof（int）表示这个数组类型的数据长度 cmp是提前写好的比较函数的名称 3.原理 比较函数cmp中，（有点难理解但很重要！！） 若返回负值—\u003e将参数a排在参数b前面 若返回0—\u003e参数a，参数b顺序不变 若返回正值—\u003e将参数a排在参数b后面 依此可以写各种其他不同排序：（待开发）\n","title":"","type":"notes"},{"content":" 例题 # 排队接水 # 知识点：\n下标索引的理解,选择排序，原始编号移动，前缀和\n解法：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 int n; 5 cin\u0026gt;\u0026gt;n; 6 double time[n]; 7 int original_index[n];//设立原始编号，很重要 8 for(int i = 0;i\u0026lt;n;i++){ 9 cin\u0026gt;\u0026gt;time[i]; 10 original_index[i] = i+1; 11 } 12 for(int i = 0;i\u0026lt;n;i++){ 13 int minindex = i; 14 for(int j = i+1;j\u0026lt;n;j++){ 15 if(time[j]\u0026lt;time[minindex]){//利用选择排序从小到大选出索引，完成第一行输出 16 minindex = j; 17 } 18 } 19 cout\u0026lt;\u0026lt;original_index[minindex]\u0026lt;\u0026lt;\u0026#34; \u0026#34;; 20 swap(time[i],time[minindex]);//防止重复，还是需要交换元素 21 swap(original_index[i],original_index[minindex]);//原始编号也要跟着它主人一起移动交换 22 } 23 cout\u0026lt;\u0026lt;endl; 24 double sum = 0; 25 26 double pre[n];//计算每个人除了自己接水，需要额外等待的时间 27 pre[0] = 0;//第一个人额外等待时间为0 28 for(int i = 1;i\u0026lt;n;i++){//从第二个人开始 29 pre[i] = time[i-1]+pre[i-1];//等于他前一个人接水时间加上前一个人额外等待时间 30 } 31 32 for(int i = 0;i\u0026lt;n;i++){//计算等待总时间 33 sum = sum+pre[i];//修改为正确的等待时间 34 } 35 double average = sum/n; 36 cout\u0026lt;\u0026lt;fixed\u0026lt;\u0026lt;setprecision(3)\u0026lt;\u0026lt;average; 37 return 0; 38} 重点在于原始编号按题目要求改变后，能够正确输出\n自然数的拆分 # 知识点：\n深度优化搜索DFS,全局变量，一些语法和编程习惯\n解法：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3vector\u0026lt;string\u0026gt; results;//设置全局变量 4void dfs(int remain,int start,string current){ 5 if(remain==0){ 6 results.push_back(current);//如果remain已经为0，说明完成一种拆分方法，将它存入results 7 return; 8 } 9 for(int i = start;i\u0026lt;=remain;i++){//先从从1到n选一个数 10 string new_current;//开一个新的拆分方法 11 if(current.empty()){ 12 new_current = to_string(i); 13 }else{ 14 new_current = current+\u0026#34;+\u0026#34;+to_string(i); 15 } 16 dfs(remain-i,i,new_current);//相当于，例如n=7，已经选了一个1，再考虑剩下的6怎么拆...... 17 } 18} 19int main(){ 20 int n; 21 cin\u0026gt;\u0026gt;n; 22 dfs(n,1,\u0026#34;\u0026#34;);//读入 23 sort(results.begin(),results.end());//按字典序升序排列（题目要求） 24 for(int i = 0;i\u0026lt;results.size();i++){ 25 if(results[i]==to_string(n)){//去掉最后的n=n 26 results.erase(results.begin()+i);//erase必须要访问变量的地址，不能用results[i] 27 i--;//此题其实不需要i--，但是如果有多个n=n就需要，保持好习惯 28 } 29 } 30 for(int i = 0;i\u0026lt;results.size();i++){ 31 cout\u0026lt;\u0026lt;n\u0026lt;\u0026lt;\u0026#34;=\u0026#34;\u0026lt;\u0026lt;results[i]\u0026lt;\u0026lt;endl; 32 } 33 return 0; 34} 全局变量在main（）函数外，所有函数都可以直接使用这个变量\n细节很多，慢慢品\u0026hellip;\u0026hellip;\n字符串处理 # 知识点：预留空间，+=的好处，字符到数值的前缀和\n题目：\n解法：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3#define ll long long 4int main(){ 5 string s; 6 s.reserve(1000005); 7 for(int i = 1;s.size()\u0026lt;=1e6;i++){ 8 string temp = to_string(i); 9 for(int j = 1;j\u0026lt;=i;j++){ 10 s += temp;//完成这个大字符串创建 11 } 12 } 13 int t; 14 cin\u0026gt;\u0026gt;t; 15 ll presum[1000005] = {0}; 16 for(ll i = 1;i\u0026lt;=1e6;i++){ 17 presum[i] = presum[i-1]+(s[i-1]-\u0026#39;0\u0026#39;);//甜菜前缀和，直接把字符转换为数值了 18 } 19 while(t--){ 20 ll l,r; 21 cin\u0026gt;\u0026gt;l\u0026gt;\u0026gt;r; 22 ll sum = presum[r]-presum[l-1]; 23 cout\u0026lt;\u0026lt;sum\u0026lt;\u0026lt;endl; 24 } 25} 求f的表达式 # 知识点：递归函数入门\n题目：\n解法：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3double f(double x, int n, int m) {//基本的递归写法，常看常新哦 4 double result = sqrt(m + x); 5 if (m \u0026lt; n) { 6 return f(result, n, m + 1); 7 } else { 8 return result; 9 } 10} 11int main() { 12 int t; 13 scanf(\u0026#34;%d\u0026#34;, \u0026amp;t); 14 while (t--) { 15 double x; 16 int n; 17 scanf(\u0026#34;%lf %d\u0026#34;, \u0026amp;x, \u0026amp;n); 18 double result = f(x, n, 1);//每次从m=1开始 19 printf(\u0026#34;%.3f\\n\u0026#34;, result); 20 } 21 return 0; 22} 活动的选择 # 知识点：贪心，区间衔接，sort排序\n题目：\n解法：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3struct timeq{ 4 int begin; 5 int end; 6}; 7int main(){ 8 int n; 9 cin\u0026gt;\u0026gt;n; 10 vector\u0026lt;timeq\u0026gt; activ(n); 11 for(int i = 0;i\u0026lt;n;i++){ 12 cin\u0026gt;\u0026gt;activ[i].begin\u0026gt;\u0026gt;activ[i].end; 13 } 14 for(int i = 0;i\u0026lt;n-1;i++){ 15 for(int j = 0;j\u0026lt;n-1-i;j++){ 16 if(activ[j].end\u0026gt;activ[j+1].end){ 17 swap(activ[j],activ[j+1]);//按结束时间从早到晚排序，结束越早的排前面，最后能够排更多个数 18 } 19 } 20 } 21 int cnt = 1; 22 for(int i = 0;i\u0026lt;n;){ 23 int j = i+1; 24 while(j\u0026lt;n \u0026amp;\u0026amp; activ[i].end\u0026gt;activ[j].begin){//从第一个最早结束的活动开始，向后寻找第一个匹配的活动 25 j++; 26 } 27 //此刻在while结束后找到了一个j 28 if(j\u0026lt;=n-1){ 29 cnt++; 30 i = j; 31 }else{ 32 break;//若j已经超出活动数量n，直接结束就可以了 33 } 34 } 35 cout\u0026lt;\u0026lt;cnt; 36 return 0; 37} 2的幂次方表示 # 知识点：主要还是递归吧 有点麻烦\n题目：在ZJNU的Oline Judge上吧\n解法：\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3string solve(int n){ 4 if(n==1)return \u0026#34;2(0)\u0026#34;;//雷霆递归（哭 5 if(n==2)return \u0026#34;2\u0026#34;; 6 string result = \u0026#34;\u0026#34;; 7 for(int power = 14;power\u0026gt;-1;power--){ 8 int two_power = 1; 9 for(int j = 0;j\u0026lt;power;j++){ 10 two_power = two_power*2; 11 } 12 if(n\u0026gt;=two_power){ 13 if(result!=\u0026#34;\u0026#34;){ 14 result += \u0026#34;+\u0026#34;; 15 } 16 if(power==1){ 17 result += \u0026#34;2\u0026#34;; 18 }else if(power==0){ 19 result += \u0026#34;2(0)\u0026#34;; 20 }else{ 21 result += \u0026#34;2(\u0026#34;+solve(power)+\u0026#34;)\u0026#34;; 22 } 23 n -= two_power; 24 } 25 } 26 return result; 27} 28int main(){ 29 int t; 30 cin\u0026gt;\u0026gt;t; 31 while(t--){ 32 int n; 33 cin\u0026gt;\u0026gt;n; 34 cout\u0026lt;\u0026lt;solve(n)\u0026lt;\u0026lt;endl; 35 } 36 return 0; 37} 最大公共子串 # 知识点：动态规划\n题目：\n给定两个字符串，输出其最长公共字串的长度以及这个字串\n字符串长度\u0026lt;1000\n解法：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3int main(){ 4 string s1,s2; 5 getline(cin,s1); 6 getline(cin,s2); 7 int len1 = s1.size(); 8 int len2 = s2.size(); 9 //dp[i][j]表示以s1[i-1]和s2[j-1]结尾的两个字串的最长公共子串长度 10 vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; dp(len1+1,vector\u0026lt;int\u0026gt;(len2+1,0)); 11 int maxlen = 0; 12 int endpos = 0; 13 for(int i = 1;i\u0026lt;=len1;i++){ 14 for(int j = 1;j\u0026lt;=len2;j++){ 15 if(s1[i-1]==s2[j-1]){ 16 dp[i][j] = dp[i-1][j-1]+1; 17 if(dp[i][j]\u0026gt;maxlen){ 18 maxlen = dp[i][j]; 19 endpos = i-1; 20 } 21 }else{ 22 dp[i][j] = 0; 23 } 24 } 25 } 26 cout\u0026lt;\u0026lt;maxlen\u0026lt;\u0026lt;endl; 27 if(maxlen\u0026gt;0){ 28 string result = s1.substr(endpos-maxlen+1,maxlen); 29 //至于为什么是endpos-maxlen+1 30 //实在理解不了就举个例子，以个别情况推出一般情况 31 cout\u0026lt;\u0026lt;result\u0026lt;\u0026lt;endl; 32 }else{ 33 cout\u0026lt;\u0026lt;\u0026#34;\u0026#34;\u0026lt;\u0026lt;endl; 34 } 35 return 0; 36} 二分+贪心(最小的最大区间) # 策略：贪心+二分\n在一定范围内二分尝试各个最大的连续区间和，判断是否能够达到该最大区间和，\n不断向更小的最大区间和二分尝试\nbool check:\n若在当前要判断的mid值下，最少需要的分段数小于等于给定的分段数，就代表能够满足条件\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3bool check(int mid,const vector\u0026lt;int\u0026gt;\u0026amp; cost,int n,int m){//数组使用\u0026amp;避免复制造成的浪费 4 int cnt = 1;//至少分成一段 5 int sum = 0; 6 for(int i = 0;i\u0026lt;n;i++){ 7 if(cost[i]\u0026gt;mid){ 8 return false; 9 } 10 if(sum+cost[i]\u0026gt;mid){ 11 sum = cost[i];//重新开始累加,注意这里别写成\u0026#34;sum = 0\u0026#34; 12 cnt++;//所需最少分段数+1 13 if(cnt\u0026gt;m){ 14 return false; 15 } 16 }else{ 17 sum+=cost[i]; 18 } 19 } 20 return true; 21} 22int main(){ 23 ios::sync_with_stdio(false); 24 cin.tie(0); 25 cout.tie(0); 26 int n,m; 27 while(cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m){ 28 vector\u0026lt;int\u0026gt; cost(n); 29 int sum = 0;int maxc = 0; 30 for(int i = 0;i\u0026lt;n;i++){ 31 cin\u0026gt;\u0026gt;cost[i]; 32 maxc = max(maxc,cost[i]); 33 sum+=cost[i]; 34 } 35 int l = maxc; 36 int r = sum; 37 int result = 0; 38 while(l\u0026lt;=r){ 39 int mid = (l+r)/2;//令最大连续区间和为mid，判断是否可行 40 //可以写成\u0026#34;mid = l+(r-l)/2\u0026#34;防止溢出 41 if(check(mid,cost,n,m)){ 42 result = mid; 43 r = mid-1;//向更小的最大区间和二分判断 44 }else{ 45 l = mid+1; 46 } 47 } 48 cout\u0026lt;\u0026lt;result\u0026lt;\u0026lt;\u0026#39;\\n\u0026#39;; 49 } 50 return 0; 51} 二分+差分(借教室) # 策略：利用二分查找第一个不能满足的订单\n利用实时的差分判断当前是否符合\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3#define ll long long 4struct borrow{ 5 ll d; 6 ll s; 7 ll t; 8}; 9ll n,m; 10vector\u0026lt;ll\u0026gt; rooms;//初始每天的空余房间 11vector\u0026lt;borrow\u0026gt; orders;//所有订单 12bool check(int k){//判断前k份订单能否满足 13 vector\u0026lt;ll\u0026gt; diff(n+2,0);//差分数组 14 for(int i = 1;i\u0026lt;=k;i++){ 15 diff[orders[i].s]+=orders[i].d; 16 diff[orders[i].t+1]-=orders[i].d; 17 } 18 ll need = 0; 19 for(int i = 1;i\u0026lt;=n;i++){ 20 //在只考虑前k个订单的前提下，遍历n天，看看是否全部能够满足。若不能，就说明不能满足前K个订单 21 need+=diff[i]; 22 if(need\u0026gt;rooms[i]){ 23 return false; 24 } 25 } 26 return true; 27} 28int main(){ 29 ios::sync_with_stdio(false); 30 cin.tie(nullptr); 31 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m; 32 rooms.resize(n+1); 33 for(ll i = 1;i\u0026lt;=n;i++){ 34 cin\u0026gt;\u0026gt;rooms[i]; 35 } 36 orders.resize(m+1); 37 for(ll i = 1;i\u0026lt;=m;i++){ 38 cin\u0026gt;\u0026gt;orders[i].d\u0026gt;\u0026gt;orders[i].s\u0026gt;\u0026gt;orders[i].t; 39 } 40 ll l = 1;ll r = m;ll ans = -1; 41 while(l\u0026lt;=r){ 42 ll mid = (l+r)/2; 43 if(!check(mid)){ 44 ans = mid; 45 r = mid-1;//继续查找第一个不满足的订单 46 }else{ 47 l = mid+1; 48 } 49 } 50 if(ans==-1){ 51 cout\u0026lt;\u0026lt;0\u0026lt;\u0026lt;endl; 52 }else{ 53 cout\u0026lt;\u0026lt;-1\u0026lt;\u0026lt;endl; 54 cout\u0026lt;\u0026lt;ans\u0026lt;\u0026lt;endl; 55 } 56 return 0; 57} 二分+最大加权平均 # 注意，严格来说，整体最大加权平均不等于单个最大性价比中挑选最优的\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3const int maxn = 10005; 4int n,k; 5vector\u0026lt;pair\u0026lt;int,int\u0026gt;\u0026gt; cv(maxn); 6double arr[maxn]; 7bool check(double x){ 8 for(int i = 0;i\u0026lt;n;i++){ 9 arr[i] = cv[i].second-x*cv[i].first; 10 } 11 sort(arr,arr+n,greater\u0026lt;double\u0026gt;()); 12 double sum = 0; 13 for(int i = 0;i\u0026lt;k;i++){ 14 sum+=arr[i]; 15 } 16 return sum\u0026gt;=0; 17} 18int main(){ 19 int t; 20 cin\u0026gt;\u0026gt;t; 21 while(t--){ 22 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;k; 23 for(int i = 0;i\u0026lt;n;i++){ 24 cin\u0026gt;\u0026gt;cv[i].first\u0026gt;\u0026gt;cv[i].second; 25 } 26 double l = 0,r = 1e7,ans = 0; 27 for(int i = 0;i\u0026lt;75;i++){ 28 double mid = (l+r)/2; 29 if(check(mid)){ 30 ans = mid; 31 l = mid;//double型，小心不要写成\u0026#34;l = mid+1\u0026#34; 32 }else{ 33 r = mid; 34 } 35 } 36 cout\u0026lt;\u0026lt;int(ans)\u0026lt;\u0026lt;endl; 37 } 38 return 0; 39} ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/basic-cpp/examples/","section":"学习笔记","summary":"例题 # 排队接水 # 知识点：\n下标索引的理解,选择排序，原始编号移动，前缀和\n解法：\n1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3int main(){ 4 int n; 5 cin\u003e\u003en; 6 double time[n]; 7 int original_index[n];//设立原始编号，很重要 8 for(int i = 0;i\u003cn;i++){ 9 cin\u003e\u003etime[i]; 10 original_index[i] = i+1; 11 } 12 for(int i = 0;i\u003cn;i++){ 13 int minindex = i; 14 for(int j = i+1;j\u003cn;j++){ 15 if(time[j]\u003ctime[minindex]){//利用选择排序从小到大选出索引，完成第一行输出 16 minindex = j; 17 } 18 } 19 cout\u003c\u003coriginal_index[minindex]\u003c\u003c\" \"; 20 swap(time[i],time[minindex]);//防止重复，还是需要交换元素 21 swap(original_index[i],original_index[minindex]);//原始编号也要跟着它主人一起移动交换 22 } 23 cout\u003c\u003cendl; 24 double sum = 0; 25 26 double pre[n];//计算每个人除了自己接水，需要额外等待的时间 27 pre[0] = 0;//第一个人额外等待时间为0 28 for(int i = 1;i\u003cn;i++){//从第二个人开始 29 pre[i] = time[i-1]+pre[i-1];//等于他前一个人接水时间加上前一个人额外等待时间 30 } 31 32 for(int i = 0;i\u003cn;i++){//计算等待总时间 33 sum = sum+pre[i];//修改为正确的等待时间 34 } 35 double average = sum/n; 36 cout\u003c\u003cfixed\u003c\u003csetprecision(3)\u003c\u003caverage; 37 return 0; 38} 重点在于原始编号按题目要求改变后，能够正确输出\n","title":"","type":"notes"},{"content":" 图论基础 # 图的存储 # 邻接表存图 # 对于每一个节点，记录这个几点连接的所有其他节点和对应权值\n1#include \u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3const int N = 100010; 4vector\u0026lt;pair\u0026lt;ll,int\u0026gt; graph[N];//图,{权值,对应的节点} 5int n,m; 6int main(){ 7 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m; 8 for(int i = 0;i\u0026lt;m;i++){ 9 int u,v,w; 10 cin\u0026gt;\u0026gt;u\u0026gt;\u0026gt;v\u0026gt;\u0026gt;w; 11 graph[u].push_back({w,v}); 12 graph[v].push_back({w,u}); 13 } 14} 邻接矩阵存图 # 用一个二维数组记录每两个点之间的距离\n两个索引分别代表两个点 g[i][j]的值代表点i和j之间的距离\n1#define ll long long 2const int N = 200010; 3const ll INF = 4e18; 4ll g[N][N]; 5int main(){ 6 int n,m; 7 cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m; 8 for(int i = 1;i\u0026lt;=n;i++){ 9 for(int j = 1;j\u0026lt;=n;j++){ 10 if(i==j){ 11 g[i][j] = 0;//同一个点当然是0 12 }else{ 13 g[i][j] = INF;//初始化矩阵为INF(不可达) 14 } 15 } 16 } 17 for(int i = 0;i\u0026lt;m;i++){ 18 int u,v; 19 ll w; 20 cin\u0026gt;\u0026gt;u\u0026gt;\u0026gt;v\u0026gt;\u0026gt;w; 21 //无向图 22 g[u][v] = min(g[u][v],w); 23 g[v][u] = min(g[v][u],w);//注意 这里出现重边时取用min是绝大部分情况 不排除其他写法 24 //如果是有向图,只用下面这一行 25 //g[u][v] = min(g[u][v],w); 26 } 27} 稠密图\u0026amp;稀疏图 # 令n=点数 m=边数\n因此无向图最大边数=(n*(n-1))/2\n如果m接近于这个最大边数 就是稠密图\n如果m接近n或者更小 就是稀疏图\n可以根据稀疏和稠密的性质选择算法 获得更高效率\n最小生成树 # 复杂度\nPrim\u0026ndash;\u0026gt;O(n^2)\nPrim堆优化\u0026ndash;\u0026gt;O(m log n)\nKruskal\u0026ndash;\u0026gt;O(m log m)\n一般来说\n稠密图-\u0026gt;朴素Prim\n稀疏图-\u0026gt;Kruskal或者堆优化Prim\n另外:\n如果n与m很接近(n==m) 选择Kruskal和堆优化Prim在复杂度上没有差异\n但是Kruskal是基于sort排序和并查集 更快且不容易写错\n选择Kruskal\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/basic-cpp/graph/","section":"学习笔记","summary":"图论基础 # 图的存储 # 邻接表存图 # 对于每一个节点，记录这个几点连接的所有其他节点和对应权值\n1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3const int N = 100010; 4vector\u003cpair\u003cll,int\u003e graph[N];//图,{权值,对应的节点} 5int n,m; 6int main(){ 7 cin\u003e\u003en\u003e\u003em; 8 for(int i = 0;i\u003cm;i++){ 9 int u,v,w; 10 cin\u003e\u003eu\u003e\u003ev\u003e\u003ew; 11 graph[u].push_back({w,v}); 12 graph[v].push_back({w,u}); 13 } 14} 邻接矩阵存图 # 用一个二维数组记录每两个点之间的距离\n","title":"","type":"notes"},{"content":" C++应用 # 随机数生成 # 传统C方法：\n1#include\u0026lt;cstdlib\u0026gt; 2#include\u0026lt;ctime\u0026gt; 3//初始化随机种子(只需一次) 4srand(time(0)); 5int random_num = rand(); 6int random_inrange = rand()%100;//0-99 7int random_inrange = rand()%100+1//1-100 8//随机质量不怎么高，易预测，不均匀 现代C++方法：\n1#include\u0026lt;random\u0026gt; 关于std:: # 由于平时写算法题都用头文件：\n#include\u0026lt;bits/stdc++.h\u0026gt;+using namespace std;\n容易忽略了std::的使用;\n1std::工具名--\u0026gt;使用std仓库的某个工具 2using namespace std--\u0026gt;默认从std使用工具 3//实际工作时,不推荐使用上述头文件 4//输入输出，字符串string，容器，算法函数等都需要加std:: 5std::cout\u0026lt;\u0026lt;\u0026#34;minecraft\u0026#34;; 6std::endl; 7std::vector\u0026lt;int\u0026gt; a;std::map\u0026lt;std::string,int\u0026gt; mp; 8std::string s = \u0026#34;hello\u0026#34;; 9std::sort(a,a+n); 10std::swap(a,b); 11std::max(x,y);std::min(x,y); 也可以只引入常用的几个：\n1using std::cout; 2using std::cin; 3using std::vector; 4using std::endl; 5//其他仍要加上std:: 矩阵乘法优化 # 1int n,m,s; 2cin\u0026gt;\u0026gt;n\u0026gt;\u0026gt;m\u0026gt;\u0026gt;s;//表示是n*m与m*s的矩阵相乘 3//原始数学算法 4for(int i = 0;i\u0026lt;n;i++){ 5 for(int j = 0;j\u0026lt;s;j++){ 6 for(int k = 0;k\u0026lt;m;k++){ 7 c[i][j] += a[i][k]*b[k][j]; 8 } 9 } 10} 11fill(c.begin(),c.end(),vector\u0026lt;int\u0026gt;(s,0)); 12//下面是效率更高的算法，先当黑盒用 13for(int i = 0;i\u0026lt;n;i++){ 14 for(int k = 0;k\u0026lt;m;k++){ 15 for(int j = 0;j\u0026lt;s;j++){ 16 c[i][j] += a[i][k]*b[k][j]; 17 } 18 } 19} 20//其实就是把基础版本的后两个for循环换了一下位置。 new/delete动态内存 # 相比C的malloc函数更加安全可用一些;\n用于申请动态内存，创建变量\n1//单变量创建 2int *p = new int; 3*p = 10;//赋值 4delete p;//释放内存method1 5 6//数组变量创建 7int size; 8cin\u0026gt;\u0026gt;size;//用户输入数组大小 9int *arr = new int[size];//动态分配 10for(int i = 0;i\u0026lt;size;i++){ 11 arr[i] = i;//赋值 12 //或者*(arr+i) = i; 13} 14delete[] arr;//释放内存method2 15 16//二维数组 17int *arr = new int[row*col]; 18 19//其他写法 20int *p = new int();//初始化为0 21int *p = new int(1);//初始化为1 22int *arr = new int[5]();//初始化全为0 23int *arr = new int[5]{1,2,3};//前三个初始化，后两个为0 vector底层指针数组 # 虽然已经会用vector\u0026lt;\u0026gt;这种自动化的工具，但是:\nint **mat和int *mat也是要掌握的 ;\n以便了解vector\u0026lt;\u0026gt;的底层原理；\n1//传统方法 2int row,col; 3cin\u0026gt;\u0026gt;row\u0026gt;\u0026gt;col;//输入矩阵大小 4int **mat = new int*[row];//每个mat元素指向一个int*的指针 5for(int i = 0;i\u0026lt;row;i++){ 6 mat[i] = new int[col];//每个mat[i]指向一个int的数组 7} 8for(int i = 0;i\u0026lt;row;i++){ 9 for(int j = 0;j\u0026lt;col;j++){ 10 mat[i][j] = i*col+j;//赋值就是老方法 11 } 12} 13for(int i = 0;i\u0026lt;row;i++){ 14 delete[] mat[i];//先释放每一行 15} 16delete[] mat;//再释放行指针数组 解引用：\nmat[i][j]=*(*(mat+i)+j)\n应用场景：\n1//创建不规则稀疏矩阵 2int **jagged = new int*[3]; 3jagged[0] = new int[2]{1,2}; 4jagged[1] = new int[3]{3,4,5}; 5jagged[2] = new int[1]{6}; 6//频繁交换行 7void row_swap(int **mat,int row1,int row2){ 8 int *tmp = mamt[row1]; 9 mat[row1] = mat[row2]; 10 mat[row2] = tmp; 11} 12//... 1//内存连续存储方法 2//性能更高 3int row = 3;int col = 4; 4int *mat = new int[row*col]; 5for(int i = 0;i\u0026lt;row;i++){ 6 for(int j = 0;j\u0026lt;col;j++){ 7 mat[i*col+j] = i*col+j;//赋值 8 } 9} 10delete[] mat;//释放内存 ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/other-cpp/applications/","section":"学习笔记","summary":"C++应用 # 随机数生成 # 传统C方法：\n1#include\u003ccstdlib\u003e 2#include\u003cctime\u003e 3//初始化随机种子(只需一次) 4srand(time(0)); 5int random_num = rand(); 6int random_inrange = rand()%100;//0-99 7int random_inrange = rand()%100+1//1-100 8//随机质量不怎么高，易预测，不均匀 现代C++方法：\n1#include\u003crandom\u003e 关于std:: # 由于平时写算法题都用头文件：\n#include\u003cbits/stdc++.h\u003e+using namespace std;\n容易忽略了std::的使用;\n1std::工具名--\u003e使用std仓库的某个工具 2using namespace std--\u003e默认从std使用工具 3//实际工作时,不推荐使用上述头文件 4//输入输出，字符串string，容器，算法函数等都需要加std:: 5std::cout\u003c\u003c\"minecraft\"; 6std::endl; 7std::vector\u003cint\u003e a;std::map\u003cstd::string,int\u003e mp; 8std::string s = \"hello\"; 9std::sort(a,a+n); 10std::swap(a,b); 11std::max(x,y);std::min(x,y); 也可以只引入常用的几个：\n","title":"","type":"notes"},{"content":" 数据结构 # 语法 # Class类 # 类似于Struct结构体的升级拓展版，先初步了解一下Class的基本语法吧.\n用于操作和数据的封装，面向对象\n大部分情况，Class内部只包含**数据和函数**\n能够把近似的数据和函数归类整理，有助于避免屎山代码\nClass内部可以再嵌套另一个Class，这里不展开\n1class 类名称{ 2private://以下内容私有，只有class内部可以调用和访问 3 //这里暂时不讨论private，只以public为例 4 string password;//比如密码私有 5public://以下内容公开，class内外都可以调用和访问 6 int age; 7 string name;//属性，数据 8 void print(){//普通函数 9 cout\u0026lt;\u0026lt;age\u0026lt;\u0026lt;\u0026#34; \u0026#34;\u0026lt;\u0026lt;name\u0026lt;\u0026lt;endl;//用于做具体操作 10 } 11 类名称(int nianling,string xingming){//构造函数 12 //函数名称必须与类名称一样，不需要写返还的类型 13 //用于创造东西 14 age = nianling; 15 name = xingming; 16 } 17 类名称(){ 18 age = 0; 19 name = \u0026#34;\u0026#34;; 20 } 21};//别漏分号 22 23 24int main(){ 25 //Class的类名称即是一个自定义的变量类型 26 //可以自行在main中调用 27 类名称 pastman;//无构造函数的初始化 28 pastman.age = 18; 29 pastman.name = \u0026#34;hth\u0026#34;; 30 //调用构造函数创建对象 31 类名称 deadman(18,\u0026#34;hth\u0026#34;); 32 //利用class创建了一个自定义类型的变量，同时调用构造函数进行了初始化 33 return 0; 34} 动态链表 # 一般都是推荐带上头结点的：\n以几个字节存储空间的代价换来后面插入删除等逻辑的统一\n前插入法：\n(前插入法的结果会使数据与写入顺序相反)\n每次的newnode要先后处理它的头和尾，也就是这个newnode的next要指向哪？又有谁的next指向这个newnode？\nnewnode-\u0026gt;next = head-\u0026gt;next;//\nhead-\u0026gt;next = newnode;//\n(两行代码顺序不能换)\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3struct node{//结点 4 int data; 5 node *next; 6} 7node *createlist(){//链表创建 8 node *head = new int();//创建头结点 9 head-\u0026gt;next = NULL; 10 while(1){ 11 int value; 12 cin\u0026gt;\u0026gt;value; 13 if(value\u0026lt;=0)break; 14 node *newnode = new node();//创建新结点 15 newnode-\u0026gt;data = value;//先把数据域处理掉 16 newnode-\u0026gt;next = head-\u0026gt;next;//处理新结点的头 17 head-\u0026gt;next = newnode;//处理新结点的尾 18 } 19 return head;//返回头结点 20} 尾插入法：\n1#include\u0026lt;bits/stdc++.h\u0026gt; 2using namespace std; 3struct node{ 4 int data; 5 node *next; 6} 7node *createlist(){ 8 node *head = new node();//创建头结点 9 head-\u0026gt;next = NULL; 10 node *tail = head;//需要再创建一个尾结点 11 while(1){ 12 int value; 13 cin\u0026gt;\u0026gt;value; 14 if(value\u0026lt;=0)break; 15 node *newnode = new node(); 16 newnode-\u0026gt;data = value;//老样子先处理数据 17 tail-\u0026gt;next = newnode;//处理newnode的尾 18 tail = newnode;//移动到newnode上 19 tail-\u0026gt;next = NULL;//处理newnode的头 20 } 21 return head; 22} 这里只包括链表基本创建，还有链表打印，查找，插入，删除，以及内存释放，待学习\n算法 # ","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/other-cpp/data-structures/","section":"学习笔记","summary":"数据结构 # 语法 # Class类 # 类似于Struct结构体的升级拓展版，先初步了解一下Class的基本语法吧.\n用于操作和数据的封装，面向对象\n大部分情况，Class内部只包含**数据和函数**\n能够把近似的数据和函数归类整理，有助于避免屎山代码\nClass内部可以再嵌套另一个Class，这里不展开\n1class 类名称{ 2private://以下内容私有，只有class内部可以调用和访问 3 //这里暂时不讨论private，只以public为例 4 string password;//比如密码私有 5public://以下内容公开，class内外都可以调用和访问 6 int age; 7 string name;//属性，数据 8 void print(){//普通函数 9 cout\u003c\u003cage\u003c\u003c\" \"\u003c\u003cname\u003c\u003cendl;//用于做具体操作 10 } 11 类名称(int nianling,string xingming){//构造函数 12 //函数名称必须与类名称一样，不需要写返还的类型 13 //用于创造东西 14 age = nianling; 15 name = xingming; 16 } 17 类名称(){ 18 age = 0; 19 name = \"\"; 20 } 21};//别漏分号 22 23 24int main(){ 25 //Class的类名称即是一个自定义的变量类型 26 //可以自行在main中调用 27 类名称 pastman;//无构造函数的初始化 28 pastman.age = 18; 29 pastman.name = \"hth\"; 30 //调用构造函数创建对象 31 类名称 deadman(18,\"hth\"); 32 //利用class创建了一个自定义类型的变量，同时调用构造函数进行了初始化 33 return 0; 34} 动态链表 # 一般都是推荐带上头结点的：\n","title":"","type":"notes"},{"content":" Environment # 安装Python解释器 # win+r输入cmd\n在命令行窗口输入python或者python --version回车\n若进入\u0026gt;\u0026gt;\u0026gt;界面或者输出python版本信息就说明安装成功\n若无法识别就去微软商店安装,记得点击add to path\n注：\n新建文本文件,更改文件后缀为.py,然后在编译器或者记事本里写好python代码,就可以进行多行python文件运行了\n安装Python开发工具 # VScode or Pycharm;\n这里安装Pycharm:\n网址PyCharm，您需要的唯一 Python IDE; (提醒:使用pycharm时切记 尽量用英文命名路径和文件夹)\n创建.py关联选项，如果只有pycharm一个开发工具那是建议勾选的,如果有多个开发环境那一般不勾选;\n更新上下文菜单可以右键文件用Pycharm打开,挺好的,建议勾选;\n更新path变量使Pycharm可以便利地在终端打开,与其他开发工具协作运行,推荐勾选;\nPycharm使用指南 # 设置 # 文件-设置-编辑-常规-自动换行：\n勾选对这些文件进行软换行,然后把后面默认的那些文件格式都先删掉，\n最后输入一个*.*，代表对所有文件格式进行软换行\n项目创建 # 首先,文件夹名称保持全英文,并且不要带空格\n先在磁盘中创建Python_projects文件夹,再在Pycharm中新建项目,选择存储在这个文件夹，选择后不要直接创建项目,要在路径后再加上\\Projects_name,这样结构会更好\n解释器类型：\n项目venv：虚拟环境运行\n基础conda：\n自定义环境：\n项目配置文件 # .venv为每个项目存放环境，工具信息 相当于一个虚拟环境 这里有独立的python各种包 包括python.exe解释器 能够有效防止环境污染\n.idea为每个项目存放配置信息，比如光标最后位置等 一般不需要动这两个文件夹\n调试 # (1)设置断点：\n点击代码左侧的行数数字，使该行代码变成红色，表示标记为断点；\n后续开发工具会运行到该断电为止，之后可以手动调试\n(2)debug调试：\n点击“调试”按钮，待程序运行到断点后，可以选择“步过，步入，单步执行，步出”等调试方式\n步过就是一步步执行后续代码；\n快捷键 # 在代码某一行的任意位置按Ctrl+/，该行代码就会被注释(\u0026quot;#\u0026quot;),再次按Ctrl+/就会取消注释;\nshift+alt+.放大代码文字大小,shift+alt+,减小代码文字大小;\nCtrl+d复制粘贴一次当前行代码到下一行;\nshift+enter快速创建新的一行，即使光标正处于某行代码中间(这个很有用);\nalt+shift按住不动,拖动鼠标光标,能进行列编辑,同时对多行进行编辑;\nctrl+y删除当前行代码;\nalt+p强制大模型插件智能推荐代码\nSyntax # 语句结束 # 回车代表语句结束，除非两部分代码写在了同一行，一般不用分号.\n变量 # Python是动态变量，同一个变量可以存储不同类型的数据\n但还是建议一个变量就存储一个类型的数据\n变量必须赋值后才能使用\nModules # streamlit # 一个python库 通过它可以依据python语言开发交互式Web界面\n无需学习所有前端代码知识\n主要用于数据科学和机器学习\n在Pycharm中打开终端PowerShell输入以下安装命令\n1pip install streamlit 详情学习前往官方网址Streamlit documentation\n运行streamlit文件需要在IDE中用终端打开文件 然后输入:\nstreamlit run xxxx.py\n默认占用端口是8501 如果出现端口异常被占用;\n可以尝试其他端口例如8000,8502,8888,8503\n在终端输入streamlit run xxx.py --server.port 端口号来修改使用的端口;\nrequests # 发送请求 用于爬虫\njson # openai # Problems # lingma插件(其实不建议装) # 依赖库路径 # 在本地直接修改项目文件夹名称后重新打开pycharm\n发现很多依赖第三方库的程序无法运行\n根本原因:虚拟环境中有绝对路径 1F:\\Python_projects\\Learn_python\\.venv\\Scripts\\python.exe ❌不存在了 2F:\\Python_projects\\AIweb调用\\.venv\\Scripts\\python.exe ✅实际位置 streamlit,lxml等就找不到正确的python解释器了\n点击项目文件夹根目录-\u0026gt;用终端打开-\u0026gt;\n1Remove-Item -Recurse -Force .venv #删除旧的虚拟环境 1#创建新环境（.venv就是相对路径） 2python -m venv .venv 3#激活环境 4.venv\\Scripts\\activate 1#根据项目import语句重新安装所有依赖的第三方库 2pip install streamlit openai requests lxml 3#或者如果有requirements.txt 4pip install -r requirements.txt 最后重新设置解释器:\n在pycharm中 英文模式下双击Shift,输入python interpreter\n进入后点击添加解释器\n选择项目文件夹/.venv/Scripts/python.exe 作为新的解释器\n然后重新运行程序试试\n以后可以在根目录终端输入\n1pip freeze \u0026gt; requirements.txt 导出依赖文件目录\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/python/python-note/pycharm/","section":"学习笔记","summary":"Environment # 安装Python解释器 # win+r输入cmd\n在命令行窗口输入python或者python --version回车\n若进入\u003e\u003e\u003e界面或者输出python版本信息就说明安装成功\n若无法识别就去微软商店安装,记得点击add to path\n注：\n新建文本文件,更改文件后缀为.py,然后在编译器或者记事本里写好python代码,就可以进行多行python文件运行了\n安装Python开发工具 # VScode or Pycharm;\n这里安装Pycharm:\n网址PyCharm，您需要的唯一 Python IDE; (提醒:使用pycharm时切记 尽量用英文命名路径和文件夹)\n创建.py关联选项，如果只有pycharm一个开发工具那是建议勾选的,如果有多个开发环境那一般不勾选;\n更新上下文菜单可以右键文件用Pycharm打开,挺好的,建议勾选;\n更新path变量使Pycharm可以便利地在终端打开,与其他开发工具协作运行,推荐勾选;\nPycharm使用指南 # 设置 # 文件-设置-编辑-常规-自动换行：\n","title":"","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"Ai","type":"tags"},{"content":"这是一个 Python 入门到 AI 应用的练习代码集，按章节分组。每一章就是一个目录，里面有当章所有 .py 练习题，点击文件名即可下载。\n✦ 文件目录 # ▸ 📁 01第一章 › 01入门程序.py ▸ 📁 02第二章_基础 › 01字面量和变量.py › 02字符串.py › 03输入输出.py › 04运算符.py › 05if条件判断.py › 06循环.py › 07循环案例1.py › 08循环案例2.py ▸ 📁 03第三章_数据容器 › 01列表.py › 02列表案例.py › 03列表案例_去重合并.py › 04列表案例3_列表推导式.py › 05字符串str.py › 06字符串案例.py › 07元组.py › 08元组案例.py › 09集合set.py › 10集合案例.py › 11字典dict.py › 12字典案例.py ▸ 📁 04第四章_函数 › 01函数基础.py › 02案例1.py › 03函数传参.py › 04匿名函数.py › 05案例2.py › 06类型注解.py ▸ 📁 05模块and面向对象 ▸ 📁 My_module01 › 01模块介绍.py › 模块导入.py ▸ 📁 My_module02 › functions.py › main.py ▸ 📁 utils › __init__.py › 包_介绍.py › 01类与对象.py › 02类的魔法方法.py › 03实例属性和类属性.py › 04面向对象案例.py › 05异常处理.py ▸ 📁 06AI应用 ▸ 📁 resources › logo.png › music_connects_people.png › poem.txt › 基岩版MC.png ▸ 📁 sessions › 2026-05-11_13_43_08.json › 2026-05-11_17_23_20.json › 01Deepseek调用.py › 02streamlit入门.py › 02文件操作入门.py › 03雷霆AI.py ▸ 📁 07爬虫 ▸ 📁 csv_data › 02.csv › csv入门.csv ▸ 📁 resources › 仙逆人物志.html › 01robots协议.py › 02Xpath语法.py › 03use_lxml.py › 04入门程序.py › 05csv.py › 06_TMDB高分榜单.py › requirements.txt ✦ 说明 # 这一页只展示目录和文件清单，不展示代码内容 — 避免一次加载太多 每个 .py 都是独立的练习脚本，下载后直接 python \u0026lt;文件名\u0026gt;.py 跑就行 .venv / __pycache__ 等环境文件已自动隐藏 想看某个 .py 的内容？点它下载到本地打开 想\u0026quot;下载整个项目\u0026quot;？直接打开 requirements.txt 装依赖，然后挨个跑 💡 后期：可以为每个 .py 加注释 / 介绍，做成\u0026quot;AI 学院 Python 入门全解\u0026quot;系列文章。 现在先以可下载 + 可浏览的结构跑起来。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/aipython/","section":"学习笔记","summary":"这是一个 Python 入门到 AI 应用的练习代码集，按章节分组。每一章就是一个目录，里面有当章所有 .py 练习题，点击文件名即可下载。\n✦ 文件目录 # ▸ 📁 01第一章 › 01入门程序.py ▸ 📁 02第二章_基础 › 01字面量和变量.py › 02字符串.py › 03输入输出.py › 04运算符.py › 05if条件判断.py › 06循环.py › 07循环案例1.py › 08循环案例2.py ▸ 📁 03第三章_数据容器 › 01列表.py › 02列表案例.py › 03列表案例_去重合并.py › 04列表案例3_列表推导式.py › 05字符串str.py › 06字符串案例.py › 07元组.py › 08元组案例.py › 09集合set.py › 10集合案例.py › 11字典dict.py › 12字典案例.py ▸ 📁 04第四章_函数 › 01函数基础.py › 02案例1.py › 03函数传参.py › 04匿名函数.py › 05案例2.py › 06类型注解.py ▸ 📁 05模块and面向对象 ▸ 📁 My_module01 › 01模块介绍.py › 模块导入.py ▸ 📁 My_module02 › functions.py › main.py ▸ 📁 utils › __init__.py › 包_介绍.py › 01类与对象.py › 02类的魔法方法.py › 03实例属性和类属性.py › 04面向对象案例.py › 05异常处理.py ▸ 📁 06AI应用 ▸ 📁 resources › logo.png › music_connects_people.png › poem.txt › 基岩版MC.png ▸ 📁 sessions › 2026-05-11_13_43_08.json › 2026-05-11_17_23_20.json › 01Deepseek调用.py › 02streamlit入门.py › 02文件操作入门.py › 03雷霆AI.py ▸ 📁 07爬虫 ▸ 📁 csv_data › 02.csv › csv入门.csv ▸ 📁 resources › 仙逆人物志.html › 01robots协议.py › 02Xpath语法.py › 03use_lxml.py › 04入门程序.py › 05csv.py › 06_TMDB高分榜单.py › requirements.txt ✦ 说明 # 这一页只展示目录和文件清单，不展示代码内容 — 避免一次加载太多 每个 .py 都是独立的练习脚本，下载后直接 python \u003c文件名\u003e.py 跑就行 .venv / __pycache__ 等环境文件已自动隐藏 想看某个 .py 的内容？点它下载到本地打开 想\"下载整个项目\"？直接打开 requirements.txt 装依赖，然后挨个跑 💡 后期：可以为每个 .py 加注释 / 介绍，做成\"AI 学院 Python 入门全解\"系列文章。 现在先以可下载 + 可浏览的结构跑起来。\n","title":"AI Python 入门练习","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/basic-cpp/","section":"学习笔记","summary":"","title":"C++ · 基础算法","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/other-cpp/","section":"学习笔记","summary":"","title":"C++ · 其他","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/cpp-algorithm/","section":"学习笔记","summary":"","title":"C++ Algorithm","type":"notes"},{"content":"(详细完整内容请见Minecraft Wiki)\nDatapacks # Simple Introductions # 数据包只针对单个存档，每一个存档都会有一个数据包文件夹（游戏版本\u0026gt;saves\u0026gt;存档名\u0026gt;datapacks)\n数据包以文件夹或者压缩包形式存在于datapacks文件夹中都可以运行，但推荐用压缩包的形式\nvscode所需插件：datapack helper plus by spyglass；syntax-mcfunction\n这两个插件工作的前提是，所创建文件的结构符合官方数据包结构\n所有具体标签名称可以在游戏内先F3+H,鼠标悬浮在物品上就可以查看\n数据包能够实现的效果大致如下:\n技能 / 法术系统 RPG 系统 Boss 战 自定义物品 新维度（部分） 世界生成 生物行为 生存机制 UI / HUD（部分） 动画 / 过场 多人玩法 原版机制增强 解谜 / 恐怖地图 固定文件结构 # data命名空间；\npack.mcmeta；\npack.png；\njson文件：\n[]数组：里面要放值。键值对，数组，字符串，数值都是值；\n{}对象：里面要放键值对。键值对的值可以放任何值；\n然后可以无限嵌套；\n数据包内json文件基本就是这个格式编写；\n覆盖原版 # 想要覆盖原版内容或者是删除原版某个内容；\n对于recipes来说：\n则需要在数据包中创建minecraft:命名空间，在此命名空间添加的内容会覆盖掉原版vanilla的同名内容，若想删除，把result写成air,或者该json文件直接为空也可以；\n标签tag # 标签文件：\n将若干同类型的事物定义为一个集合，方便调用；使用json格式；\nreplace：false-\u0026gt;取同名冲突路径文件的并集，挺友好；\nreplace：true-\u0026gt;一般不用这个，会覆盖同路径文件；\n引用标签文件：#命名空间+文件名；\n函数function # 函数文件：\n在大多数情况可以代替命令方块使用；\n一行只写一条指令；\n缩进可以加在左边 右边不能再加；\n加“#”注释，但注意这里注释和命令不能处于同一行；同一行要么命令要么注释；\n调用一个函数时，minecraft会在一个游戏刻内执行完该函数所有命令；\n函数文件中一但有错误，整个文件都会失效。因此当数据包无法执行时，需要去确认error的位置，此时可以用二分法排错，先删去一般代码再/reload，根据提示继续排错；\n函数的执行：\n函数会继承命令的执行环境；\n当由数据包执行函数时：\n位置位于主世界出生点，可以/setworldspawn修改，x轴正方向；\n玩家输入/function执行函数时：\n于玩家所在位置执行，实体对象为该玩家，该玩家维度，该玩家朝向；\n两个特殊的函数标签：load.json,tick.json；名称固定，且位于minecraft命名空间下\nload.json:此标签指定的函数会在数据包加载时自动执行一次\ntick.json:此标签指定的函数会在每个游戏刻都执行一次，tick要谨慎使用哦\n/schedule function\u0026lt;路径\u0026gt;\u0026lt;时间\u0026gt;\u0026lt; append或者replace \u0026gt;命令：设置一定时间后执行函数\n(一堆图片待添加)\n配方recipes # 配方的json文件都放在recipes命名空间内，可以在此命名空间内再分类几个文件夹，方便开发和维护;\n(json文件其实不能带注释的，但为了学习用“//”注释一下)\ncrafting配方：(工作台)\n无序合成：\n以下添加配方：用一个钻石矿+金矿+绿宝石矿，合成一个圆石\n1{ 2 \u0026#34;type\u0026#34;:\u0026#34;minecraft:crafting_shapeless\u0026#34;,//表示原料可以无序摆放，2*2工作台也可以 3 \u0026#34;ingredients\u0026#34;:[ 4 { 5 \u0026#34;item\u0026#34;:\u0026#34;minecraft:diamond_ore\u0026#34; 6 }, 7 { 8 \u0026#34;item\u0026#34;:\u0026#34;minecraft:gold_ore\u0026#34; 9 }, 10 { 11 \u0026#34;item\u0026#34;:\u0026#34;minecraft:emerald_ore\u0026#34; 12 } 13 ], 14 \u0026#34;result\u0026#34;:{ 15 \u0026#34;item\u0026#34;:\u0026#34;minecraft:stone\u0026#34;, 16 \u0026#34;count\u0026#34;:1 //如果是1其实可以省略改行代码，默认合成数量就是1 17 } 18} 添加“用深层钻石矿或者普通钻石矿都可以合成”的两种写法：\n（1）\n1{ 2 \u0026#34;type\u0026#34;:\u0026#34;minecraft:crafting_shapeless\u0026#34;, 3 \u0026#34;ingredients\u0026#34;:[ 4 [ 5 { 6 \u0026#34;item\u0026#34;:\u0026#34;minecraft:diamond_ore\u0026#34; 7 }, 8 { 9 \u0026#34;item\u0026#34;:\u0026#34;minecraft:deepslate_diamond_ore\u0026#34; 10 } 11 ],//第一项钻石矿用数组形式写，数组里再包含多个键值对 12 { 13 \u0026#34;item\u0026#34;:\u0026#34;minecraft:gold_ore\u0026#34; 14 }, 15 { 16 \u0026#34;item\u0026#34;:\u0026#34;minecraft:emerald_ore\u0026#34; 17 } 18 ], 19 \u0026#34;result\u0026#34;:{ 20 \u0026#34;item\u0026#34;:\u0026#34;minecraft:stone\u0026#34;, 21 \u0026#34;count\u0026#34;:1 22 } 23} （2）\n1{ 2 \u0026#34;type\u0026#34;:\u0026#34;minecraft:crafting_shapeless\u0026#34;, 3 \u0026#34;ingredients\u0026#34;:[ 4 { 5 \u0026#34;tag\u0026#34;:\u0026#34;minecraft:diamond_ores\u0026#34;//不使用item而是使用能包含这一类矿石的标签tag 6 }, 7 { 8 \u0026#34;item\u0026#34;:\u0026#34;minecraft:gold_ore\u0026#34; 9 }, 10 { 11 \u0026#34;item\u0026#34;:\u0026#34;minecraft:emerald_ore\u0026#34; 12 } 13 ], 14 \u0026#34;result\u0026#34;:{ 15 \u0026#34;item\u0026#34;:\u0026#34;minecraft:stone\u0026#34;, 16 \u0026#34;count\u0026#34;:1 17 } 18} (原版不包含的标签也可以自己写，然后引用自己写的标签)\n接下来是有序合成：\n1{ 2 \u0026#34;type\u0026#34;:\u0026#34;minecraft:crafting_shaped\u0026#34;, 3 \u0026#34;pattern\u0026#34;:[ 4 \u0026#34;aaa\u0026#34;, 5 \u0026#34;aba\u0026#34;, 6 \u0026#34;aaa\u0026#34; 7 ], 8 \u0026#34;key\u0026#34;:{ 9 \u0026#34;a\u0026#34;:{ 10 \u0026#34;item\u0026#34;:\u0026#34;minecraft:obsidian\u0026#34; 11 }, 12 \u0026#34;b\u0026#34;:{ 13 \u0026#34;item\u0026#34;:\u0026#34;minecraft:diamond_ore\u0026#34; 14 } 15 }, 16 \u0026#34;result\u0026#34;:{ 17 \u0026#34;item\u0026#34;:\u0026#34;minecraft:totem_of_undying\u0026#34;, 18 \u0026#34;count\u0026#34;:1 19 } 20} blasting\u0026amp;\u0026amp;smelting配方：（高炉\u0026amp;\u0026amp;熔炉）\n熔炉，高炉，烟熏炉都是差不多的，可以举一反三\n篝火也可也编写的，也与上面三者类似，只不过没有experience可以编写\n1{ 2 \u0026#34;type\u0026#34;: \u0026#34;minecraft:blasting\u0026#34;, 3 \u0026#34;ingredient\u0026#34;: { 4 \u0026#34;item\u0026#34;: \u0026#34;minecraft:diamond_block\u0026#34; 5 }, 6 \u0026#34;result\u0026#34;: \u0026#34;minecraft:coal\u0026#34;,//这类result直接填id就好了 7 \u0026#34;experience\u0026#34;: 666,//获得经验值 8 \u0026#34;cookingtime\u0026#34;: 200//所需时间(游戏刻) 9} 切石机比较特殊，count必须写，而且可以写一对多，就是完全一样的配方生成多种不同物品，其他的写法同上；\n锻造台(smithing)：新版需要锻造模版；有点复杂放到后面再说；\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/minecraft/datapacks-notes/","section":"学习笔记","summary":"(详细完整内容请见Minecraft Wiki)\nDatapacks # Simple Introductions # 数据包只针对单个存档，每一个存档都会有一个数据包文件夹（游戏版本\u003esaves\u003e存档名\u003edatapacks)\n数据包以文件夹或者压缩包形式存在于datapacks文件夹中都可以运行，但推荐用压缩包的形式\nvscode所需插件：datapack helper plus by spyglass；syntax-mcfunction\n这两个插件工作的前提是，所创建文件的结构符合官方数据包结构\n所有具体标签名称可以在游戏内先F3+H,鼠标悬浮在物品上就可以查看\n数据包能够实现的效果大致如下:\n技能 / 法术系统 RPG 系统 Boss 战 自定义物品 新维度（部分） 世界生成 生物行为 生存机制 UI / HUD（部分） 动画 / 过场 多人玩法 原版机制增强 解谜 / 恐怖地图 固定文件结构 # data命名空间；\n","title":"Datapacks","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/categories/demo/","section":"Categories","summary":"","title":"Demo","type":"categories"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/demo/","section":"Tags","summary":"","title":"Demo","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/","section":"学习笔记","summary":"","title":"Demo \u0026\u0026 Resources","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/docker/","section":"学习笔记","summary":"","title":"Docker","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/","section":"学习笔记","summary":"","title":"Docs","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/flutter/","section":"学习笔记","summary":"","title":"Flutter","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/git/","section":"学习笔记","summary":"","title":"Git","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/","section":"学习笔记","summary":"","title":"Language","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/minecraft/","section":"学习笔记","summary":"","title":"Minecraft","type":"notes"},{"content":" PatPat 官方 Wiki — 中文完整翻译 # 来源：https://github.com/LopyMine/PatPat/wiki\n翻译整理时间：2026-05-10 | 对应 Wiki 版本：2024-2025\n目录 # 入门：关于自定义动画 创建动画纹理 创建动画配置 3.1 主选项 3.2 \u0026ldquo;animation\u0026rdquo; 对象 3.3 \u0026ldquo;frame\u0026rdquo; 对象 3.4 \u0026ldquo;sound\u0026rdquo; 对象 3.5 \u0026ldquo;entity\u0026rdquo; 对象 3.6 \u0026ldquo;from\u0026rdquo; 对象 3.7 创建你自己的动画配置 添加动画音效 4.1 从 MP3 转换为 OGG 4.2 注册音效 模板资源包 成品资源包 附录：完整示例配置文件 1. 入门：关于自定义动画 # 原文：Getting Started • About Custom Animations\nPatPat 模组的自定义动画可以通过原版资源包机制创建。你的资源包包含三个主要文件：\n文件 是否必需 说明 动画纹理 ✅ 必需 包含所有动画帧的精灵图 动画配置 ✅ 必需 JSON/JSON5 文件，定义动画参数 动画音效 ❌ 可选 自定义音效及 sounds.json 注册 我们试试为 PatPat 模组创建一个自定义动画资源包。\n建议先下载模板资源包开始，但这并非必需。\n2. 创建动画纹理 # 原文：Creating Animation Texture\n自定义动画的核心要素之一是动画纹理。简言之，纹理就是把所有动画帧存放在一张 .png 文件中。\n让我们创建一个包含 2D 活塞动画的纹理。\n第 1 步：首先获取活塞侧面纹理（我从 Minecraft 资产中获得的）：\n第 2 步：打开它，旋转并添加一些帧：\n我会使用 Aseprite 来操作，你可以用任何其他图像编辑软件\n第 3 步：逐帧制作动画：\n第 4 步：保存纹理，完成！\n确认你的最终纹理文件是一个精灵图（spritesheet），所有帧水平排列在一张 PNG 中。\n3. 创建动画配置 # 原文：Creating Animation Config\n现在需要为动画创建配置文件。配置只能是 .json 或 .json5 格式。你可以将此文件放在 assets/patpat/ 下的任何子文件夹中。\nPatPat 模组提供了一个示例配置，含有所有选项。\n下面详细介绍每个选项的用途：\n3.1 主选项 # version # 始于：1.0.0 | 类型：String | 示例：1.5.2\n表示配置文件的版本。这很有必要，以便将来模组能处理旧的配置选项。填写一个不带空格、以点号分隔的三个数字组成的字符串。\npriority # 始于：1.0.0 | 类型：Integer | 示例：10 | 默认值：0\n表示自定义动画的优先级。填写 -2147483648 到 2147483647 之间的整数。\n尽量避免使用最小值和最大值，范围 [-10000, 10000] 完全够用！\n优先级如何工作？（点击展开） 每个自定义动画都有自己的优先级。当玩家与一个实体交互时，第一个满足以下三个条件的自定义动画将被使用：\n实体类型 实体名称 实体 UUID 如果有多个自定义动画满足这些条件，则按以下规则排序：\n如果自定义动画来自不同的资源包，则使用资源包列表中位置更靠上的那个。 如果自定义动画来自同一资源包，则使用 priority 值更高的那个。 如果 priority 相同，则按文件路径字母序排序。 animation # 始于：1.0.0 | 详见 3.2 \u0026ldquo;animation\u0026rdquo; 对象\n包含动画设置，如持续时间、音效等。\nblacklist # 始于：1.0.0 | 类型：Boolean | 示例：false 或 true | 默认值：false\n将 entities 列表切换为白名单模式（false）或黑名单模式（true）。\n如果为 true，则列表作为黑名单——接受所有实体，除了 entities 列表中列出的。 如果为 false，则列表作为白名单——只接受 entities 列表中列出的实体。 entities # 始于：1.0.0 | 详见 3.5 \u0026ldquo;entity\u0026rdquo; 对象\n包含此动画将生效的实体列表。可以设置为 \u0026quot;all\u0026quot; 来选择所有实体。\n3.2 \u0026ldquo;animation\u0026rdquo; 对象 # texture # 始于：1.0.0 | 类型：String | 示例：patpat:textures/path/to/texture.png\n包含动画播放时将使用的纹理路径。\n注意：所有动画纹理必须放在 textures/ 文件夹内，因为模组只在此文件夹中查找纹理！\nduration # 始于：1.0.0 | 类型：Integer | 示例：300\n表示动画持续时间，单位为毫秒（ms）。不能为负数。\nframe # 始于：1.0.0 | 详见 3.3 \u0026ldquo;frame\u0026rdquo; 对象\n包含帧设置，如总帧数、偏移量、缩放等。\nsound # 始于：1.0.0 | 详见 3.4 \u0026ldquo;sound\u0026rdquo; 对象\n指定动画播放时伴随的音效，以及可选的音高和音量范围。\n3.3 \u0026ldquo;frame\u0026rdquo; 对象 # totalFrames # 始于：1.0.0 | 类型：Integer | 示例：5\n表示纹理中的总帧数。\nscaleX # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：0.9\n表示纹理在 X 轴上的缩放。例如，如果值为 2.0，则纹理将放大两倍。\nscaleY # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：0.9\n表示纹理在 Y 轴上的缩放。例如，如果值为 2.0，则纹理将放大两倍。\noffsetX # 始于：1.0.0 | 类型：Double | 示例：-1.5 | 默认值：0.0\n表示纹理在 X 轴上的偏移量。\noffsetY # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：0.0\n表示纹理在 Y 轴上的偏移量。\noffsetZ # 始于：1.0.0 | 类型：Double | 示例：-1.5 | 默认值：0.0\n表示纹理在 Z 轴上的偏移量。\n3.4 \u0026ldquo;sound\u0026rdquo; 对象 # id # 始于：1.0.0 | 类型：String | 示例：patpat:pat_sound\n表示音效 ID。\nminPitch # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：1.0\n表示音效的最小音高值。\n注意：在示例配置中也写作 min_pitch（下划线格式），两者均可。\nmaxPitch # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：1.0\n表示音效的最大音高值。\n注意：在示例配置中也写作 max_pitch（下划线格式），两者均可。\nvolume # 始于：1.0.0 | 类型：Double | 示例：1.5 | 默认值：1.0\n表示音效的音量。\n3.5 \u0026ldquo;entity\u0026rdquo; 对象 # entities 数组中的每个元素可以是字符串（仅 id）或带有更多筛选条件的对象。\nid # 始于：1.0.0 | 类型：String | 示例：minecraft:pig\n表示实体类型。如果此字段不存在，PatPat 模组会跳过此项比较。\nname # 始于：1.0.0 | 类型：String | 示例：My Cute Dog\n表示实体名称。实体名称指的是实体被命名的名字，而非实体类型名。例如，我把我的狗命名为 My Cute Dog，我只想对这个名字的实体使用动画，那就把 My Cute Dog 写在这里。\nuuid # 始于：1.0.0 | 类型：String | 示例：192e3748-12d5-4573-a8a5-479cd394a1dc\n表示实体 UUID。通常你会用它来为某个特定的玩家指定动画，因为每个玩家有唯一的 UUID。例如，只想对玩家 LopyMine 使用动画，把他的 UUID 写在这里。\nfrom # 始于：1.0.0 | 详见 3.6 \u0026ldquo;from\u0026rdquo; 对象\n指定谁可以触发此动画。例如，有两个玩家，但动画只应在其中一人抚摸狗时触发，就可以在此配置。\n3.6 \u0026ldquo;from\u0026rdquo; 对象 # name # 始于：1.0.0 | 类型：String | 示例：nikita51\n表示可以使用此动画的玩家名。例如，你想要一个动画只有你抚摸别人时才生效，那就把你的昵称写在这里。\nuuid # 始于：1.0.0 | 类型：String | 示例：192e3748-12d5-4573-a8a5-479cd394a1dc\n表示玩家 UUID。和 name 功能相同，但使用 UUID。\n3.7 创建你自己的动画配置 # 第 1 步：基于这个示例配置，创建我们自己的简单配置文件：\nanimated_piston.json5\n1{ 2 \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34;, 3 \u0026#34;animation\u0026#34;: { 4 \u0026#34;texture\u0026#34;: \u0026#34;patpat:textures/animated_piston_texture.png\u0026#34;, 5 \u0026#34;duration\u0026#34;: 300, 6 \u0026#34;frame\u0026#34;: { 7 \u0026#34;totalFrames\u0026#34;: 5, 8 \u0026#34;scaleX\u0026#34;: 1, 9 \u0026#34;scaleY\u0026#34;: 1, 10 \u0026#34;offsetX\u0026#34;: 0, 11 \u0026#34;offsetY\u0026#34;: 0, 12 \u0026#34;offsetZ\u0026#34;: 0 13 } 14 }, 15 \u0026#34;entities\u0026#34;: [ 16 \u0026#34;minecraft:zombie\u0026#34; 17 ] 18} 第 2 步：将它保存在与纹理相同的目录中：\n第 3 步：加载资源包进游戏，然后抚摸僵尸看看效果：\n第 4 步：可以看到动画生效了，但我们没听到任何声音——因为我们忘了为动画添加自定义音效。下面我们就来做这件事：\n4. 添加动画音效 # 原文：Adding Animation Sound(s)\n最后，让我们为自定义动画添加音效。其实，如果你曾经通过资源包给 Minecraft 添加过自定义音效，这里并没有什么新东西。\n4.1 从 MP3 转换为 OGG # 第 1 步：先获取所需的声音文件。例如，我从互联网下载了一个活塞激活音效，但它是 .mp3 格式——这个格式行不通。\n第 2 步：我们需要把声音从 .mp3 转换为 .ogg。可以使用任意在线转换工具来完成。\n⚠️ 不能直接重命名文件！ 仅改变扩展名不会改变音频格式。\n第 3 步：好的，现在有了正确的音频格式。剩下的就是注册这个音效了。\n4.2 注册音效 # 第 1 步：首先，将音效文件放入 assets/patpat/sounds/ 文件夹（对我们来说 namespace 就是 patpat）。然后，在 assets/patpat/sounds.json 中注册该音效。\n这是一个简单的 sounds.json 内容示例：\nsounds.json\n1{ 2 \u0026#34;这里填写唯一的音效ID\u0026#34;: { 3 \u0026#34;sounds\u0026#34;: [ 4 \u0026#34;命名空间:这里填写sounds文件夹里的音效文件名（不含.ogg）\u0026#34; 5 ] 6 } 7} 第 2 步：修改成我们的内容：\nsounds.json\n1{ 2 \u0026#34;patpat_piston_sound_id\u0026#34;: { 3 \u0026#34;sounds\u0026#34;: [ 4 \u0026#34;patpat:piston_sound\u0026#34; 5 ] 6 } 7} 第 3 步：最后，告诉 PatPat 模组动画要播放哪个音效。需要编辑 animated_piston.json5，同时指定最小/最大音高和音量。\n以下是我们要添加的内容：\nanimated_piston.json5\n1{ 2 // ... 3 \u0026#34;animation\u0026#34;: { 4 // ... 5 \u0026#34;sound\u0026#34;: { 6 \u0026#34;id\u0026#34;: \u0026#34;patpat:patpat_piston_sound_id\u0026#34;, 7 \u0026#34;minPitch\u0026#34;: 0.5, 8 \u0026#34;maxPitch\u0026#34;: 1.5, 9 \u0026#34;volume\u0026#34;: 0.8 10 } 11 // ... 12 } 13 // ... 14} 查看完整文件（点击展开） animated_piston.json5\n1{ 2 \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34;, 3 \u0026#34;animation\u0026#34;: { 4 \u0026#34;texture\u0026#34;: \u0026#34;patpat:textures/animated_piston.png\u0026#34;, 5 \u0026#34;duration\u0026#34;: 300, 6 7 \u0026#34;sound\u0026#34;: { 8 \u0026#34;id\u0026#34;: \u0026#34;patpat:patpat_piston_sound_id\u0026#34;, 9 \u0026#34;minPitch\u0026#34;: 0.5, 10 \u0026#34;maxPitch\u0026#34;: 1.5, 11 \u0026#34;volume\u0026#34;: 0.8 12 }, 13 14 \u0026#34;frame\u0026#34;: { 15 \u0026#34;totalFrames\u0026#34;: 5, 16 17 \u0026#34;scaleX\u0026#34;: 1, 18 \u0026#34;scaleY\u0026#34;: 1, 19 20 \u0026#34;offsetX\u0026#34;: 0, 21 \u0026#34;offsetY\u0026#34;: 0, 22 \u0026#34;offsetZ\u0026#34;: 0 23 } 24 }, 25 \u0026#34;entities\u0026#34;: [ 26 \u0026#34;minecraft:zombie\u0026#34; 27 ] 28} 第 4 步：现在测试我们的成品资源包！\n5. 模板资源包 # 原文：Template Resource Pack\n你可以从这里下载自定义动画的模板资源包。此资源包包含你需要编辑的文件夹和文件，您可以免费随意使用/修改。\n资源包结构 # 1. 2└── Template Custom Animation/ 3 ├── assets/ 4 │ └── patpat/ 5 │ ├── sounds.json 6 │ ├── sounds/ 7 │ └── texture/ 8 └── pack.mcmeta 6. 成品资源包 # 原文：Ready‑To‑Use Resource Pack\n你可以从这里下载本 Wiki 制作的成品资源包——即活塞自定义动画。你可以免费随意使用/修改。\n资源包结构 # 1. 2└── Piston Custom Animation/ 3 ├── assets/ 4 │ └── patpat/ 5 │ ├── sounds.json 6 │ ├── sounds/ 7 │ │ └── piston_sound.ogg 8 │ └── texture/ 9 │ ├── animated_piston_config.json5 10 │ ├── animated_piston_texture.png 11 │ └── piston_side.png 12 ├── pack.png 13 └── pack.mcmeta 7. 附录：完整示例配置文件 # 来源：PatPat 源码中的示例配置\n以下是从 PatPat 模组源码中提取的官方完整示例配置文件（使用 JSON5 格式，支持注释）：\n1// no j52j 2// 上面这行注释对模组开发者很重要！ 3// 参见 https://github.com/LopyMine/Mossy?tab=readme-ov-file#about-json5-files 4{ 5 \u0026#34;version\u0026#34;: \u0026#34;1.0.1\u0026#34;, 6 \u0026#34;priority\u0026#34;: 1, 7 // 可选，默认 0 8 9 \u0026#34;animation\u0026#34;: { 10 \u0026#34;texture\u0026#34;: \u0026#34;patpat:textures/test1/custom_hand.png\u0026#34;, 11 \u0026#34;duration\u0026#34;: 230, 12 \u0026#34;frame\u0026#34;: { 13 \u0026#34;totalFrames\u0026#34;: 3, 14 // 纹理中的总帧数 15 \u0026#34;scaleX\u0026#34;: 1, 16 // 帧宽缩放，支持浮点数，可选，默认 1 17 \u0026#34;scaleY\u0026#34;: 1, 18 // 帧高缩放，支持浮点数，可选，默认 1 19 \u0026#34;offsetX\u0026#34;: 0, 20 // 可选，默认 0，支持浮点数，如 0.543, 0.2, 0.00002 21 \u0026#34;offsetY\u0026#34;: 0, 22 // 可选，默认 0，支持浮点数，如 0.543, 0.2, 0.00002 23 \u0026#34;offsetZ\u0026#34;: 0 24 // 可选，默认 0，支持浮点数，如 0.543, 0.2, 0.00002 25 }, 26 \u0026#34;sound\u0026#34;: { 27 \u0026#34;id\u0026#34;: \u0026#34;patpat:bonk\u0026#34;, 28 \u0026#34;min_pitch\u0026#34;: 0.9, 29 // 可选，默认 1 30 \u0026#34;max_pitch\u0026#34;: 1.2, 31 // 可选，默认 1 32 \u0026#34;volume\u0026#34;: 2.5 33 // 可选，默认 1 34 } 35 // 也可以简写为： \u0026#34;sound\u0026#34;: \u0026#34;patpat:bonk\u0026#34; 36 }, 37 \u0026#34;blacklist\u0026#34;: false, 38 // 可选，默认为 false 39 // 如果为 true，则该配置对除了 \u0026#34;entities\u0026#34; 以外的所有生物生效 40 41 \u0026#34;entities\u0026#34;: [ 42 \u0026#34;minecraft:goat\u0026#34;, 43 \u0026#34;minecraft:cat\u0026#34;, 44 { 45 \u0026#34;id\u0026#34;: \u0026#34;minecraft:player\u0026#34;, 46 \u0026#34;name\u0026#34;: \u0026#34;LopyMine\u0026#34;, 47 // 可选 48 \u0026#34;uuid\u0026#34;: \u0026#34;192e3748-12d5-4573-a8a5-479cd394a1dc\u0026#34; 49 // 可选 50 }, 51 // 详细的实体信息 52 { 53 \u0026#34;id\u0026#34;: \u0026#34;minecraft:goat\u0026#34;, 54 \u0026#34;name\u0026#34;: \u0026#34;Funny Goat\u0026#34;, 55 // 可选 56 \u0026#34;from\u0026#34;: [ 57 // 可选 58 { 59 \u0026#34;name\u0026#34;: \u0026#34;nikita51\u0026#34;, 60 // 可选 61 \u0026#34;uuid\u0026#34;: \u0026#34;7b829ed59b74428f9b4dede06975fbc1\u0026#34; 62 // 可选 63 } 64 // 如果两个字段都缺失，将抛出错误 65 ] 66 } 67 ] 68 // 或者可以用 \u0026#34;entities\u0026#34;: \u0026#34;minecraft:goat\u0026#34; 来指定单一实体 69} 本文档功能等同 PatPat 官方 Wiki 全部页面内容的中文翻译整合，包括：\nGetting Started • About Custom Animations Creating Animation Texture Creating Animation Config Adding Animation Sound(s) Template Resource Pack Ready‑To‑Use Resource Pack 所有图片均从原 Wiki 引用（raw.githubusercontent.com CDN）。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/minecraft/patpat-wiki/","section":"学习笔记","summary":"PatPat 官方 Wiki — 中文完整翻译 # 来源：https://github.com/LopyMine/PatPat/wiki\n翻译整理时间：2026-05-10 | 对应 Wiki 版本：2024-2025\n目录 # 入门：关于自定义动画 创建动画纹理 创建动画配置 3.1 主选项 3.2 “animation” 对象 3.3 “frame” 对象 3.4 “sound” 对象 3.5 “entity” 对象 3.6 “from” 对象 3.7 创建你自己的动画配置 添加动画音效 4.1 从 MP3 转换为 OGG 4.2 注册音效 模板资源包 成品资源包 附录：完整示例配置文件 1. 入门：关于自定义动画 # 原文：Getting Started • About Custom Animations\n","title":"PatPat 官方 Wiki — 中文完整翻译","type":"notes"},{"content":" PatPat 模组 — 资源包制作指南 # 结合 PatPat 官方 Wiki 与实际操作，涵盖两种修改方式。\n目录 # 两种修改方式 PatPat 模组资产结构 前置条件 方式 A：替换默认动画（简单） A1. 确定 pack_format A2. 处理纹理 A3. 处理音效 A4. 编写 pack.mcmeta A5. 打包 ZIP 方式 B：自定义动画配置（高级） B1. 动画配置文件格式 B2. 配置字段详解 B3. 优先级系统 B4. 自定义音效注册 B5. 完整示例 获取原版 Minecraft 素材 官方模板资源包 常见踩坑 参考链接 两种修改方式 # 方式 A：替换默认资产 方式 B：自定义动画配置 原理 直接覆盖 PatPat 默认的纹理和音效文件 通过 JSON 配置文件添加新动画，可指定实体、触发者、优先级 适用场景 修改所有生物的抚摸效果 为特定实体/玩家制作专属动画 配置复杂度 低（只改文件不改配置） 中（需要编写 .json / .json5 配置） 灵活性 一种动画通用于所有生物 可同时存在多个动画，按实体类型/名称/UUID 匹配 两种方式可以共存 —— 方式 B 的动画会在匹配到特定实体时覆盖方式 A 的默认效果。\nPatPat 模组资产结构 # 从 PatPat-1.2.6+26.1+fabric.jar 解压得到：\n1assets/patpat/ 2├── sounds.json # 默认音效注册表 3├── sounds/ 4│ ├── pat.ogg (9KB) # 抚摸音效变体 1 5│ ├── pat1.ogg (9KB) # 抚摸音效变体 2 6│ ├── pat2.ogg (9KB) # 抚摸音效变体 3 7│ ├── lopi.ogg (16KB) # 彩蛋音效变体 1 8│ ├── lopi1.ogg (15KB) # 彩蛋音效变体 2 9│ ├── lopi2.ogg (17KB) # 彩蛋音效变体 3 10│ └── lopi3.ogg (17KB) # 彩蛋音效变体 4 11├── textures/ 12│ ├── default/patpat.png # 默认动画纹理（560×112，5帧） 13│ ├── cape/patpat_cape_hand.png # 披风纹理（64×32） 14│ ├── config/ # 配置界面图标 15│ └── easter/egg.json # 内置彩蛋配置（山羊 \u0026#34;Снежа\u0026#34;） 16└── lang/ # 140+ 语言文件 默认纹理规格：\n属性 值 文件 textures/default/patpat.png 尺寸 560 × 112（5 帧精灵图） 每帧 112 × 112 格式 PNG, RGBA 默认音效规格：\n属性 值 文件 sounds/pat.ogg / pat1.ogg / pat2.ogg 格式 OGG Vorbis, 单声道 采样率 44100 Hz sounds.json 内容：\n1{ 2 \u0026#34;patpat\u0026#34;: { \u0026#34;sounds\u0026#34;: [\u0026#34;patpat:pat\u0026#34;, \u0026#34;patpat:pat1\u0026#34;, \u0026#34;patpat:pat2\u0026#34;] }, 3 \u0026#34;lopi\u0026#34;: { \u0026#34;sounds\u0026#34;: [\u0026#34;patpat:lopi\u0026#34;, \u0026#34;patpat:lopi1\u0026#34;, \u0026#34;patpat:lopi2\u0026#34;, \u0026#34;patpat:lopi3\u0026#34;] } 4} 前置条件 # 工具 用途 图像编辑器（GIMP / Aseprite / Photoshop / Pillow） 制作/编辑 PNG 纹理 Audacity 或在线转换器 导出 OGG Vorbis 单声道音效（不能只改后缀名） 7-Zip / Python zipfile 打包 ZIP 浏览器 访问 Mojang API 获取原版素材 方式 A：替换默认动画 # 直接覆盖 patpat.png 和 pat*.ogg，改变所有生物的抚摸效果。这是我们实际操作中采用的方式。\nA1. 确定 pack_format # pack_format 是 Minecraft 判断资源包兼容性的版本号。错误的值会导致资源包不显示或不兼容。\nMinecraft 版本 pack_format 1.21.1 34 1.21.4 46 1.21.5 55 26.1 84 自查方法：\n游戏内 F3 + V：右侧显示当前支持的 pack format Minecraft Wiki 完整对照表 1# API 查询（以 26.1 为例） 2curl -s \u0026#34;https://piston-meta.mojang.com/mc/game/version_manifest_v2.json\u0026#34; \\ 3 | jq -r \u0026#39;.versions[] | select(.id==\u0026#34;26.1\u0026#34;) | .url\u0026#39; \\ 4 | xargs curl -s | jq \u0026#39;.pack_version.resource\u0026#39; 5# 输出: {\u0026#34;resource\u0026#34;: 84, \u0026#34;data\u0026#34;: 103} A2. 处理纹理 # 目标路径：assets/patpat/textures/default/patpat.png\n必须为 560 × 112 的精灵图（5 帧 × 112×112）。\n示例：倒置末地烛（Python / Pillow）：\n1from PIL import Image, ImageOps 2 3# 加载原版末地烛纹理（16×16） 4src = Image.open(\u0026#34;end_rod.png\u0026#34;) 5 6# 垂直翻转 → 倒置 7flipped = ImageOps.flip(src) 8 9# 缩放到 112×112（NEAREST 保留像素风格） 10frame = flipped.resize((112, 112), Image.NEAREST) 11 12# 平铺 5 帧 → 560×112 13spritesheet = Image.new(\u0026#34;RGBA\u0026#34;, (560, 112)) 14for i in range(5): 15 spritesheet.paste(frame, (i * 112, 0)) 16 17spritesheet.save(\u0026#34;patpat.png\u0026#34;) 也可以用 Aseprite 逐帧绘制真正的动画（而非 5 帧相同），参考 官方 Wiki：Creating Animation Texture。\nA3. 处理音效 # 目标路径：assets/patpat/sounds/pat.ogg / pat1.ogg / pat2.ogg\n1# 从原版素材复制（以史莱姆音效为例） 2cp slime_big1.ogg pat.ogg 3cp slime_big2.ogg pat1.ogg 4cp slime_small1.ogg pat2.ogg 格式验证：\n1file pat.ogg 2# 期望: Ogg data, Vorbis audio, mono, 44100 Hz 3# ❌ 如果是 stereo → 用 Audacity 重新导出为 Mono A4. 编写 pack.mcmeta # 1{ 2 \u0026#34;pack\u0026#34;: { 3 \u0026#34;description\u0026#34;: \u0026#34;PatPat × 倒置末地烛 + 史莱姆音效\u0026#34;, 4 \u0026#34;pack_format\u0026#34;: 84, 5 \u0026#34;supported_formats\u0026#34;: 84 6 } 7} A5. 打包 ZIP # ⚠️ 最常见的错误：ZIP 多了一层文件夹 # 1❌ 错误： 2my_pack.zip 3└── MyPack/ ← 多余！ 4 ├── pack.mcmeta 5 └── assets/... 6 7✅ 正确： 8my_pack.zip 9├── pack.mcmeta ← 必须在 ZIP 根层级 10└── assets/ 11 └── patpat/ 12 ├── textures/default/patpat.png 13 └── sounds/... 验证 ZIP 结构 # 1python3 -c \u0026#34; 2import zipfile 3with zipfile.ZipFile(\u0026#39;my_pack.zip\u0026#39;, \u0026#39;r\u0026#39;) as zf: 4 for name in zf.namelist(): 5 print(name) 6\u0026#34; 7# 第一行必须是 pack.mcmeta Python 打包脚本 # 1import zipfile, os 2 3src_dir = \u0026#34;my_pack_folder\u0026#34; # 源文件夹 4with zipfile.ZipFile(\u0026#34;my_pack.zip\u0026#34;, \u0026#34;w\u0026#34;, zipfile.ZIP_DEFLATED) as zf: 5 for root, dirs, files in os.walk(src_dir): 6 for f in files: 7 fp = os.path.join(root, f) 8 arcname = os.path.relpath(fp, src_dir) 9 zf.write(fp, arcname) 方式 B：自定义动画配置 # PatPat 支持通过 JSON 配置文件创建专属动画，可精确控制哪些实体触发、谁可以触发、动画参数等。这是官方 Wiki 的核心内容。\n根据 PatPat Wiki — Creating Animation Config，你需要三个文件：\n文件 必需 说明 动画纹理 .png ✅ 精灵图（所有帧放一张图） 动画配置 .json / .json5 ✅ 定义纹理路径、帧数、持续时间、实体匹配规则等 自定义音效 .ogg + sounds.json ❌（可选） 注册新音效事件 配置文件的存放位置：assets/patpat/ 下的任意子目录。\nB1. 动画配置文件格式 # 参考 官方示例配置：\n1// animated_piston.json5（文件名随意，后缀 .json 或 .json5） 2{ 3 \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34;, // 配置版本（必需） 4 \u0026#34;priority\u0026#34;: 10, // 优先级（可选，默认 0） 5 \u0026#34;blacklist\u0026#34;: false, // true=黑名单 / false=白名单（可选，默认 false） 6 \u0026#34;animation\u0026#34;: { 7 \u0026#34;texture\u0026#34;: \u0026#34;patpat:textures/animated_piston.png\u0026#34;, 8 \u0026#34;duration\u0026#34;: 300, // 动画时长（ms） 9 \u0026#34;frame\u0026#34;: { 10 \u0026#34;totalFrames\u0026#34;: 5, // 总帧数 11 \u0026#34;scaleX\u0026#34;: 1.0, // X 轴缩放（默认 0.9） 12 \u0026#34;scaleY\u0026#34;: 1.0, // Y 轴缩放（默认 0.9） 13 \u0026#34;offsetX\u0026#34;: 0.0, // X 轴偏移（默认 0） 14 \u0026#34;offsetY\u0026#34;: 0.0, // Y 轴偏移（默认 0） 15 \u0026#34;offsetZ\u0026#34;: 0.0 // Z 轴偏移（默认 0） 16 }, 17 \u0026#34;sound\u0026#34;: { 18 \u0026#34;id\u0026#34;: \u0026#34;patpat:my_custom_sound_id\u0026#34;, 19 \u0026#34;minPitch\u0026#34;: 0.5, 20 \u0026#34;maxPitch\u0026#34;: 1.5, 21 \u0026#34;volume\u0026#34;: 0.8 22 } 23 }, 24 \u0026#34;entities\u0026#34;: [ 25 // 指定实体（可以是类型字符串或 entity 对象） 26 \u0026#34;minecraft:zombie\u0026#34;, 27 { 28 \u0026#34;id\u0026#34;: \u0026#34;minecraft:sheep\u0026#34;, 29 \u0026#34;name\u0026#34;: \u0026#34;Jeb_\u0026#34;, // 仅匹配名为 \u0026#34;Jeb_\u0026#34; 的羊 30 \u0026#34;from\u0026#34;: { 31 \u0026#34;name\u0026#34;: \u0026#34;LopyMine\u0026#34; // 仅 LopyMine 抚摸时触发 32 } 33 } 34 ] 35} B2. 配置字段详解 # 以下内容来自 PatPat Wiki: Creating Animation Config，标注 ✅ 为必需项。\n主选项 # 字段 类型 默认值 说明 version ✅ String — 配置版本号（如 \u0026quot;1.0.0\u0026quot;），用于未来兼容处理 priority Integer 0 优先级，范围建议 [-10000, 10000] blacklist Boolean false true=黑名单模式 / false=白名单模式 entities ✅ Array — 实体匹配列表，设为 \u0026quot;all\u0026quot; 匹配所有实体 animation 对象 # 字段 类型 默认值 说明 texture ✅ String — 纹理路径，如 \u0026quot;patpat:textures/xxx.png\u0026quot;。纹理必须在 textures/ 目录下 duration ✅ Integer — 动画持续时间（毫秒），不可为负 frame ✅ Object — 帧设置 sound ✅ Object 无 音效设置 frame 对象 # 字段 类型 默认值 说明 totalFrames ✅ Integer — 纹理中的总帧数 scaleX Double 0.9 X 轴缩放比例 scaleY Double 0.9 Y 轴缩放比例 offsetX Double 0.0 X 轴偏移 offsetY Double 0.0 Y 轴偏移 offsetZ Double 0.0 Z 轴偏移 sound 对象 # 字段 类型 默认值 说明 id ✅ String — 音效 ID，如 \u0026quot;patpat:my_sound\u0026quot; minPitch Double 1.0 最小音高 maxPitch Double 1.0 最大音高 volume Double 1.0 音量 entity 对象（entities 数组中每个元素可以是字符串或对象） # 字段 类型 说明 id String 实体类型，如 \u0026quot;minecraft:pig\u0026quot; name String 实体名称（不是类型名），如 \u0026quot;My Cute Dog\u0026quot; uuid String 实体 UUID from.name String 触发者玩家名 from.uuid String 触发者玩家 UUID B3. 优先级系统 # 来源：PatPat Wiki — priority\n当玩家抚摸实体时，PatPat 按以下顺序选择动画：\n筛选匹配当前实体类型 / 实体名称 / 实体 UUID 的动画 如果多个动画匹配同一实体： 不同资源包中 → 使用资源包列表靠上的 同一资源包中 → 使用 priority 值更高的 priority 相同时 → 按文件路径字母序排列 B4. 自定义音效注册 # 来源：PatPat Wiki — Adding Animation Sound(s)\n如果要使用新音效（而非 PatPat 内置的 patpat:patpat 音效事件），需要注册：\n将 .ogg 文件放入 assets/patpat/sounds/ 创建/编辑 assets/patpat/sounds.json： 1{ 2 \u0026#34;my_custom_sound_id\u0026#34;: { 3 \u0026#34;sounds\u0026#34;: [\u0026#34;patpat:my_sound_file_name\u0026#34;] 4 } 5} 在动画配置中引用： 1\u0026#34;sound\u0026#34;: { 2 \u0026#34;id\u0026#34;: \u0026#34;patpat:my_custom_sound_id\u0026#34;, 3 \u0026#34;minPitch\u0026#34;: 0.8, 4 \u0026#34;maxPitch\u0026#34;: 1.2, 5 \u0026#34;volume\u0026#34;: 1.0 6} ⚠️ 如果 sounds.json 格式有误，整个文件会被忽略。使用 JSON 校验器检查。\nB5. 完整示例 # 以下是一个为僵尸定制活塞动画的资源包结构：\n1MyPatPatAnimation/ 2├── pack.mcmeta 3└── assets/ 4 └── patpat/ 5 ├── textures/ 6 │ └── animated_piston.png # 活塞精灵图 7 ├── sounds/ 8 │ └── piston_sound.ogg # 自定义音效 9 ├── sounds.json # 音效注册 10 └── my_animations/ 11 └── animated_piston.json5 # 动画配置 对应的 pack.mcmeta：\n1{ 2 \u0026#34;pack\u0026#34;: { 3 \u0026#34;description\u0026#34;: \u0026#34;PatPat × 自定义活塞动画\u0026#34;, 4 \u0026#34;pack_format\u0026#34;: 84, 5 \u0026#34;supported_formats\u0026#34;: 84 6 } 7} 获取原版 Minecraft 素材 # 如果希望借用原版 Minecraft 纹理或音效（如末地烛、史莱姆声音），可从 Mojang 官方服务器下载。\n从 Asset Index 获取 # 1# 1. 获取版本元数据 2VER=\u0026#34;26.1\u0026#34; 3VER_URL=$(curl -s \u0026#34;https://piston-meta.mojang.com/mc/game/version_manifest_v2.json\u0026#34; \\ 4 | python3 -c \u0026#34;import sys,json; d=json.load(sys.stdin); \\ 5 [print(v[\u0026#39;url\u0026#39;]) for v in d[\u0026#39;versions\u0026#39;] if v[\u0026#39;id\u0026#39;]==\u0026#39;$VER\u0026#39;]\u0026#34;) 6 7# 2. 获取 asset index URL 8ASSET_IDX=$(curl -s \u0026#34;$VER_URL\u0026#34; \\ 9 | python3 -c \u0026#34;import sys,json; print(json.load(sys.stdin)[\u0026#39;assetIndex\u0026#39;][\u0026#39;url\u0026#39;])\u0026#34;) 10 11# 3. 搜索目标文件 12curl -s \u0026#34;$ASSET_IDX\u0026#34; | python3 -c \u0026#34; 13import sys,json 14d=json.load(sys.stdin) 15for path, info in d[\u0026#39;objects\u0026#39;].items(): 16 if \u0026#39;end_rod\u0026#39; in path or \u0026#39;slime\u0026#39; in path: 17 print(f\u0026#39;{path} -\u0026gt; {info[\\\u0026#34;hash\\\u0026#34;]}\u0026#39;) 18\u0026#34; 输出示例：\n1minecraft/textures/block/end_rod.png -\u0026gt; \u0026lt;sha1_hash\u0026gt; 2minecraft/sounds/mob/slime/big1.ogg -\u0026gt; b5eca1979e69271b2065ac67ba2c37b5afac0f98 下载文件 # 1https://resources.download.minecraft.net/{hash前2位}/{完整hash} 1# 例 2curl -o big1.ogg \\ 3 \u0026#34;https://resources.download.minecraft.net/b5/b5eca1979e69271b2065ac67ba2c37b5afac0f98\u0026#34; 从客户端 JAR 提取（纹理） # 部分纹理也可直接从客户端 JAR 解压：\n1curl -o client.jar \u0026#34;\u0026lt;version.json 中 downloads.client.url\u0026gt;\u0026#34; 2unzip client.jar \u0026#34;assets/minecraft/textures/block/end_rod.png\u0026#34; 官方模板资源包 # PatPat 官方提供了模板资源包，结构如下：\n1Template Custom Animation/ 2├── pack.mcmeta 3└── assets/ 4 └── patpat/ 5 ├── sounds.json 6 ├── sounds/ 7 └── texture/ 可以直接下载后修改。官方 Wiki 也有一个成品示例（活塞动画资源包）。\n常见踩坑 # 症状 原因 解决 资源包不显示在列表中 pack_format 版本号不对 用 F3+V 确认当前版本值 显示但标记**\u0026ldquo;不兼容\u0026rdquo;** pack_format 太低（如 34 用于 26.1） 更新为正确值（26.1 = 84） 显示**\u0026ldquo;已损坏\u0026rdquo;** ZIP 根结构错误 / JSON 语法错误 pack.mcmeta 必须在 ZIP 根层级 纹理显示异常 尺寸不匹配 默认纹理必须 560×112；自定义动画纹理可任意尺寸 音效无声 OGG 是立体声而非单声道 Audacity → 导出 Mono sounds.json 内所有音效全部失效 JSON 格式错误（缺少逗号/引号） 用 JSON 校验器检查语法 自定义动画不生效 实体匹配规则不满足 / version 字段缺失 检查 entities 配置和 version 字段 F3+T 重载后不变 未启用资源包或优先级太低 选项→资源包 → 移到列表顶部 调试快捷键 # 快捷键 作用 F3 + V 显示当前支持的 pack_format / data pack version F3 + T 重新加载所有资源包（无需重启游戏） 参考链接 # 资源 链接 PatPat 官方 Wiki — 入门 https://github.com/LopyMine/PatPat/wiki/Getting-Started-%E2%80%A2-About-Custom-Animations PatPat Wiki — 创建动画纹理 https://github.com/LopyMine/PatPat/wiki/Creating-Animation-Texture PatPat Wiki — 创建动画配置 https://github.com/LopyMine/PatPat/wiki/Creating-Animation-Config PatPat Wiki — 添加音效 https://github.com/LopyMine/PatPat/wiki/Adding-Animation-Sound(s) PatPat Wiki — 模板资源包 https://github.com/LopyMine/PatPat/wiki/Template-Resource-Pack PatPat 官方配置示例 https://github.com/LopyMine/PatPat/blob/master/src/main/resources/example/example_custom_animation_config.json5 PatPat 模组源码 https://github.com/LopyMine/PatPat Minecraft Wiki — Pack format https://minecraft.wiki/w/Pack_format Minecraft Wiki — pack.mcmeta https://minecraft.wiki/w/Pack.mcmeta Minecraft Wiki — Resource Pack https://minecraft.wiki/w/Resource_Pack Minecraft Wiki — sounds.json https://minecraft.wiki/w/Sounds.json Mojang 版本清单 API https://piston-meta.mojang.com/mc/game/version_manifest_v2.json Mojang 资源 CDN https://resources.download.minecraft.net/ Fabric 官方文档 https://docs.fabricmc.net/ 本文档结合 PatPat 官方 Wiki（2024-2025）与实际操作验证，在 Minecraft 26.1（Fabric）上测试通过。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/demo/minecraft/patpat-guide/","section":"学习笔记","summary":"PatPat 模组 — 资源包制作指南 # 结合 PatPat 官方 Wiki 与实际操作，涵盖两种修改方式。\n目录 # 两种修改方式 PatPat 模组资产结构 前置条件 方式 A：替换默认动画（简单） A1. 确定 pack_format A2. 处理纹理 A3. 处理音效 A4. 编写 pack.mcmeta A5. 打包 ZIP 方式 B：自定义动画配置（高级） B1. 动画配置文件格式 B2. 配置字段详解 B3. 优先级系统 B4. 自定义音效注册 B5. 完整示例 获取原版 Minecraft 素材 官方模板资源包 常见踩坑 参考链接 两种修改方式 # 方式 A：替换默认资产 方式 B：自定义动画配置 原理 直接覆盖 PatPat 默认的纹理和音效文件 通过 JSON 配置文件添加新动画，可指定实体、触发者、优先级 适用场景 修改所有生物的抚摸效果 为特定实体/玩家制作专属动画 配置复杂度 低（只改文件不改配置） 中（需要编写 .json / .json5 配置） 灵活性 一种动画通用于所有生物 可同时存在多个动画，按实体类型/名称/UUID 匹配 两种方式可以共存 —— 方式 B 的动画会在匹配到特定实体时覆盖方式 A 的默认效果。\n","title":"PatPat 模组 — 资源包制作指南","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/python/","section":"学习笔记","summary":"","title":"Python","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/language/python/python-note/","section":"学习笔记","summary":"","title":"Python · Note","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/scripts/","section":"Tags","summary":"","title":"Scripts","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/categories/tools/","section":"Categories","summary":"","title":"Tools","type":"categories"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/tools/","section":"Tags","summary":"","title":"Tools","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/ubuntu/","section":"Tags","summary":"","title":"Ubuntu","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/vscode/","section":"Tags","summary":"","title":"Vscode","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/vscode/","section":"学习笔记","summary":"","title":"VSCode","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/tags/windows/","section":"Tags","summary":"","title":"Windows","type":"tags"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/","section":"学习笔记","summary":"","title":"WSL2","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/fix/","section":"学习笔记","summary":"","title":"WSL2 · Fix","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/hermes/","section":"学习笔记","summary":"","title":"WSL2 · Hermes","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/wsl2/opencode/","section":"学习笔记","summary":"","title":"WSL2 · Opencode","type":"notes"},{"content":"🛠 这里收录日常折腾出来的小脚本。文件即说明 — 大部分脚本打开看注释就能用，不必单独写文档。\n✦ 文件目录 # ▸ 📁 Ubuntu › hyper-v install.cmd ▸ 📁 VScode › VS code settings.png › setup_cpp.bat ▸ 📁 Windows › auto_shutdown_2am.bat › auto_shutdown_4am.bat ▸ 📁 py_scripts ▸ 📁 files_conversion › cpp2md.py › dev-cpp_to_md.py ▸ 📁 files_fix › nbt-fixer.py ✦ 分类速览 # 文件类型 用途 跑法 .bat / .cmd Windows 批处理（自动关机 / 环境配置） 双击运行 .py 通用 Python 工具（文件转换 / 修复） python xxx.py .png 示意图 / 配置截图 仅展示 ⚠️ 部分 .bat 含管理员操作，下载后先看一眼再跑 — 里面都有注释。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/tools/","section":"学习笔记","summary":"🛠 这里收录日常折腾出来的小脚本。文件即说明 — 大部分脚本打开看注释就能用，不必单独写文档。\n✦ 文件目录 # ▸ 📁 Ubuntu › hyper-v install.cmd ▸ 📁 VScode › VS code settings.png › setup_cpp.bat ▸ 📁 Windows › auto_shutdown_2am.bat › auto_shutdown_4am.bat ▸ 📁 py_scripts ▸ 📁 files_conversion › cpp2md.py › dev-cpp_to_md.py ▸ 📁 files_fix › nbt-fixer.py ✦ 分类速览 # 文件类型 用途 跑法 .bat / .cmd Windows 批处理（自动关机 / 环境配置） 双击运行 .py 通用 Python 工具（文件转换 / 修复） python xxx.py .png 示意图 / 配置截图 仅展示 ⚠️ 部分 .bat 含管理员操作，下载后先看一眼再跑 — 里面都有注释。\n","title":"工具箱 · Scripts","type":"notes"},{"content":"","date":"2026-01-01","externalUrl":null,"permalink":"/notes/docs/apps/","section":"学习笔记","summary":"","title":"其他 Apps","type":"notes"},{"content":" /Vault/docs/ Docs 环境配置 · 工具使用 Docker / Git / VSCode / WSL2 / Flutter / 其他工具的折腾记录\nWSL2 \u0026#43; Hyper-V \u0026#43; Ubuntu 一键安装 Docker Desktop 部署 Dify \u0026#43; 本地大模型 Git 常用命令 / 多账号配置 #docker #git #wsl #vscode #flutter /Vault/language/ Language 开发语言 · 算法笔记 C\u0026#43;\u0026#43; 算法 / Python 语法 / ACM 模板\nC\u0026#43;\u0026#43; 算法笔记（DP / 图论 / 字符串） C\u0026#43;\u0026#43; 算法模板集（50\u0026#43; 代码块） Pycharm 使用指南 #cpp #python #algorithm /Vault/demo/ Demo \u0026amp;\u0026amp; Resources AI 入门 · Minecraft · Agent AI 学院练习 / Minecraft 数据包 / 资源包 / 材质 / Agent\nAI Python 入门练习（40\u0026#43; 脚本） Minecraft 数据包 / 资源包 笔记 PatPat 资源包 wiki 全集 #ai #minecraft #agent #crawler /Vault/tools/ Tools 日常脚本 Windows / Ubuntu / VSCode / Python 工具脚本\nWindows 自动关机脚本 VSCode C\u0026#43;\u0026#43; 环境一键配置 Python 文件转换 / 修复工具 #windows #ubuntu #vscode #script ✦ 📁 数据源：/Vault/（只读）。新增内容后，把对应章节同步进 data/vault.yaml 即可在此处显示。\n全部文章 # 这里会列出 /notes/ 下的所有 .md（按时间倒序）。\n","date":"2026-01-01","externalUrl":null,"permalink":"/notes/","section":"学习笔记","summary":" /Vault/docs/ Docs 环境配置 · 工具使用 Docker / Git / VSCode / WSL2 / Flutter / 其他工具的折腾记录\nWSL2 + Hyper-V + Ubuntu 一键安装 Docker Desktop 部署 Dify + 本地大模型 Git 常用命令 / 多账号配置 #docker #git #wsl #vscode #flutter /Vault/language/ Language 开发语言 · 算法笔记 C++ 算法 / Python 语法 / ACM 模板\n","title":"学习笔记","type":"notes"},{"content":" 我是谁 # 📌 这是模板页。把下面的占位文本替换成你自己的内容。\n名字： 在读 / 在职： 坐标： 专注方向： 我在做什么 # 一两句话说明你最近在忙什么 —— 学期项目、实习、折腾的副业、个人项目。\n技术栈 # 按熟悉程度排列：\n常用：xxx, xxx, xxx 会用：xxx, xxx 在学：xxx, xxx 联系方式 # GitHub：https://github.com/ 邮箱：mailto: 其他：xxx 模板使用说明 # 这页是 content/about/_index.md，编辑后保存即可。 顶栏的「关于我」会自动指向这里。 想删就删掉这个文件，不会影响其他模块。\n","externalUrl":null,"permalink":"/about/","section":"关于我","summary":"我是谁 # 📌 这是模板页。把下面的占位文本替换成你自己的内容。\n名字： 在读 / 在职： 坐标： 专注方向： 我在做什么 # 一两句话说明你最近在忙什么 —— 学期项目、实习、折腾的副业、个人项目。\n技术栈 # 按熟悉程度排列：\n常用：xxx, xxx, xxx 会用：xxx, xxx 在学：xxx, xxx 联系方式 # GitHub：https://github.com/ 邮箱：mailto: 其他：xxx 模板使用说明 # 这页是 content/about/_index.md，编辑后保存即可。 顶栏的「关于我」会自动指向这里。 想删就删掉这个文件，不会影响其他模块。\n","title":"关于我","type":"about"},{"content":" ✦ 还没想好喵\n占位说明 # 每篇 markdown 标题是日期或主题，下面随便写就好。\n","externalUrl":null,"permalink":"/life/","section":"生活","summary":"✦ 还没想好喵\n占位说明 # 每篇 markdown 标题是日期或主题，下面随便写就好。\n","title":"生活","type":"life"},{"content":" ✦ 🛠 这里以后会放一些 vibe coding 项目、Agent 实验、小工具… 每条作品用一张卡 + 简短描述 + 链接表示。\n占位说明 # 想加作品？在 data/works.yaml 里登记一条，再放一篇 markdown 进来即可。 或者直接在下面用 markdown 自由写也行 — 这个模块不会被任何数据驱动。 ","externalUrl":null,"permalink":"/works/","section":"作品","summary":"✦ 🛠 这里以后会放一些 vibe coding 项目、Agent 实验、小工具… 每条作品用一张卡 + 简短描述 + 链接表示。\n占位说明 # 想加作品？在 data/works.yaml 里登记一条，再放一篇 markdown 进来即可。 或者直接在下面用 markdown 自由写也行 — 这个模块不会被任何数据驱动。 ","title":"作品","type":"works"}]