<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>YiXuanYun</title>
  
  <subtitle>亦轩云</subtitle>
  <link href="https://home.y1xuanyun.cn/atom.xml" rel="self"/>
  
  <link href="https://home.y1xuanyun.cn/"/>
  <updated>2026-05-21T09:00:00.000Z</updated>
  <id>https://home.y1xuanyun.cn/</id>
  
  <author>
    <name>亦轩云</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Unity开发方向暑期实习考核</title>
    <link href="https://home.y1xuanyun.cn/posts/26u3d01.html"/>
    <id>https://home.y1xuanyun.cn/posts/26u3d01.html</id>
    <published>2026-05-20T03:00:00.000Z</published>
    <updated>2026-05-21T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<hr><h2 id="一、项目概述">一、项目概述</h2><table><thead><tr><th>项目信息</th><th>详情</th></tr></thead><tbody><tr><td>项目名称</td><td>倭瓜射手大冒险</td></tr><tr><td>游戏类型</td><td>横版自动前进弹跳射击跑酷</td></tr><tr><td>开发引擎</td><td>Unity（2D 模式）</td></tr><tr><td>编程语言</td><td>C#</td></tr><tr><td>核心玩法</td><td>玩家操控融合倭瓜与豌豆射手特征的植物角色，通过跳跃躲避敌人、自动射击消灭敌人，收集武器道具增强火力，挑战无限递增难度</td></tr></tbody></table><h3 id="项目文件结构">项目文件结构</h3><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">Assets<span class="regexp">/code/</span>Scripts/</span><br><span class="line">├── Background/          <span class="comment"># 背景滚动与地面管理</span></span><br><span class="line">│   ├── BackgroundScroll.cs</span><br><span class="line">│   └── GroundManager.cs</span><br><span class="line">├── Bullets/             <span class="comment"># 子弹系统</span></span><br><span class="line">│   └── Bullet.cs</span><br><span class="line">├── Enemies/             <span class="comment"># 敌人系统</span></span><br><span class="line">│   ├── Enemy.cs</span><br><span class="line">│   └── EnemySpawner.cs</span><br><span class="line">├── Managers/            <span class="comment"># 全局管理器</span></span><br><span class="line">│   ├── GameManager.cs</span><br><span class="line">│   └── AudioManager.cs</span><br><span class="line">├── Player/              <span class="comment"># 玩家控制</span></span><br><span class="line">│   └── PlayerController.cs</span><br><span class="line">├── Powerups/            <span class="comment"># 道具系统</span></span><br><span class="line">│   ├── Powerup.cs</span><br><span class="line">│   └── PowerupSpawner.cs</span><br><span class="line">└── UI/                  <span class="comment"># 界面系统</span></span><br><span class="line">    ├── UIManager.cs</span><br><span class="line">    └── GameInfoDisplay.cs</span><br></pre></td></tr></table></figure><hr><h2 id="二、架构设计与设计模式">二、架构设计与设计模式</h2><h3 id="2-1-单例模式（Singleton-Pattern）">2.1 单例模式（Singleton Pattern）</h3><p>项目中有三个核心管理器使用了单例模式：<code>GameManager</code>、<code>AudioManager</code>、<code>GroundManager</code>。</p><p><strong>实现方式</strong>：在 <code>Awake()</code> 中进行实例检测，保证全局唯一访问点。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GameManager.cs</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> GameManager Instance &#123; <span class="keyword">get</span>; <span class="keyword">private</span> <span class="keyword">set</span>; &#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Awake</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (Instance == <span class="literal">null</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        Instance = <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        Destroy(gameObject);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>为什么用单例</strong>：GameManager 需要全局访问游戏状态（分数、生命、暂停等），AudioManager 需要跨场景保持音乐播放，GroundManager 提供全局地面 Y 坐标引用</li><li><strong><code>Destroy(gameObject)</code> 的作用</strong>：防止场景中存在多个单例实例，确保唯一性</li><li><strong>AudioManager 额外使用 <code>DontDestroyOnLoad</code></strong>：音乐需要在场景切换时不被销毁，实现跨场景持续播放</li><li><strong><code>&#123; get; private set; &#125;</code> 的意义</strong>：外部只能读取实例引用，不能修改，保证单例的不可变性和安全性</li></ul><h3 id="2-2-组件化架构（Component-Based-Architecture）">2.2 组件化架构（Component-Based Architecture）</h3><p>项目遵循 Unity 的组件化设计理念，每个脚本职责单一：</p><table><thead><tr><th>组件</th><th>职责</th></tr></thead><tbody><tr><td><code>GameManager</code></td><td>游戏状态管理、分数、生命、暂停/恢复</td></tr><tr><td><code>PlayerController</code></td><td>玩家输入处理、跳跃、射击、武器切换</td></tr><tr><td><code>Enemy</code></td><td>敌人个体行为（移动、受击、动画）</td></tr><tr><td><code>EnemySpawner</code></td><td>敌人生成逻辑与难度递增</td></tr><tr><td><code>Bullet</code></td><td>子弹飞行、碰撞检测、爆炸逻辑</td></tr><tr><td><code>Powerup</code></td><td>道具下落与滚动</td></tr><tr><td><code>PowerupSpawner</code></td><td>道具随机生成</td></tr><tr><td><code>BackgroundScroll</code></td><td>多层视差滚动</td></tr><tr><td><code>GroundManager</code></td><td>全局地面坐标提供</td></tr><tr><td><code>UIManager</code></td><td>所有 UI 面板的显示/隐藏与交互</td></tr><tr><td><code>GameInfoDisplay</code></td><td>游戏内实时信息展示</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li>职责分离使得每个组件可独立测试和修改</li><li>Spawner 与实体分离，生成逻辑与个体行为解耦</li><li>UI 层与逻辑层分离，UIManager 仅负责显示，不包含业务逻辑</li></ul><h3 id="2-3-状态机思想（State-Management）">2.3 状态机思想（State Management）</h3><p><code>GameManager</code> 通过布尔标志管理游戏状态：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="built_in">bool</span> IsGameOver &#123; <span class="keyword">get</span>; <span class="keyword">private</span> <span class="keyword">set</span>; &#125;</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">bool</span> IsPaused &#123; <span class="keyword">get</span>; <span class="keyword">private</span> <span class="keyword">set</span>; &#125;</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">bool</span> IsInMainMenu &#123; <span class="keyword">get</span>; <span class="keyword">private</span> <span class="keyword">set</span>; &#125;</span><br></pre></td></tr></table></figure><p>所有游戏对象在 <code>Update()</code> 开头检查状态，决定是否执行逻辑：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (GameManager.Instance.IsGameOver || GameManager.Instance.IsPaused) <span class="keyword">return</span>;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li>这是一种轻量级的状态控制，避免了正式状态机的复杂度</li><li>通过 <code>Time.timeScale = 0f</code> 实现暂停效果，所有基于 <code>Time.deltaTime</code> 的逻辑自动停止</li><li>状态属性使用 <code>&#123; get; private set; &#125;</code>，外部只读，仅 GameManager 内部可修改</li></ul><hr><h2 id="三、玩家系统">三、玩家系统</h2><h3 id="3-1-跳跃系统（二段跳-自动弹跳）">3.1 跳跃系统（二段跳 + 自动弹跳）</h3><p><strong>核心实现</strong>：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="built_in">bool</span> hasGroundJump;  <span class="comment">// 是否有地面跳跃机会</span></span><br><span class="line"><span class="keyword">private</span> <span class="built_in">bool</span> hasAirJump;     <span class="comment">// 是否有空中跳跃机会</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleInput</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">bool</span> wantJump = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (Input.GetMouseButtonDown(<span class="number">0</span>))</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (EventSystem.current != <span class="literal">null</span> &amp;&amp; EventSystem.current.IsPointerOverGameObject())</span><br><span class="line">            <span class="keyword">return</span>;  <span class="comment">// 防止点击UI时触发跳跃</span></span><br><span class="line">        wantJump = <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (Input.GetKeyDown(KeyCode.Space))</span><br><span class="line">        wantJump = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (wantJump)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (hasGroundJump)</span><br><span class="line">        &#123;</span><br><span class="line">            DoJump(jumpForce);</span><br><span class="line">            hasGroundJump = <span class="literal">false</span>;</span><br><span class="line">            hasAirJump = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (hasAirJump)</span><br><span class="line">        &#123;</span><br><span class="line">            DoJump(jumpForce * <span class="number">0.85f</span>);  <span class="comment">// 二段跳力度衰减</span></span><br><span class="line">            hasAirJump = <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>双标志位设计</strong>：<code>hasGroundJump</code> 和 <code>hasAirJump</code> 两个布尔值实现二段跳，比计数器方式更清晰</li><li><strong>二段跳力度衰减</strong>：<code>jumpForce * 0.85f</code>，让二段跳略弱于一段跳，手感更自然</li><li><strong>UI 穿透防护</strong>：<code>IsPointerOverGameObject()</code> 防止点击 UI 按钮时误触发跳跃</li><li><strong>着地重置</strong>：在 <code>FixedUpdate</code> 中检测着地时重置跳跃状态</li></ul><h3 id="3-2-自动弹跳（Auto-Bounce）">3.2 自动弹跳（Auto Bounce）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleAutoBounce</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (!isGrounded) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    bounceTimer += Time.deltaTime;</span><br><span class="line">    <span class="keyword">if</span> (bounceTimer &gt;= bounceInterval)</span><br><span class="line">    &#123;</span><br><span class="line">        rb.velocity = <span class="keyword">new</span> Vector2(rb.velocity.x, bounceForce);</span><br><span class="line">        bounceTimer = <span class="number">0f</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li>角色在地面时自动周期性弹跳，营造&quot;倭瓜蹦跳&quot;的生动感</li><li>仅在 <code>isGrounded</code> 时触发，空中不弹跳</li></ul><h3 id="3-3-着地检测（FixedUpdate-物理检测）">3.3 着地检测（FixedUpdate 物理检测）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">FixedUpdate</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    wasGrounded = isGrounded;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (transform.position.y &lt;= groundY + <span class="number">0.5f</span> &amp;&amp; rb.velocity.y &lt;= <span class="number">0.1f</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        rb.velocity = <span class="keyword">new</span> Vector2(rb.velocity.x, <span class="number">0f</span>);</span><br><span class="line">        rb.position = <span class="keyword">new</span> Vector2(rb.position.x, groundY + <span class="number">0.5f</span>);</span><br><span class="line">        isGrounded = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!wasGrounded)</span><br><span class="line">        &#123;</span><br><span class="line">            hasGroundJump = <span class="literal">true</span>;</span><br><span class="line">            hasAirJump = <span class="literal">false</span>;</span><br><span class="line">            TriggerSquash(<span class="literal">true</span>);  <span class="comment">// 触发着地压扁动画</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        isGrounded = <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>为什么用 <code>FixedUpdate</code></strong>：物理检测放在 <code>FixedUpdate</code> 中保证与物理引擎同步，避免 <code>Update</code> 帧率不稳定导致的穿透问题</li><li><strong>双重条件检测</strong>：<code>position.y &lt;= groundY + 0.5f &amp;&amp; velocity.y &lt;= 0.1f</code>，位置和速度同时判断，防止上升阶段误判着地</li><li><strong><code>wasGrounded</code> 标志</strong>：区分&quot;持续在地面&quot;和&quot;刚着地&quot;两种状态，只在刚着地时触发压扁动画和跳跃重置</li></ul><h3 id="3-4-Squash-Stretch-动画（挤压拉伸）">3.4 Squash &amp; Stretch 动画（挤压拉伸）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleSquashStretch</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (!isSquashing)</span><br><span class="line">    &#123;</span><br><span class="line">        transform.localScale = Vector3.Lerp(transform.localScale, originalScale, Time.deltaTime * <span class="number">10f</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    squashTimer += Time.deltaTime;</span><br><span class="line">    <span class="built_in">float</span> t = squashTimer / squashDuration;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (t &gt;= <span class="number">1f</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        isSquashing = <span class="literal">false</span>;</span><br><span class="line">        transform.localScale = originalScale;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">float</span> squash = Mathf.Sin(t * Mathf.PI);</span><br><span class="line">    <span class="keyword">if</span> (squashIsLand)  <span class="comment">// 着地：横向拉伸，纵向压扁</span></span><br><span class="line">    &#123;</span><br><span class="line">        transform.localScale = <span class="keyword">new</span> Vector3(</span><br><span class="line">            originalScale.x * (<span class="number">1f</span> + squash * squashAmount),</span><br><span class="line">            originalScale.y * (<span class="number">1f</span> - squash * squashAmount),</span><br><span class="line">            originalScale.z</span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>  <span class="comment">// 起跳：纵向拉伸，横向收缩</span></span><br><span class="line">    &#123;</span><br><span class="line">        transform.localScale = <span class="keyword">new</span> Vector3(</span><br><span class="line">            originalScale.x * (<span class="number">1f</span> - squash * squashAmount * <span class="number">0.7f</span>),</span><br><span class="line">            originalScale.y * (<span class="number">1f</span> + squash * squashAmount),</span><br><span class="line">            originalScale.z</span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>动画12原则之 Squash &amp; Stretch</strong>：经典动画原理，着地时压扁、起跳时拉伸，增强角色动态感</li><li><strong><code>Mathf.Sin(t * Mathf.PI)</code> 曲线</strong>：0→1→0 的平滑过渡，比线性插值更有弹性感</li><li><strong>方向区分</strong>：着地和起跳的挤压方向相反，通过 <code>squashIsLand</code> 标志区分</li><li><strong>Lerp 回弹</strong>：非激活状态时用 <code>Lerp</code> 平滑恢复原始缩放，避免突变</li></ul><h3 id="3-5-武器系统">3.5 武器系统</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="built_in">enum</span> WeaponType &#123; Pea, CornCannon, MachineGun &#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleShooting</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    fireTimer += Time.deltaTime;</span><br><span class="line">    <span class="built_in">float</span> fireRate = currentWeapon == WeaponType.MachineGun ? machineGunFireRate :</span><br><span class="line">                     currentWeapon == WeaponType.CornCannon ? cornFireRate : peaFireRate;</span><br><span class="line">    <span class="keyword">if</span> (fireTimer &gt;= fireRate)</span><br><span class="line">    &#123;</span><br><span class="line">        GameObject prefab = currentWeapon == WeaponType.MachineGun ? machineGunBulletPrefab :</span><br><span class="line">                            currentWeapon == WeaponType.CornCannon ? cornBulletPrefab : peaBulletPrefab;</span><br><span class="line">        <span class="keyword">if</span> (prefab != <span class="literal">null</span> &amp;&amp; firePoint != <span class="literal">null</span>)</span><br><span class="line">            Instantiate(prefab, firePoint.position, firePoint.rotation);</span><br><span class="line">        fireTimer = <span class="number">0f</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><table><thead><tr><th>武器类型</th><th>射速</th><th>子弹类型</th><th>特点</th></tr></thead><tbody><tr><td>豌豆（Pea）</td><td>0.5s/发</td><td>普通子弹</td><td>基础武器，永久可用</td></tr><tr><td>机枪豌豆（MachineGun）</td><td>0.1s/发</td><td>普通子弹</td><td>高速连射，火力压制</td></tr><tr><td>玉米大炮（CornCannon）</td><td>1s/发</td><td>爆炸子弹</td><td>范围伤害，清场利器</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li><strong>枚举驱动</strong>：<code>WeaponType</code> 枚举统一管理武器类型，避免魔法字符串</li><li><strong>计时器射击</strong>：<code>fireTimer</code> 累加 <code>Time.deltaTime</code>，达到射速间隔时发射，实现自动射击</li><li><strong>限时机制</strong>：武器道具持续 <code>weaponDuration</code>（3秒）后自动切回豌豆</li><li><strong>嘴部精灵切换</strong>：<code>UpdateMouthSprite()</code> 根据当前武器切换角色嘴部外观，增强视觉反馈</li></ul><hr><h2 id="四、敌人系统">四、敌人系统</h2><h3 id="4-1-敌人行为状态机">4.1 敌人行为状态机</h3><p>敌人有两个行为阶段：<strong>下落阶段</strong> 和 <strong>地面阶段</strong>。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Update</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (!isGrounded)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 阶段1：从空中下落</span></span><br><span class="line">        transform.Translate(Vector3.down * fallSpeed * Time.deltaTime);</span><br><span class="line">        <span class="keyword">if</span> (transform.position.y &lt;= groundY + <span class="number">0.5f</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            isGrounded = <span class="literal">true</span>;</span><br><span class="line">            transform.position = <span class="keyword">new</span> Vector3(transform.position.x, groundY + <span class="number">0.5f</span>, transform.position.z);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 阶段2：地面移动 + 空闲动画</span></span><br><span class="line">        <span class="built_in">float</span> speed = GameManager.Instance.GetCurrentScrollSpeed() + moveSpeed;</span><br><span class="line">        transform.Translate(Vector3.left * speed * Time.deltaTime);</span><br><span class="line">        HandleIdleAnimation();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>两阶段设计</strong>：敌人从空中落下（增加视觉变化），着地后随背景滚动左移</li><li><strong>速度叠加</strong>：<code>scrollSpeed + moveSpeed</code>，敌人移动速度 = 背景滚动速度 + 自身移动速度，保证敌人始终向左移动</li><li><strong><code>OnBecameInvisible</code> 清理</strong>：离开屏幕左侧 15 单位后自动销毁，防止内存泄漏</li></ul><h3 id="4-2-受击反馈系统">4.2 受击反馈系统</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">TakeDamage</span>(<span class="params"><span class="built_in">int</span> dmg</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    health -= dmg;</span><br><span class="line">    <span class="keyword">if</span> (health &lt;= <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        GameManager.Instance.AddScore(scoreValue);</span><br><span class="line">        Destroy(gameObject);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (mainSpriteRenderer != <span class="literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            mainSpriteRenderer.color = hitColor;  <span class="comment">// 变红</span></span><br><span class="line">            Invoke(<span class="keyword">nameof</span>(ResetColor), hitFlashDuration);  <span class="comment">// 0.1秒后恢复</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>视觉反馈</strong>：受击时精灵变红，0.1 秒后恢复原色，给玩家明确的命中感</li><li><strong><code>Invoke</code> 延迟调用</strong>：简单实现定时恢复颜色，无需额外协程</li><li><strong>分数奖励</strong>：击杀敌人时通过 <code>GameManager</code> 加分，实现跨组件通信</li></ul><h3 id="4-3-空闲呼吸动画（Idle-Squash）">4.3 空闲呼吸动画（Idle Squash）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleIdleAnimation</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">float</span> t = Mathf.Sin(Time.time * idleSquashSpeed);</span><br><span class="line">    <span class="built_in">float</span> squashY = <span class="number">1f</span> - t * idleSquashAmount;</span><br><span class="line">    <span class="built_in">float</span> squashX = <span class="number">1f</span> + t * idleSquashAmount * <span class="number">0.5f</span>;</span><br><span class="line"></span><br><span class="line">    transform.localScale = <span class="keyword">new</span> Vector3(originalScale.x * squashX, originalScale.y * squashY, originalScale.z);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">float</span> offsetY = originalScale.y * (<span class="number">1f</span> - squashY) * <span class="number">0.5f</span>;</span><br><span class="line">    transform.position = <span class="keyword">new</span> Vector3(originalPosition.x, originalPosition.y + offsetY, originalPosition.z);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>正弦波驱动</strong>：<code>Mathf.Sin(Time.time * speed)</code> 产生周期性缩放，模拟呼吸感</li><li><strong>Y轴压缩时X轴膨胀</strong>：保持体积感的经典动画技巧</li><li><strong>位置补偿</strong>：缩放时调整 Y 位置，使敌人&quot;脚&quot;始终贴地，不会悬浮或陷入地面</li></ul><h3 id="4-4-动态难度系统（EnemySpawner）">4.4 动态难度系统（EnemySpawner）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">IncreaseDifficulty</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    difficultyLevel++;</span><br><span class="line">    currentSpawnInterval = Mathf.Max(minSpawnInterval, currentSpawnInterval - spawnIntervalReduction);</span><br><span class="line">    currentMoveSpeedBonus += moveSpeedIncrease;</span><br><span class="line">    currentHealthBonus += healthIncrease;</span><br><span class="line">    currentScoreBonus += scoreValueIncrease;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><table><thead><tr><th>难度参数</th><th>初始值</th><th>每级增量</th><th>上限</th></tr></thead><tbody><tr><td>生成间隔</td><td>3s</td><td>-0.3s</td><td>0.6s（下限）</td></tr><tr><td>移动速度加成</td><td>0</td><td>+0.3</td><td>无上限</td></tr><tr><td>生命加成</td><td>0</td><td>+1</td><td>无上限</td></tr><tr><td>分数加成</td><td>0</td><td>+50</td><td>无上限</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li><strong>多维难度递增</strong>：同时调整生成频率、敌人速度、敌人血量、击杀分数，避免单一维度调整导致的体验单调</li><li><strong><code>Mathf.Max</code> 保底</strong>：生成间隔不低于 0.6s，防止敌人过于密集无法游玩</li><li><strong>难度等级可预设</strong>：<code>SetStartingDifficulty(int level)</code> 允许从指定难度开始，支持设置面板选择起始难度</li><li><strong>定时触发</strong>：每 <code>difficultyInterval</code>（20秒）提升一级，节奏可预期</li></ul><hr><h2 id="五、子弹系统">五、子弹系统</h2><h3 id="5-1-子弹基础行为">5.1 子弹基础行为</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Start</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    rb.velocity = transform.right * speed;  <span class="comment">// 沿发射方向飞行</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>子弹沿 <code>firePoint</code> 的右方向发射，速度由 <code>speed</code> 参数控制。</p><h3 id="5-2-爆炸子弹（AOE-伤害）">5.2 爆炸子弹（AOE 伤害）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Explode</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (explosionEffect != <span class="literal">null</span>)</span><br><span class="line">        Instantiate(explosionEffect, transform.position, Quaternion.identity);</span><br><span class="line"></span><br><span class="line">    Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, explosionRadius);</span><br><span class="line">    <span class="keyword">foreach</span> (Collider2D collider <span class="keyword">in</span> hitColliders)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (collider.CompareTag(<span class="string">&quot;Enemy&quot;</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            Enemy enemy = collider.GetComponent&lt;Enemy&gt;();</span><br><span class="line">            <span class="keyword">if</span> (enemy != <span class="literal">null</span>)</span><br><span class="line">                enemy.TakeDamage(damage);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    Destroy(gameObject);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong><code>Physics2D.OverlapCircleAll</code></strong>：圆形范围检测，获取爆炸半径内所有碰撞体，实现 AOE 伤害</li><li><strong>爆炸特效</strong>：通过 <code>explosionEffect</code> 预制体实例化爆炸视觉效果</li><li><strong><code>isExplosive</code> 标志</strong>：同一 Bullet 脚本通过布尔标志区分普通子弹和爆炸子弹，复用代码</li><li><strong><code>OnDrawGizmosSelected</code></strong>：在编辑器中绘制爆炸半径辅助线，方便调参</li></ul><h3 id="5-3-子弹精灵动画">5.3 子弹精灵动画</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">HandleAnimation</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (bulletSprites == <span class="literal">null</span> || bulletSprites.Length == <span class="number">0</span>) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    animationTimer += Time.deltaTime;</span><br><span class="line">    <span class="keyword">if</span> (animationTimer &gt;= animationSpeed)</span><br><span class="line">    &#123;</span><br><span class="line">        currentSpriteIndex = (currentSpriteIndex + <span class="number">1</span>) % bulletSprites.Length;</span><br><span class="line">        spriteRenderer.sprite = bulletSprites[currentSpriteIndex];</span><br><span class="line">        animationTimer = <span class="number">0f</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>帧动画</strong>：通过精灵数组循环切换实现逐帧动画（如豌豆飞出效果的3帧动画）</li><li><strong>取模循环</strong>：<code>(index + 1) % length</code> 实现无限循环播放</li></ul><h3 id="5-4-越界销毁">5.4 越界销毁</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">CheckIfOutOfBounds</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (transform.position.x &gt; Camera.main.transform.position.x + Camera.main.orthographicSize * <span class="number">2f</span> ||</span><br><span class="line">        transform.position.x &lt; Camera.main.transform.position.x - Camera.main.orthographicSize * <span class="number">2f</span> ||</span><br><span class="line">        transform.position.y &gt; Camera.main.transform.position.y + Camera.main.orthographicSize ||</span><br><span class="line">        transform.position.y &lt; Camera.main.transform.position.y - Camera.main.orthographicSize)</span><br><span class="line">    &#123;</span><br><span class="line">        Destroy(gameObject);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li>基于相机视口范围判断，而非固定坐标，适配不同分辨率</li><li>水平方向使用 <code>orthographicSize * 2</code>（宽屏），垂直方向使用 <code>orthographicSize</code></li></ul><hr><h2 id="六、道具系统">六、道具系统</h2><h3 id="6-1-道具行为（Powerup）">6.1 道具行为（Powerup）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Update</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (!isGrounded)</span><br><span class="line">    &#123;</span><br><span class="line">        transform.Translate(Vector3.down * fallSpeed * Time.deltaTime);</span><br><span class="line">        <span class="keyword">if</span> (transform.position.y &lt;= groundY + <span class="number">0.8f</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            isGrounded = <span class="literal">true</span>;</span><br><span class="line">            transform.position = <span class="keyword">new</span> Vector3(transform.position.x, groundY + <span class="number">0.8f</span>, transform.position.z);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">float</span> scrollSpeed = GameManager.Instance.GetCurrentScrollSpeed();</span><br><span class="line">        transform.Translate(Vector3.left * scrollSpeed * Time.deltaTime);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>与敌人相似的下落+滚动模式</strong>：道具从空中落下，着地后随背景滚动</li><li><strong>着地高度不同</strong>：道具着地高度 <code>groundY + 0.8f</code> 高于敌人的 <code>groundY + 0.5f</code>，视觉上道具浮在地面上方</li><li><strong><code>weaponType</code> 字段</strong>：每个道具预制体关联一种武器类型，玩家拾取后激活对应武器</li></ul><h3 id="6-2-道具生成器（PowerupSpawner）">6.2 道具生成器（PowerupSpawner）</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">SpawnPowerup</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    GameObject powerupPrefab = powerupPrefabs[Random.Range(<span class="number">0</span>, powerupPrefabs.Length)];</span><br><span class="line">    <span class="built_in">float</span> spawnX = Camera.main.transform.position.x + spawnDistance;</span><br><span class="line">    <span class="built_in">float</span> spawnY = Random.Range(minSpawnHeight, maxSpawnHeight);</span><br><span class="line">    Vector3 spawnPosition = <span class="keyword">new</span> Vector3(spawnX, spawnY, <span class="number">0f</span>);</span><br><span class="line">    Instantiate(powerupPrefab, spawnPosition, Quaternion.identity);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>随机生成间隔</strong>：<code>Random.Range(minSpawnInterval, maxSpawnInterval)</code> 即 3~7 秒，避免固定节奏</li><li><strong>随机高度</strong>：道具在 5~8 高度生成，部分需要跳跃才能获取，增加策略性</li><li><strong>基于相机位置生成</strong>：在相机右侧 <code>spawnDistance</code> 处生成，保证玩家看不到生成过程</li></ul><hr><h2 id="七、背景视差滚动系统">七、背景视差滚动系统</h2><h3 id="7-1-多层视差实现">7.1 多层视差实现</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[<span class="meta">Header(<span class="string">&quot;Scroll Multipliers&quot;</span>)</span>]</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">float</span> cloudScrollMultiplier = <span class="number">0.2f</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">float</span> backLayerScrollMultiplier = <span class="number">0.5f</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">float</span> grassLayerScrollMultiplier = <span class="number">1f</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">float</span> dirtLayerScrollMultiplier = <span class="number">1f</span>;</span><br></pre></td></tr></table></figure><table><thead><tr><th>层级</th><th>速度倍率</th><th>视觉效果</th></tr></thead><tbody><tr><td>云层（Cloud）</td><td>0.2x</td><td>远景，缓慢移动</td></tr><tr><td>背景层（Back）</td><td>0.5x</td><td>中景，中速移动</td></tr><tr><td>草地层（Grass）</td><td>1.0x</td><td>近景，全速移动</td></tr><tr><td>泥土层（Dirt）</td><td>1.0x</td><td>近景，全速移动</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li><strong>视差滚动原理</strong>：不同层以不同速度移动，模拟景深效果，近处快、远处慢</li><li><strong>倍率驱动</strong>：通过 <code>multiplier</code> 参数控制每层速度，易于调整</li><li><strong>无限滚动</strong>：当某层精灵移出屏幕左侧时，将其移到最右侧精灵的右边</li></ul><h3 id="7-2-无限滚动算法">7.2 无限滚动算法</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">ScrollLayerGroup</span>(<span class="params">Transform[] layers, <span class="built_in">float</span> multiplier, <span class="built_in">float</span> deltaTime</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">float</span> movement = currentScrollSpeed * multiplier * deltaTime;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">foreach</span> (Transform layer <span class="keyword">in</span> layers)</span><br><span class="line">    &#123;</span><br><span class="line">        layer.Translate(Vector2.left * movement);</span><br><span class="line"></span><br><span class="line">        SpriteRenderer spriteRenderer = layer.GetComponent&lt;SpriteRenderer&gt;();</span><br><span class="line">        <span class="keyword">if</span> (spriteRenderer != <span class="literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">float</span> spriteWidth = spriteRenderer.bounds.size.x;</span><br><span class="line">            <span class="keyword">if</span> (layer.position.x &lt; -spriteWidth)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="built_in">float</span> rightmostX = FindRightmostPosition(layers, spriteWidth);</span><br><span class="line">                layer.position = <span class="keyword">new</span> Vector3(rightmostX + spriteWidth, layer.position.y, layer.position.z);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>循环拼接</strong>：当精灵完全移出左侧（<code>position.x &lt; -spriteWidth</code>）时，将其接到最右侧精灵后面</li><li><strong><code>FindRightmostPosition</code></strong>：动态查找当前最右侧精灵位置，确保拼接无缝</li><li><strong>基于 <code>bounds.size.x</code></strong>：使用实际渲染宽度而非固定值，适配不同尺寸的精灵</li></ul><h3 id="7-3-速度递增">7.3 速度递增</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">IncreaseSpeed</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    currentScrollSpeed = Mathf.Min(maxScrollSpeed, currentScrollSpeed + scrollSpeedIncreaseRate);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>每 30 秒速度增加 0.05，上限 8，配合敌人难度递增形成整体难度曲线。</p><hr><h2 id="八、UI-系统">八、UI 系统</h2><h3 id="8-1-UIManager-面板管理">8.1 UIManager 面板管理</h3><p>UIManager 管理五个主要界面：</p><table><thead><tr><th>界面</th><th>功能</th></tr></thead><tbody><tr><td>主菜单（MainMenu）</td><td>开始游戏、设置、退出</td></tr><tr><td>设置面板（Settings）</td><td>难度、速度、音乐、音量</td></tr><tr><td>游戏 HUD</td><td>分数、生命值</td></tr><tr><td>暂停界面（Pause）</td><td>继续、重新开始、返回主菜单</td></tr><tr><td>游戏结束（GameOver）</td><td>最终分数、重新开始、返回主菜单</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li><strong>面板激活/隐藏</strong>：通过 <code>SetActive(true/false)</code> 控制面板显示，简单高效</li><li><strong>按钮事件绑定</strong>：在 <code>Start()</code> 中通过 <code>onClick.AddListener</code> 统一绑定，避免 Inspector 拖拽遗漏</li><li><strong>ESC 键处理</strong>：<code>Update()</code> 中监听 <code>KeyCode.Escape</code>，主菜单下关闭设置，游戏中切换暂停</li></ul><h3 id="8-2-设置面板交互">8.2 设置面板交互</h3><p><strong>速度选择 Toggle 互斥逻辑</strong>：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="built_in">bool</span> isUpdatingSpeedToggles;  <span class="comment">// 防止递归触发</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">OnNormalSpeedChanged</span>(<span class="params"><span class="built_in">bool</span> isOn</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (isUpdatingSpeedToggles) <span class="keyword">return</span>;  <span class="comment">// 程序修改时跳过</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (isOn)</span><br><span class="line">    &#123;</span><br><span class="line">        GameManager.Instance.SetGameSpeed(<span class="number">1f</span>);</span><br><span class="line">        isUpdatingSpeedToggles = <span class="literal">true</span>;</span><br><span class="line">        mediumSpeedToggle.isOn = <span class="literal">false</span>;</span><br><span class="line">        fastSpeedToggle.isOn = <span class="literal">false</span>;</span><br><span class="line">        isUpdatingSpeedToggles = <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        isUpdatingSpeedToggles = <span class="literal">true</span>;</span><br><span class="line">        normalSpeedToggle.isOn = <span class="literal">true</span>;  <span class="comment">// 阻止取消选中</span></span><br><span class="line">        isUpdatingSpeedToggles = <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong><code>isUpdatingSpeedToggles</code> 防递归</strong>：程序修改 <code>isOn</code> 会触发 <code>onValueChanged</code> 回调，使用标志位防止无限递归</li><li><strong>Toggle 互斥</strong>：选中一个时取消其他，取消选中时强制保持选中（至少选一个）</li><li><strong>三档速度</strong>：1x / 1.5x / 2.25x，通过 <code>Time.timeScale</code> 实现</li></ul><h3 id="8-3-GameInfoDisplay-实时信息">8.3 GameInfoDisplay 实时信息</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">UpdateJumpHint</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (player != <span class="literal">null</span> &amp;&amp; player.HasJumpedOnce)</span><br><span class="line">    &#123;</span><br><span class="line">        jumpHintText.gameObject.SetActive(<span class="literal">false</span>);  <span class="comment">// 首次跳跃后永久隐藏</span></span><br><span class="line">        jumpHintHidden = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">float</span> t = (Mathf.Sin(Time.time * pulseSpeed) + <span class="number">1f</span>) / <span class="number">2f</span>;</span><br><span class="line">    jumpHintText.fontSize = Mathf.RoundToInt(Mathf.Lerp(minFontSize, maxFontSize, t));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>脉冲提示</strong>：跳跃提示文字大小在 24~32 之间正弦波动，吸引注意力</li><li><strong>一次性提示</strong>：玩家首次跳跃后永久隐藏，不再干扰</li><li><strong>武器倒计时</strong>：实时显示当前武器名称和剩余秒数</li><li><strong>难度信息</strong>：显示当前难度等级、各项加成和下次加强倒计时</li></ul><hr><h2 id="九、数据持久化">九、数据持久化</h2><p>项目使用 <code>PlayerPrefs</code> 实现简单的本地持久化：</p><table><thead><tr><th>存储键</th><th>类型</th><th>用途</th></tr></thead><tbody><tr><td><code>BestScore</code></td><td>int</td><td>历史最高分</td></tr><tr><td><code>GameSpeed</code></td><td>float</td><td>游戏速度设置</td></tr><tr><td><code>StartingDifficulty</code></td><td>int</td><td>起始难度设置</td></tr><tr><td><code>MusicEnabled</code></td><td>int (0/1)</td><td>音乐开关</td></tr><tr><td><code>MusicVolume</code></td><td>float</td><td>音乐音量</td></tr><tr><td><code>SkipMainMenu</code></td><td>int (0/1)</td><td>重新开始时跳过主菜单</td></tr></tbody></table><p><strong>面试要点</strong>：</p><ul><li><strong><code>PlayerPrefs</code> 适用场景</strong>：简单的键值对存储，适合设置项和最高分</li><li><strong><code>SkipMainMenu</code> 技巧</strong>：重新开始时设置标记，场景加载后检测标记直接开始游戏，避免回到主菜单</li><li><strong>局限性</strong>：<code>PlayerPrefs</code> 不适合复杂数据结构，生产环境应考虑 JSON 文件或数据库</li></ul><hr><h2 id="十、游戏流程与状态管理">十、游戏流程与状态管理</h2><h3 id="10-1-完整游戏流程">10.1 完整游戏流程</h3><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">启动 → 主菜单（Time.<span class="attribute">timeScale</span>=0）</span><br><span class="line">  ├── 开始游戏 → 游戏进行中（Time.<span class="attribute">timeScale</span>=GameSpeed）</span><br><span class="line">  │     ├── 暂停 → 暂停界面（Time.<span class="attribute">timeScale</span>=0）</span><br><span class="line">  │     │     ├── 继续 → 恢复游戏</span><br><span class="line">  │     │     ├── 重新开始 → 场景重载</span><br><span class="line">  │     │     └── 返回主菜单 → 场景重载</span><br><span class="line">  │     └── 生命归零 → 游戏结束（Time.<span class="attribute">timeScale</span>=0）</span><br><span class="line">  │           ├── 重新开始 → 场景重载</span><br><span class="line">  │           └── 返回主菜单 → 场景重载</span><br><span class="line">  ├── 设置 → 设置面板</span><br><span class="line">  └── 退出 → 关闭应用</span><br></pre></td></tr></table></figure><h3 id="10-2-场景重载机制">10.2 场景重载机制</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">RestartGame</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (Score &gt; bestScore)</span><br><span class="line">    &#123;</span><br><span class="line">        bestScore = Score;</span><br><span class="line">        PlayerPrefs.SetInt(<span class="string">&quot;BestScore&quot;</span>, bestScore);</span><br><span class="line">    &#125;</span><br><span class="line">    PlayerPrefs.SetInt(<span class="string">&quot;SkipMainMenu&quot;</span>, <span class="number">1</span>);</span><br><span class="line">    SceneManager.LoadScene(SceneManager.GetActiveScene().name);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ReturnToMainMenu</span>()</span></span><br><span class="line">&#123;</span><br><span class="line">    Time.timeScale = <span class="number">0f</span>;</span><br><span class="line">    SceneManager.LoadScene(SceneManager.GetActiveScene().name);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li><strong>统一使用场景重载</strong>：重新开始和返回主菜单都通过 <code>SceneManager.LoadScene</code> 实现，简洁可靠</li><li><strong><code>SkipMainMenu</code> 区分</strong>：重载后通过此标记决定是进入主菜单还是直接开始游戏</li><li><strong>最高分保存</strong>：每次场景重载前检查并保存最高分</li></ul><hr><h2 id="十一、碰撞与物理系统">十一、碰撞与物理系统</h2><h3 id="11-1-碰撞层设计">11.1 碰撞层设计</h3><table><thead><tr><th>碰撞体</th><th>Tag</th><th>行为</th></tr></thead><tbody><tr><td>玩家</td><td>Player</td><td>检测与 Enemy/Powerup 的触发器碰撞</td></tr><tr><td>敌人</td><td>Enemy</td><td>检测与 Player 的触发器碰撞（造成伤害）</td></tr><tr><td>子弹</td><td>无特定 Tag</td><td>检测与 Enemy 的触发器碰撞（造成伤害）</td></tr><tr><td>道具</td><td>Powerup</td><td>被玩家检测拾取</td></tr></tbody></table><h3 id="11-2-双向碰撞处理">11.2 双向碰撞处理</h3><p><strong>Enemy 与 Player 的碰撞</strong>在两侧都有处理：</p><ul><li><code>Enemy.OnTriggerEnter2D</code>：敌人碰到玩家 → 玩家受伤，敌人销毁</li><li><code>PlayerController.OnTriggerEnter2D</code>：玩家碰到敌人 → 玩家受伤，敌人销毁</li></ul><p><strong>面试要点</strong>：</p><ul><li>双侧处理保证无论哪一方先检测到碰撞都能正确响应</li><li>子弹与敌人的碰撞仅在 <code>Bullet.OnTriggerEnter2D</code> 中处理（单向）</li></ul><hr><h2 id="十二、性能优化要点">十二、性能优化要点</h2><h3 id="12-1-对象清理">12.1 对象清理</h3><table><thead><tr><th>清理方式</th><th>适用对象</th><th>触发条件</th></tr></thead><tbody><tr><td><code>OnBecameInvisible</code></td><td>敌人、道具</td><td>移出屏幕左侧 15 单位</td></tr><tr><td><code>CheckIfOutOfBounds</code></td><td>子弹</td><td>移出相机视口范围</td></tr><tr><td><code>Destroy</code></td><td>敌人（被击杀/碰到玩家）、子弹（命中）、道具（被拾取）</td><td>逻辑触发</td></tr></tbody></table><h3 id="12-2-状态检查短路">12.2 状态检查短路</h3><p>所有 <code>Update()</code> 方法开头检查游戏状态：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (GameManager.Instance.IsGameOver || GameManager.Instance.IsPaused) <span class="keyword">return</span>;</span><br></pre></td></tr></table></figure><p><strong>面试要点</strong>：</p><ul><li>暂停/结束时跳过所有逻辑运算，减少不必要的 CPU 开销</li><li><code>Time.timeScale = 0</code> 本身会停止物理更新，但 <code>Update()</code> 仍会执行（使用真实时间），所以需要手动检查</li></ul><h3 id="12-3-潜在优化方向（面试加分项）">12.3 潜在优化方向（面试加分项）</h3><table><thead><tr><th>优化方向</th><th>当前方案</th><th>改进方案</th></tr></thead><tbody><tr><td>对象池</td><td><code>Instantiate/Destroy</code></td><td>对象池复用敌人、子弹、道具</td></tr><tr><td>FindObjectOfType</td><td><code>GameInfoDisplay.Start()</code></td><td>Inspector 引用或单例访问</td></tr><tr><td>帧动画</td><td>手动计时器切换精灵</td><td>Unity Animator 或 Sprite Sheet 动画</td></tr><tr><td>碰撞检测</td><td>多次 <code>GetComponent</code></td><td>缓存组件引用</td></tr></tbody></table><hr><h2 id="十三、技术难点与解决方案">十三、技术难点与解决方案</h2><h3 id="13-1-着地检测精度问题">13.1 着地检测精度问题</h3><p><strong>问题</strong>：使用 <code>OnCollisionEnter2D</code> 检测着地容易出现&quot;粘地&quot;或&quot;穿地&quot;问题，特别是在高速下落时。</p><p><strong>解决方案</strong>：在 <code>FixedUpdate</code> 中基于位置和速度双重判断：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (transform.position.y &lt;= groundY + <span class="number">0.5f</span> &amp;&amp; rb.velocity.y &lt;= <span class="number">0.1f</span>)</span><br></pre></td></tr></table></figure><ul><li>位置判断确保角色不低于地面</li><li>速度判断确保角色在下降阶段才判定着地</li><li>直接修正位置和速度，避免物理引擎累积误差</li></ul><h3 id="13-2-Toggle-互斥递归问题">13.2 Toggle 互斥递归问题</h3><p><strong>问题</strong>：代码修改 Toggle 的 <code>isOn</code> 属性会触发 <code>onValueChanged</code> 回调，导致无限递归。</p><p><strong>解决方案</strong>：引入 <code>isUpdatingSpeedToggles</code> 布尔标志：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (isUpdatingSpeedToggles) <span class="keyword">return</span>;</span><br><span class="line">isUpdatingSpeedToggles = <span class="literal">true</span>;</span><br><span class="line"><span class="comment">// 修改其他 Toggle...</span></span><br><span class="line">isUpdatingSpeedToggles = <span class="literal">false</span>;</span><br></pre></td></tr></table></figure><h3 id="13-3-无限滚动无缝拼接">13.3 无限滚动无缝拼接</h3><p><strong>问题</strong>：多层背景以不同速度滚动时，精灵拼接处可能出现缝隙。</p><p><strong>解决方案</strong>：动态查找最右侧精灵位置，将移出的精灵精确接到最右侧：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">float</span> rightmostX = FindRightmostPosition(layers, spriteWidth);</span><br><span class="line">layer.position = <span class="keyword">new</span> Vector3(rightmostX + spriteWidth, layer.position.y, layer.position.z);</span><br></pre></td></tr></table></figure><h3 id="13-4-暂停时-UI-点击穿透">13.4 暂停时 UI 点击穿透</h3><p><strong>问题</strong>：点击 UI 按钮时同时触发了玩家的跳跃。</p><p><strong>解决方案</strong>：使用 <code>EventSystem.current.IsPointerOverGameObject()</code> 检测点击是否在 UI 上：</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (EventSystem.current != <span class="literal">null</span> &amp;&amp; EventSystem.current.IsPointerOverGameObject())</span><br><span class="line">    <span class="keyword">return</span>;</span><br></pre></td></tr></table></figure><hr><h2 id="十四、项目亮点总结（面试话术）">十四、项目亮点总结（面试话术）</h2><ol><li><p><strong>完整的游戏循环</strong>：从主菜单→游戏→暂停→结束→重开，状态管理清晰，使用 <code>Time.timeScale</code> 控制暂停，布尔标志控制逻辑分支</p></li><li><p><strong>多维难度递增系统</strong>：同时调整敌人生成频率、移动速度、血量、分数四个维度，配合背景滚动加速，形成平滑的难度曲线</p></li><li><p><strong>Squash &amp; Stretch 动画</strong>：在玩家和敌人上都实现了挤压拉伸动画，遵循动画12原则，增强角色动态表现力</p></li><li><p><strong>多层视差滚动</strong>：4 层不同速度的背景滚动，实现景深效果，无限循环拼接算法保证无缝</p></li><li><p><strong>武器系统设计</strong>：三种武器差异化设计（射速/伤害/范围），限时切换机制增加策略性</p></li><li><p><strong>爆炸 AOE 机制</strong>：玉米大炮使用 <code>Physics2D.OverlapCircleAll</code> 实现范围伤害，配合爆炸特效</p></li><li><p><strong>数据持久化</strong>：使用 <code>PlayerPrefs</code> 保存最高分和设置项，重启后保留用户偏好</p></li><li><p><strong>UI 交互细节</strong>：Toggle 互斥防递归、跳跃提示脉冲动画、武器倒计时显示、ESC 键多场景响应</p></li></ol>]]></content>
    
    
    <summary type="html">根据基础需求文档在72小时内递交作品成果demo参与考核</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="C#" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="Unity" scheme="https://home.y1xuanyun.cn/tags/Unity/"/>
    
    <category term="3D" scheme="https://home.y1xuanyun.cn/tags/3D/"/>
    
    <category term="游戏开发" scheme="https://home.y1xuanyun.cn/tags/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91/"/>
    
    <category term="实习" scheme="https://home.y1xuanyun.cn/tags/%E5%AE%9E%E4%B9%A0/"/>
    
  </entry>
  
  <entry>
    <title>Inno Setup 安装包制作指南</title>
    <link href="https://home.y1xuanyun.cn/posts/25pc02.html"/>
    <id>https://home.y1xuanyun.cn/posts/25pc02.html</id>
    <published>2025-10-16T03:00:00.000Z</published>
    <updated>2025-10-16T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>前言</h1><p>在现代软件开发中，专业的安装包是产品交付的重要环节。Inno Setup 作为一款免费的 Windows 安装包制作工具，以其强大的功能和灵活的配置受到广大开发者的喜爱。本文将详细介绍如何使用 Inno Setup 制作专业的安装包。<br>点击前往：<a href="https://jrsoftware.org/isinfo.php">Inno Setup 官网</a> 点击下载：<a href="https://file.y1xuanyun.cn/posts/25pc02/ChineseSimplified.isl">Inno Setup 中文包</a></p><h1>第一章：Inno Setup 基础概念</h1><h2 id="1-1-什么是-Inno-Setup？">1.1 什么是 Inno Setup？</h2><p>Inno Setup 是一个免费的 Windows 安装程序制作工具，由 Jordan Russell 开发。它提供了丰富的功能，包括：</p><ul><li>创建单个 EXE 安装文件</li><li>支持自定义安装界面</li><li>强大的脚本语言支持</li><li>完整的卸载功能支持</li></ul><h2 id="1-2-基本项目结构">1.2 基本项目结构</h2><p>一个典型的 Inno Setup 脚本文件（.iss）包含以下主要部分：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Setup]</span>           <span class="comment">; 安装程序基本设置</span></span><br><span class="line"><span class="section">[Languages]</span>       <span class="comment">; 语言支持配置</span></span><br><span class="line"><span class="section">[Types]</span>           <span class="comment">; 安装类型定义</span></span><br><span class="line"><span class="section">[Components]</span>      <span class="comment">; 组件定义</span></span><br><span class="line"><span class="section">[Files]</span>           <span class="comment">; 文件复制规则</span></span><br><span class="line"><span class="section">[Run]</span>             <span class="comment">; 安装后运行程序</span></span><br><span class="line"><span class="section">[Registry]</span>        <span class="comment">; 注册表操作</span></span><br><span class="line"><span class="section">[UninstallRun]</span>    <span class="comment">; 卸载时运行程序</span></span><br><span class="line"><span class="section">[UninstallDelete]</span> <span class="comment">; 卸载时删除文件</span></span><br><span class="line"><span class="section">[Icons]</span>           <span class="comment">; 快捷方式创建</span></span><br><span class="line"><span class="section">[Code]</span>            <span class="comment">; Pascal 脚本代码</span></span><br></pre></td></tr></table></figure><h1>第二章：基础配置详解</h1><h2 id="2-1-Setup-段配置">2.1 [Setup] 段配置</h2><p>这是安装程序的核心配置部分，定义了安装包的基本属性：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Setup]</span></span><br><span class="line"><span class="comment">; 应用程序信息</span></span><br><span class="line"><span class="attr">AppName</span>=我的应用程序</span><br><span class="line"><span class="attr">AppVersion</span>=<span class="number">1.0</span>.<span class="number">0</span></span><br><span class="line"><span class="attr">AppPublisher</span>=我的公司</span><br><span class="line"><span class="attr">AppPublisherURL</span>=https://www.mycompany.com/</span><br><span class="line"><span class="comment">; 安装目录设置</span></span><br><span class="line"><span class="attr">DefaultDirName</span>=&#123;autopf&#125;\MyApplication</span><br><span class="line"><span class="comment">; 允许用户修改安装目录</span></span><br><span class="line"><span class="attr">DisableDirPage</span>=<span class="literal">no</span></span><br><span class="line"><span class="comment">; 开始菜单文件夹名称</span></span><br><span class="line"><span class="attr">DefaultGroupName</span>=我的应用程序</span><br><span class="line"><span class="comment">; 输出设置</span></span><br><span class="line"><span class="attr">OutputDir</span>=Output</span><br><span class="line"><span class="attr">OutputBaseFilename</span>=MyApp_Setup</span><br><span class="line"><span class="attr">SetupIconFile</span>=myapp.ico</span><br><span class="line"><span class="comment">; 压缩设置</span></span><br><span class="line"><span class="attr">Compression</span>=lzma2</span><br><span class="line"><span class="attr">SolidCompression</span>=<span class="literal">yes</span></span><br><span class="line"><span class="comment">; 权限设置</span></span><br><span class="line"><span class="attr">PrivilegesRequired</span>=admin</span><br><span class="line"><span class="attr">WizardStyle</span>=modern</span><br></pre></td></tr></table></figure><p><strong>关键参数说明：</strong></p><ul><li><code>AppName</code>：应用程序名称</li><li><code>DefaultDirName</code>：默认安装目录</li><li><code>&#123;autopf&#125;</code>：自动选择 Program Files 目录</li><li><code>PrivilegesRequired=admin</code>：需要管理员权限</li></ul><h2 id="2-2-多语言支持">2.2 多语言支持</h2><p><strong>前言有中文语言包下载链接，已挂载至github文仓</strong></p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Languages]</span></span><br><span class="line">Name: &quot;chinesesimp&quot;<span class="comment">; MessagesFile: &quot;ChineseSimplified.isl&quot;</span></span><br><span class="line">Name: &quot;english&quot;<span class="comment">; MessagesFile: &quot;compiler:Default.isl&quot;</span></span><br></pre></td></tr></table></figure><h1>第三章：安装类型与组件管理</h1><h2 id="3-1-定义安装类型">3.1 定义安装类型</h2><ul><li><code>Flags: iscustom</code> 表示自定义选项</li></ul><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Types]</span></span><br><span class="line">Name: &quot;full&quot;<span class="comment">; Description: &quot;完整安装&quot;</span></span><br><span class="line">Name: &quot;compact&quot;<span class="comment">; Description: &quot;典型安装&quot;</span></span><br><span class="line">Name: &quot;custom&quot;<span class="comment">; Description: &quot;自定义安装&quot;; Flags: iscustom</span></span><br></pre></td></tr></table></figure><h2 id="3-2-组件定义">3.2 组件定义</h2><ul><li><code>Types</code> 表示分组依据</li><li><code>Flags: fixed</code> 表示必选组件</li></ul><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Components]</span></span><br><span class="line">Name: &quot;main&quot;<span class="comment">; Description: &quot;主程序文件&quot;; Types: full compact custom; Flags: fixed</span></span><br><span class="line">Name: &quot;database&quot;<span class="comment">; Description: &quot;数据库组件&quot;; Types: full</span></span><br><span class="line">Name: &quot;drivers&quot;<span class="comment">; Description: &quot;驱动程序&quot;; Types: full</span></span><br><span class="line">Name: &quot;docs&quot;<span class="comment">; Description: &quot;帮助文档&quot;; Types: full</span></span><br></pre></td></tr></table></figure><h1>第四章：文件处理与复制</h1><h2 id="4-1-Files-段配置">4.1 [Files] 段配置</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Files]</span></span><br><span class="line"><span class="comment">; 基本文件复制</span></span><br><span class="line">Source: &quot;..\Build*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;&quot;; Flags: ignoreversion recursesubdirs</span></span><br><span class="line"><span class="comment">; 组件相关文件</span></span><br><span class="line">Source: &quot;..\Database*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;\Database&quot;; Flags: ignoreversion; Components: database</span></span><br><span class="line">Source: &quot;..\Drivers*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;\Drivers&quot;; Flags: ignoreversion; Components: drivers</span></span><br><span class="line"><span class="comment">; 配置文件（不覆盖用户修改）</span></span><br><span class="line">Source: &quot;config.ini&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;&quot;; Flags: ignoreversion onlyifdoesntexist</span></span><br><span class="line"><span class="comment">; 临时文件（安装后删除）</span></span><br><span class="line">Source: &quot;temp_setup.exe&quot;<span class="comment">; DestDir: &quot;&#123;tmp&#125;&quot;; Flags: deleteafterinstall</span></span><br></pre></td></tr></table></figure><p><strong>常用 Flags 说明：</strong></p><ul><li><code>ignoreversion</code>：忽略文件版本检查</li><li><code>recursesubdirs</code>：递归复制子目录</li><li><code>onlyifdoesntexist</code>：仅当文件不存在时复制</li><li><code>deleteafterinstall</code>：安装完成后删除</li></ul><h2 id="4-2-目录常量说明">4.2 目录常量说明</h2><table><thead><tr><th>常量</th><th>说明</th></tr></thead><tbody><tr><td><code>&#123;app&#125;</code></td><td>应用程序安装目录</td></tr><tr><td><code>&#123;tmp&#125;</code></td><td>系统临时目录</td></tr><tr><td><code>&#123;src&#125;</code></td><td>安装文件所在目录</td></tr><tr><td><code>&#123;pf&#125;</code></td><td>Program Files 目录</td></tr><tr><td><code>&#123;cf&#125;</code></td><td>Common Files 目录</td></tr></tbody></table><h1>第五章：安装过程控制</h1><h2 id="5-1-运行外部程序">5.1 运行外部程序</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Run]</span></span><br><span class="line"><span class="comment">; 安装后运行主程序</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\MyApp.exe&quot;<span class="comment">; Description: &quot;启动应用程序&quot;; Flags: nowait postinstall skipifsilent</span></span><br><span class="line"><span class="comment">; 安装服务</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\ServiceInstaller.exe&quot;<span class="comment">; Parameters: &quot;/install&quot;; StatusMsg: &quot;正在安装服务...&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line"><span class="comment">; 执行命令行操作</span></span><br><span class="line">Filename: &quot;net&quot;<span class="comment">; Parameters: &quot;start MyService&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line"><span class="comment">; 条件执行</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\Tool.exe&quot;<span class="comment">; Parameters: &quot;/setup&quot;; Check: IsComponentSelected(&#x27;tools&#x27;)</span></span><br></pre></td></tr></table></figure><h2 id="5-2-注册表操作">5.2 注册表操作</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Registry]</span></span><br><span class="line"><span class="comment">; 添加文件关联</span></span><br><span class="line">Root: HKCR<span class="comment">; Subkey: &quot;.myext&quot;; ValueType: string; ValueName: &quot;&quot;; ValueData: &quot;MyApp.Document&quot;</span></span><br><span class="line"><span class="comment">; 应用程序设置</span></span><br><span class="line">Root: HKCU<span class="comment">; Subkey: &quot;Software\MyCompany\MyApp&quot;; ValueType: string; ValueName: &quot;InstallPath&quot;; ValueData: &quot;&#123;app&#125;&quot;</span></span><br><span class="line"><span class="comment">; 卸载信息</span></span><br><span class="line">Root: HKLM<span class="comment">; Subkey: &quot;Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp&quot;; ValueType: string; ValueName: &quot;DisplayName&quot;; ValueData: &quot;我的应用程序&quot;</span></span><br></pre></td></tr></table></figure><h1>第六章：数据库集成安装</h1><h2 id="6-1-MySQL-数据库安装示例">6.1 MySQL 数据库安装示例</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Run]</span></span><br><span class="line"><span class="comment">; 停止现有服务</span></span><br><span class="line">Filename: &quot;net&quot;<span class="comment">; Parameters: &quot;stop MySQL&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line"><span class="comment">; 初始化数据目录</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\mysql\bin\mysqld.exe&quot;<span class="comment">; Parameters: &quot;--initialize-insecure --basedir=&quot;&quot;&#123;app&#125;\mysql&quot;&quot; --datadir=&quot;&quot;&#123;app&#125;\mysql\data&quot;&quot;&quot;; StatusMsg: &quot;初始化数据库...&quot;</span></span><br><span class="line"><span class="comment">; 安装并启动服务</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\mysql\bin\mysqld.exe&quot;<span class="comment">; Parameters: &quot;--install MySQLService&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line">Filename: &quot;net&quot;<span class="comment">; Parameters: &quot;start MySQLService&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line"><span class="comment">; 执行SQL脚本</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\mysql\bin\mysql.exe&quot;<span class="comment">; Parameters: &quot;-u root -e &quot;&quot;source &#123;app&#125;\database\init.sql&quot;&quot;&quot;; Flags: runhidden waituntilterminated</span></span><br></pre></td></tr></table></figure><h2 id="6-2-ODBC-数据源配置">6.2 ODBC 数据源配置</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Registry]</span></span><br><span class="line">Root: HKLM<span class="comment">; Subkey: &quot;SOFTWARE\ODBC\ODBC.INI\MyAppDSN&quot;; ValueType: string; ValueName: &quot;Driver&quot;; ValueData: &quot;&#123;app&#125;\drivers\myodbc.dll&quot;</span></span><br><span class="line">Root: HKLM<span class="comment">; Subkey: &quot;SOFTWARE\ODBC\ODBC.INI\MyAppDSN&quot;; ValueType: string; ValueName: &quot;Server&quot;; ValueData: &quot;localhost&quot;</span></span><br><span class="line">Root: HKLM<span class="comment">; Subkey: &quot;SOFTWARE\ODBC\ODBC.INI\MyAppDSN&quot;; ValueType: string; ValueName: &quot;Database&quot;; ValueData: &quot;myappdb&quot;</span></span><br></pre></td></tr></table></figure><h1>第七章：高级脚本编程</h1><h2 id="7-1-Pascal-脚本基础">7.1 Pascal 脚本基础</h2><figure class="highlight pascal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">[Code]</span><br><span class="line"><span class="comment">// 自定义函数示例</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">InitializeSetup</span><span class="params">()</span>:</span> Boolean;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line"><span class="comment">// 系统检查</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> IsWindowsVersionOrNewer(<span class="number">6</span>, <span class="number">1</span>) <span class="keyword">then</span> <span class="keyword">begin</span></span><br><span class="line">MsgBox(<span class="string">&#x27;此程序需要 Windows 7 或更高版本。&#x27;</span>, mbError, MB_OK);</span><br><span class="line">Result := False;</span><br><span class="line"><span class="keyword">end</span> <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">Result := True;</span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="comment">// 组件选择检查</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">ShouldSkipPage</span><span class="params">(PageID: Integer)</span>:</span> Boolean;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line"><span class="comment">// 如果未选择数据库组件，跳过数据库配置页面</span></span><br><span class="line"><span class="keyword">if</span> (PageID = wpSelectComponents) <span class="keyword">and</span> <span class="keyword">not</span> IsComponentSelected(<span class="string">&#x27;database&#x27;</span>) <span class="keyword">then</span></span><br><span class="line">Result := True</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">Result := False;</span><br><span class="line"><span class="keyword">end</span>;</span><br></pre></td></tr></table></figure><h2 id="7-2-服务状态检测函数">7.2 服务状态检测函数</h2><figure class="highlight pascal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">[Code]</span><br><span class="line"><span class="comment">// 检查服务是否已安装</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">IsServiceInstalled</span><span class="params">(ServiceName: <span class="keyword">string</span>)</span>:</span> Boolean;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">Result := RegKeyExists(HKLM,</span><br><span class="line"><span class="string">&#x27;SYSTEM\CurrentControlSet\Services&#x27;</span>+ ServiceName);</span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="comment">// 检查服务是否运行</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">IsServiceRunning</span><span class="params">(ServiceName: <span class="keyword">string</span>)</span>:</span> Boolean;</span><br><span class="line"><span class="keyword">var</span></span><br><span class="line">ResultCode: Integer;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">Result := False;</span><br><span class="line"><span class="keyword">if</span> Exec(ExpandConstant(<span class="string">&#x27;net.exe&#x27;</span>), <span class="string">&#x27;start&#x27;</span>, <span class="string">&#x27;&#x27;</span>, SW_HIDE,</span><br><span class="line">ewWaitUntilTerminated, ResultCode) <span class="keyword">then</span></span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line"><span class="comment">// 解析 net start 输出判断服务状态</span></span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="comment">// 自定义安装页面</span></span><br><span class="line"><span class="function"><span class="keyword">procedure</span> <span class="title">CreateCustomPages</span>;</span></span><br><span class="line"><span class="keyword">var</span></span><br><span class="line">Page: TWizardPage;</span><br><span class="line">Edit: TEdit;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">Page := CreateCustomPage(wpSelectComponents, <span class="string">&#x27;数据库配置&#x27;</span>, <span class="string">&#x27;请输入数据库连接信息&#x27;</span>);</span><br><span class="line">Edit := TEdit.Create(Page);</span><br><span class="line">Edit.Parent := Page.Surface;</span><br><span class="line">Edit.Left := ScaleX(<span class="number">0</span>);</span><br><span class="line">Edit.Top := ScaleY(<span class="number">0</span>);</span><br><span class="line">Edit.Width := ScaleX(<span class="number">200</span>);</span><br><span class="line">Edit.Text := <span class="string">&#x27;localhost&#x27;</span>;</span><br><span class="line"><span class="keyword">end</span>;</span><br></pre></td></tr></table></figure><h1>第八章：卸载配置</h1><h2 id="8-1-卸载时执行操作">8.1 卸载时执行操作</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[UninstallRun]</span></span><br><span class="line"><span class="comment">; 停止并删除服务</span></span><br><span class="line">Filename: &quot;net&quot;<span class="comment">; Parameters: &quot;stop MyService&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\ServiceInstaller.exe&quot;<span class="comment">; Parameters: &quot;/uninstall&quot;; Flags: runhidden waituntilterminated</span></span><br><span class="line"><span class="comment">; 删除临时文件</span></span><br><span class="line">Filename: &quot;&#123;cmd&#125;&quot;<span class="comment">; Parameters: &quot;/c del /q &quot;&quot;&#123;app&#125;\temp*.*&quot;&quot;&quot;; Flags: runhidden waituntilterminated</span></span><br></pre></td></tr></table></figure><h2 id="8-2-卸载时清理文件">8.2 卸载时清理文件</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[UninstallDelete]</span></span><br><span class="line"><span class="comment">; 删除整个目录</span></span><br><span class="line">Type: filesandordirs<span class="comment">; Name: &quot;&#123;app&#125;\temp&quot;</span></span><br><span class="line">Type: filesandordirs<span class="comment">; Name: &quot;&#123;app&#125;\logs&quot;</span></span><br><span class="line"><span class="comment">; 删除特定文件</span></span><br><span class="line">Type: files<span class="comment">; Name: &quot;&#123;app&#125;\cache.dat&quot;</span></span><br><span class="line"><span class="comment">; 删除注册表项</span></span><br><span class="line">Type: regkey<span class="comment">; Root: HKCU; Subkey: &quot;Software\MyApp&quot;</span></span><br></pre></td></tr></table></figure><h1>第九章：快捷方式与用户界面</h1><h2 id="9-1-创建快捷方式">9.1 创建快捷方式</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Icons]</span></span><br><span class="line"><span class="comment">; 开始菜单快捷方式</span></span><br><span class="line">Name: &quot;&#123;group&#125;\我的应用程序&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\MyApp.exe&quot;</span></span><br><span class="line">Name: &quot;&#123;group&#125;\卸载&quot;<span class="comment">; Filename: &quot;&#123;uninstallexe&#125;&quot;</span></span><br><span class="line"><span class="comment">; 桌面快捷方式</span></span><br><span class="line">Name: &quot;&#123;autodesktop&#125;\我的应用程序&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\MyApp.exe&quot;</span></span><br><span class="line"><span class="comment">; 快速启动栏（Windows 7/8）</span></span><br><span class="line">Name: &quot;&#123;userappdata&#125;\Microsoft\Internet Explorer\Quick Launch\我的应用程序&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\MyApp.exe&quot;</span></span><br><span class="line"><span class="comment">; 带参数的快捷方式</span></span><br><span class="line">Name: &quot;&#123;group&#125;\配置工具&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\ConfigTool.exe&quot;; Parameters: &quot;-mode admin&quot;</span></span><br></pre></td></tr></table></figure><h2 id="9-2-自定义安装界面">9.2 自定义安装界面</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Setup]</span></span><br><span class="line"><span class="comment">; 启用现代向导样式</span></span><br><span class="line"><span class="attr">WizardStyle</span>=modern</span><br><span class="line"><span class="comment">; 自定义向导图片</span></span><br><span class="line"><span class="attr">WizardSmallImageFile</span>=small.bmp</span><br><span class="line"><span class="attr">WizardImageFile</span>=large.bmp</span><br><span class="line"><span class="comment">; 安装完成页面显示选项</span></span><br><span class="line"><span class="attr">DisableFinishedPage</span>=<span class="literal">no</span></span><br><span class="line"><span class="attr">DisableWelcomePage</span>=<span class="literal">no</span></span><br></pre></td></tr></table></figure><h1>第十章：实战案例 - 企业级应用部署</h1><h2 id="10-1-完整的企业应用安装脚本">10.1 完整的企业应用安装脚本</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Setup]</span></span><br><span class="line"><span class="attr">AppName</span>=企业管理系统</span><br><span class="line"><span class="attr">AppVersion</span>=<span class="number">2.1</span>.<span class="number">0</span></span><br><span class="line"><span class="attr">AppPublisher</span>=企业信息科技有限公司</span><br><span class="line"><span class="attr">AppPublisherURL</span>=https://www.example.com/</span><br><span class="line"><span class="attr">DefaultDirName</span>=&#123;autopf&#125;\EnterpriseSystem</span><br><span class="line"><span class="attr">DefaultGroupName</span>=企业管理系统</span><br><span class="line"><span class="attr">OutputDir</span>=Output</span><br><span class="line"><span class="attr">OutputBaseFilename</span>=EnterpriseSystem_Setup</span><br><span class="line"><span class="attr">SetupIconFile</span>=app.ico</span><br><span class="line"><span class="attr">Compression</span>=lzma2</span><br><span class="line"><span class="attr">SolidCompression</span>=<span class="literal">yes</span></span><br><span class="line"><span class="attr">PrivilegesRequired</span>=admin</span><br><span class="line"><span class="attr">WizardStyle</span>=modern</span><br><span class="line"><span class="section">[Languages]</span></span><br><span class="line">Name: &quot;chinesesimp&quot;<span class="comment">; MessagesFile: &quot;ChineseSimplified.isl&quot;</span></span><br><span class="line"><span class="section">[Types]</span></span><br><span class="line">Name: &quot;full&quot;<span class="comment">; Description: &quot;完整安装（推荐）&quot;</span></span><br><span class="line">Name: &quot;server&quot;<span class="comment">; Description: &quot;服务器安装&quot;</span></span><br><span class="line">Name: &quot;client&quot;<span class="comment">; Description: &quot;客户端安装&quot;</span></span><br><span class="line">Name: &quot;custom&quot;<span class="comment">; Description: &quot;自定义安装&quot;; Flags: iscustom</span></span><br><span class="line"><span class="section">[Components]</span></span><br><span class="line">Name: &quot;main&quot;<span class="comment">; Description: &quot;主程序&quot;; Types: full server client custom; Flags: fixed</span></span><br><span class="line">Name: &quot;database&quot;<span class="comment">; Description: &quot;数据库服务&quot;; Types: full server</span></span><br><span class="line">Name: &quot;web&quot;<span class="comment">; Description: &quot;Web服务&quot;; Types: full server</span></span><br><span class="line">Name: &quot;client&quot;<span class="comment">; Description: &quot;客户端组件&quot;; Types: full client custom</span></span><br><span class="line"><span class="section">[Files]</span></span><br><span class="line">Source: &quot;..\Server*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;&quot;; Flags: ignoreversion recursesubdirs; Components: main</span></span><br><span class="line">Source: &quot;..\Database*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;\Database&quot;; Flags: ignoreversion; Components: database</span></span><br><span class="line">Source: &quot;..\Web*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;\Web&quot;; Flags: ignoreversion; Components: web</span></span><br><span class="line">Source: &quot;..\Client*&quot;<span class="comment">; DestDir: &quot;&#123;app&#125;\Client&quot;; Flags: ignoreversion; Components: client</span></span><br><span class="line"><span class="section">[Run]</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\Database\setup.exe&quot;<span class="comment">; Parameters: &quot;/silent&quot;; StatusMsg: &quot;安装数据库...&quot;; Components: database</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\Web\install.exe&quot;<span class="comment">; Parameters: &quot;/quiet&quot;; StatusMsg: &quot;配置Web服务...&quot;; Components: web</span></span><br><span class="line">Filename: &quot;&#123;app&#125;\Client\Client.exe&quot;<span class="comment">; Description: &quot;启动客户端程序&quot;; Flags: nowait postinstall; Components: client</span></span><br><span class="line"><span class="section">[Icons]</span></span><br><span class="line">Name: &quot;&#123;group&#125;\企业管理系统&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\Client\Client.exe&quot;; Components: client</span></span><br><span class="line">Name: &quot;&#123;group&#125;\管理控制台&quot;<span class="comment">; Filename: &quot;&#123;app&#125;\AdminConsole.exe&quot;; Components: main</span></span><br><span class="line">Name: &quot;&#123;group&#125;\卸载企业管理系统&quot;<span class="comment">; Filename: &quot;&#123;uninstallexe&#125;&quot;</span></span><br></pre></td></tr></table></figure><h2 id="10-2-高级错误处理与日志记录">10.2 高级错误处理与日志记录</h2><figure class="highlight pascal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">[Code]</span><br><span class="line"><span class="keyword">var</span></span><br><span class="line">InstallLog: <span class="keyword">string</span>;</span><br><span class="line"><span class="function"><span class="keyword">procedure</span> <span class="title">LogMessage</span><span class="params">(Msg: <span class="keyword">string</span>)</span>;</span></span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">InstallLog := InstallLog + DateTimeToStr(Now) + <span class="string">&#x27; - &#x27;</span> + Msg + <span class="string">#13</span><span class="string">#10</span>;</span><br><span class="line">SaveStringToFile(ExpandConstant(<span class="string">&#x27;&#123;tmp&#125;\install.log&#x27;</span>), InstallLog, True);</span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">InitializeSetup</span><span class="params">()</span>:</span> Boolean;</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line"><span class="keyword">try</span></span><br><span class="line">LogMessage(<span class="string">&#x27;安装程序启动&#x27;</span>);</span><br><span class="line"><span class="comment">// 系统要求检查</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> IsAdminLoggedOn <span class="keyword">then</span> <span class="keyword">begin</span></span><br><span class="line">MsgBox(<span class="string">&#x27;需要管理员权限运行安装程序。&#x27;</span>, mbError, MB_OK);</span><br><span class="line">Result := False;</span><br><span class="line"><span class="keyword">Exit</span>;</span><br></pre></td></tr></table></figure><h1>第十一章：最佳实践与调试技巧</h1><h2 id="11-1-调试技巧">11.1 调试技巧</h2><ol><li><strong>使用日志输出</strong>：</li></ol><figure class="highlight pascal"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MsgBox(<span class="string">&#x27;调试信息: &#x27;</span> + SomeVariable, mbInformation, MB_OK);</span><br></pre></td></tr></table></figure><ol start="2"><li><strong>启用详细日志</strong>：</li></ol><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Setup]</span></span><br><span class="line"><span class="attr">SetupLogging</span>=<span class="literal">yes</span></span><br></pre></td></tr></table></figure><ol start="3"><li><strong>使用编译器指令</strong>：</li></ol><figure class="highlight pascal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ifdef DEBUG</span><br><span class="line">MsgBox(<span class="string">&#x27;调试模式已启用&#x27;</span>, mbInformation, MB_OK);</span><br><span class="line">endif</span><br></pre></td></tr></table></figure><h2 id="11-2-性能优化建议">11.2 性能优化建议</h2><ol><li><strong>文件压缩策略</strong>：</li></ol><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">Compression</span>=lzma2/max</span><br></pre></td></tr></table></figure><ol start="2"><li><p><strong>合理使用组件</strong>，避免不必要的文件复制</p></li><li><p><strong>优化脚本逻辑</strong>，减少不必要的注册表操作</p></li></ol><h1>总结</h1><p>通过本文的学习，您应该已经掌握了 Inno Setup 的核心概念和高级技巧。从基础的文件复制到复杂的数据库集成，从简单的安装界面到自定义的安装逻辑，Inno Setup 都能提供强大的支持。</p><p><strong>关键要点回顾：</strong></p><ol><li><strong>规划先行</strong>：在开始编写脚本前，明确安装需求和目标环境</li><li><strong>模块化设计</strong>：合理使用组件和安装类型，提高灵活性</li><li><strong>错误处理</strong>：完善的错误处理机制是专业安装包的标志</li><li><strong>用户体验</strong>：清晰的提示和友好的界面同样重要</li><li><strong>测试充分</strong>：在不同环境下全面测试安装包</li></ol><p>Inno Setup 的学习曲线相对平缓，但功能深度很大。建议从简单的项目开始，逐步尝试更复杂的功能，最终能够制作出满足各种需求的专业级安装包。</p><h1>致谢</h1><div class="note default flat"><p>笔者水平有限，内容参考：<a href="https://chat.deepseek.com">DeepSeek</a></p></div><hr><p><em>本文基于实际项目经验编写，示例代码经过脱敏处理，可直接用于学习参考。建议在实际项目中根据具体需求进行调整和优化。</em></p>]]></content>
    
    
    <summary type="html">适用于创建专业级 Windows 安装包，方便查阅相关语法</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="Windows" scheme="https://home.y1xuanyun.cn/tags/Windows/"/>
    
    <category term="脚本" scheme="https://home.y1xuanyun.cn/tags/%E8%84%9A%E6%9C%AC/"/>
    
    <category term="Inno Setup" scheme="https://home.y1xuanyun.cn/tags/Inno-Setup/"/>
    
    <category term="打包" scheme="https://home.y1xuanyun.cn/tags/%E6%89%93%E5%8C%85/"/>
    
    <category term="安装包" scheme="https://home.y1xuanyun.cn/tags/%E5%AE%89%E8%A3%85%E5%8C%85/"/>
    
  </entry>
  
  <entry>
    <title>PICO 4 Ultra VR游戏开发完全指南</title>
    <link href="https://home.y1xuanyun.cn/posts/25u3d03.html"/>
    <id>https://home.y1xuanyun.cn/posts/25u3d03.html</id>
    <published>2025-09-20T03:00:00.000Z</published>
    <updated>2025-09-21T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>本文详细记录了基于Unity引擎进行PICO 4 Ultra VR游戏开发的完整流程，重点总结了环境配置、SDK导入、核心功能实现、常见问题排查与解决方案，旨在帮助开发者高效完成VR项目开发与发布。</p></blockquote><hr><h1>一、 环境配置与SDK导入</h1><h2 id="1-获取开发资源">1. 获取开发资源</h2><ul><li>从PICO开发者官网下载最新版 <strong>PICO Unity Integration SDK</strong></li><li>在Unity中通过 <code>Assets &gt; Import Package &gt; Custom Package...</code> 导入SDK包</li></ul><h2 id="2-核心项目设置">2. 核心项目设置</h2><table><thead><tr><th style="text-align:left">设置项</th><th style="text-align:left">要求</th><th style="text-align:left">路径</th></tr></thead><tbody><tr><td style="text-align:left"><strong>Minimum API Level</strong></td><td style="text-align:left">Android 10.0 (API level 29) +</td><td style="text-align:left">Player Settings &gt; Other Settings</td></tr><tr><td style="text-align:left"><strong>Scripting Backend</strong></td><td style="text-align:left">IL2CPP</td><td style="text-align:left">Player Settings &gt; Other Settings</td></tr><tr><td style="text-align:left"><strong>Target Architectures</strong></td><td style="text-align:left">ARM64</td><td style="text-align:left">Player Settings &gt; Other Settings</td></tr><tr><td style="text-align:left"><strong>Active Input Handling</strong></td><td style="text-align:left">Input System Package (New)</td><td style="text-align:left">Player Settings &gt; Configuration</td></tr><tr><td style="text-align:left"><strong>XR Plug-in Management</strong></td><td style="text-align:left">启用PICO</td><td style="text-align:left">Project Settings &gt; XR Plug-in Management &gt; Android</td></tr></tbody></table><h2 id="3-一键配置">3. 一键配置</h2><p>导入SDK后弹出的 <strong>PICO Unity Setup Tool</strong> 窗口，直接点击 <strong><code>Apply All</code></strong> 完成自动配置，重启Unity生效。</p><h2 id="4-PICO-4-Ultra-更新">4. PICO 4 Ultra 更新</h2><p>我们需要在SDK包中点击左侧 <strong><code>Toolkit</code></strong> 包，并选择左侧 <strong><code>样本</code></strong> 折叠卡，导入最新的 <strong><code>Starter Assets</code></strong></p><hr><h1>二、 场景搭建与视角处理</h1><h2 id="1-场景设置">1. 场景设置</h2><ul><li><strong>删除</strong>场景中默认的 <code>Main Camera</code> 对象</li><li>使用PICO官方预制体 <strong><code>XR Interaction Setup</code></strong>（推荐）或XR Interaction Toolkit的 <strong><code>XR Origin</code></strong></li></ul><h2 id="2-核心组件解析">2. 核心组件解析</h2><table><thead><tr><th style="text-align:left">组件</th><th style="text-align:left">功能说明</th><th style="text-align:left">所在路径</th></tr></thead><tbody><tr><td style="text-align:left"><strong>XR Origin (XR Rig)</strong></td><td style="text-align:left">VR玩家根对象，管理所有追踪设备</td><td style="text-align:left">场景根层级</td></tr><tr><td style="text-align:left"><strong>Camera Offset</strong></td><td style="text-align:left">调整玩家虚拟身高（Y坐标）</td><td style="text-align:left">XR Origin子对象</td></tr><tr><td style="text-align:left"><strong>Main Camera</strong></td><td style="text-align:left">头显视角，由设备自动驱动</td><td style="text-align:left">Camera Offset子对象</td></tr><tr><td style="text-align:left"><strong>Tracked Pose Driver</strong></td><td style="text-align:left">关键组件，将头显数据应用至摄像机</td><td style="text-align:left">Main Camera组件</td></tr></tbody></table><h2 id="3-⚠️-常见问题：视角无法跟随头显转动">3. ⚠️ 常见问题：视角无法跟随头显转动</h2><p><strong>现象</strong>：只能用手柄控制移动和转向，头部转动无效。</p><p><strong>解决方案</strong>：</p><ol><li><strong>设备连接检查</strong>：<ul><li>头显内开启 <strong>开发者模式</strong> 和 <strong>USB调试</strong></li><li>连接电脑时选择“传输文件”</li><li>电脑端使用 <code>adb devices</code> 命令验证连接</li></ul></li><li><strong>组件验证</strong>：确保 <code>Main Camera</code> 上有 <code>Tracked Pose Driver</code> 组件且配置正确</li><li><strong>权限问题</strong>：Unity编辑器切勿以管理员身份运行</li><li><strong>驱动不兼容</strong>：使用PICO官方预制体 <strong><code>XR Interaction Setup</code></strong></li></ol><hr><h1>三、 输入设备绑定与交互</h1><h2 id="1-手柄模型绑定">1. 手柄模型绑定</h2><ul><li>PICO专用手柄预制体路径：<code>Packages/PICO Integration/Assets/Resources/Prefabs/Controllers/</code></li><li>将 <strong><code>PICOControllerLeft</code></strong> 和 <strong><code>PICOControllerRight</code></strong> 预制体分别赋值给：<ul><li><code>XR Origin/LeftHand Controller</code> 的 <code>Model Prefab</code> 属性</li><li><code>XR Origin/RightHand Controller</code> 的 <code>Model Prefab</code> 属性</li></ul></li></ul><h2 id="2-交互逻辑实现（XR-Interaction-Toolkit）">2. 交互逻辑实现（XR Interaction Toolkit）</h2><table><thead><tr><th style="text-align:left">组件</th><th style="text-align:left">功能</th><th style="text-align:left">添加对象</th></tr></thead><tbody><tr><td style="text-align:left"><strong>XR Grab Interactable</strong></td><td style="text-align:left">使物体可被抓取</td><td style="text-align:left">骰子、棋子等交互物</td></tr><tr><td style="text-align:left"><strong>XR Ray Interactor</strong></td><td style="text-align:left">从手柄发射射线</td><td style="text-align:left">Left/Right Hand Controller</td></tr><tr><td style="text-align:left"><strong>XR Socket Interactor</strong></td><td style="text-align:left">创建精准插槽</td><td style="text-align:left">目标放置位置</td></tr></tbody></table><hr><h1>四、 UI系统适配</h1><h2 id="1-Canvas设置">1. Canvas设置</h2><ul><li>将UI <code>Canvas</code> 的 <strong><code>Render Mode</code></strong> 从 <code>Screen Space - Overlay</code> 改为 <strong><code>World Space</code></strong></li><li>像操作3D物体一样调整其位置、旋转和缩放</li></ul><h2 id="2-交互改造">2. 交互改造</h2><ul><li>为每个可交互UI元素（Button、Slider等）<strong>单独添加</strong> <code>Box Collider</code> 组件</li><li><strong>必须勾选</strong> <code>Box Collider</code> 的 <strong><code>Is Trigger</code></strong> 属性</li><li>将 <code>EventSystem</code> 上的 <code>Standalone Input Module</code> 替换为 <strong><code>XR UI Input Module</code></strong></li></ul><hr><h1>五、 构建与部署</h1><h2 id="1-构建设置">1. 构建设置</h2><ul><li>打开 <code>File &gt; Build Settings</code>，选择 <strong>Android</strong> 平台</li><li>在 <strong><code>Run Device</code></strong> 下拉菜单中选择已连接的PICO设备</li></ul><h2 id="2-开始构建">2. 开始构建</h2><ul><li>点击 <strong><code>Build And Run</code></strong> 进行自动编译并安装至头显</li><li><strong>备选方案</strong>：点击 <strong><code>Build</code></strong> 生成APK，通过 <code>adb install</code> 或手动安装</li></ul><h2 id="3-⚠️-构建常见问题">3. ⚠️ 构建常见问题</h2><p><strong>问题1：Active Input Handling is set to Both</strong></p><ul><li><strong>解决</strong>：在 <code>Player Settings &gt; Configuration</code> 中，将输入处理改为 <strong><code>Input System Package (New)</code></strong> only</li></ul><p><strong>问题2：No Android devices connected</strong></p><ul><li><strong>解决</strong>：检查设备USB连接、驱动及头显内的USB调试开关</li></ul><hr><h1>六、 性能优化与体验建议</h1><ul><li><strong>性能</strong>：维持高帧率（72/90Hz）是核心。使用Unity Profiler分析，优化Draw Call（静态合批），应用LOD，烘焙光照</li><li><strong>舒适性</strong>：移动方式优先选择 <strong>瞬移 (<code>Teleportation</code>)</strong>，减少晕动症</li><li><strong>沉浸感</strong>：为交互添加手柄震动反馈，使用空间音频</li></ul><hr><h1>总结</h1><p>通过以上系统化的流程，开发者可以高效完成PICO 4 Ultra的VR游戏开发，规避常见陷阱，并打造出体验优秀的沉浸式应用。关键在于确保基础环境配置正确，善用官方预制体与XR Interaction Toolkit组件，并遵循VR设计的特定规范（如UI适配、移动方式选择）。</p>]]></content>
    
    
    <summary type="html">Unity开发移植到PICO 4 Ultra设备上的VR游戏</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="C#" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="Unity" scheme="https://home.y1xuanyun.cn/tags/Unity/"/>
    
    <category term="3D" scheme="https://home.y1xuanyun.cn/tags/3D/"/>
    
    <category term="VR" scheme="https://home.y1xuanyun.cn/tags/VR/"/>
    
    <category term="虚拟现实" scheme="https://home.y1xuanyun.cn/tags/%E8%99%9A%E6%8B%9F%E7%8E%B0%E5%AE%9E/"/>
    
    <category term="PICO 4 Ultra" scheme="https://home.y1xuanyun.cn/tags/PICO-4-Ultra/"/>
    
    <category term="移植" scheme="https://home.y1xuanyun.cn/tags/%E7%A7%BB%E6%A4%8D/"/>
    
  </entry>
  
  <entry>
    <title>Hex博客CDN资源失效问题的完整解决实录</title>
    <link href="https://home.y1xuanyun.cn/posts/25web01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25web01.html</id>
    <published>2025-09-06T03:00:00.000Z</published>
    <updated>2025-09-06T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>本文详细记录了一次Hexo博客CDN资源链接失效问题的发现、分析、解决和复盘全过程，为类似问题提供完整的解决思路和方案。</p></blockquote><h1>问题背景</h1><p>近期，我的基于Hexo和Butterfly主题的个人博客部分功能突然异常，包括：</p><ul><li>图片懒加载失效</li><li>音乐播放器无法显示</li><li>Font Awesome图标不显示</li><li>打字机效果消失</li><li>页面预加载功能失效</li></ul><h1>第一阶段：问题发现与诊断</h1><h2 id="症状识别">症状识别</h2><p>通过浏览器开发者工具(F12)的Console面板，发现大量404错误，指向以下失效CDN链接：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 所有链接均返回404状态码</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/instant.page/5.1.0/instantpage.min.js</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vanilla-lazyload/17.3.1/lazyload.iife.min.js</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/6.0.0/css/all.min.css</span></span><br><span class="line"><span class="attr">https</span>:<span class="comment">//lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/typed.js/2.0.12/typed.min.js</span></span><br></pre></td></tr></table></figure><p>根本原因分析<br>这些链接原本来自字节跳动的CDN服务，但现已失效或停止对外服务，导致依赖这些外部资源的博客功能全部瘫痪。</p><h1>第二阶段：解决方案探索</h1><h2 id="方案一：替换为jsDelivr-CDN（初次尝试）">方案一：替换为jsDelivr CDN（初次尝试）</h2><p>最初选择jsDelivr作为替代方案，因为它是对开发者友好的公共CDN：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 初步替换方案</span></span><br><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://cdn.jsdelivr.net/npm/instant.page/5.1.0/instantpage.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.8.3/dist/lazyload.iife.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js&quot;&gt;&lt;/script&gt;</span></span><br></pre></td></tr></table></figure><h2 id="方案二：转向UNPKG-CDN（实际采用）">方案二：转向UNPKG CDN（实际采用）</h2><p>发现jsDelivr在某些地区访问不稳定后，转向UNPKG：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 初步替换方案</span></span><br><span class="line"><span class="comment"># 最终采用的UNPKG方案</span></span><br><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;https://unpkg.com/aplayer@1.10.1/dist/APlayer.min.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;https://unpkg.com/@fortawesome/fontawesome-free@6.5.1/css/all.min.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://unpkg.com/instant.page@5.1.0/instantpage.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://unpkg.com/vanilla-lazyload@17.8.3/dist/lazyload.iife.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://unpkg.com/aplayer@1.10.1/dist/APlayer.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://unpkg.com/typed.js@2.0.12/lib/typed.min.js&quot;&gt;&lt;/script&gt;</span></span><br></pre></td></tr></table></figure><h2 id="方案三：Butterfly主题内置功能启用">方案三：Butterfly主题内置功能启用</h2><p>对于某些功能，Butterfly主题已提供内置支持：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># _config.butterfly.yml</span></span><br><span class="line"><span class="attr">lazyload:</span> <span class="literal">true</span>        <span class="comment"># 启用懒加载</span></span><br><span class="line"><span class="attr">instantpage:</span> <span class="literal">true</span>     <span class="comment"># 启用即时预览</span></span><br><span class="line"><span class="attr">pjax:</span> <span class="literal">true</span>            <span class="comment"># 启用PJAX局部刷新</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 音乐播放器配置</span></span><br><span class="line"><span class="attr">aplayer:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">meting:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">asset_inject:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><h1>第三阶段：方案实施与验证</h1><h2 id="实施步骤">实施步骤</h2><ol><li>备份原配置文件 _config.butterfly.yml</li><li>根据采用的方案修改注入配置</li><li>执行 hexo clean &amp;&amp; hexo g &amp;&amp; hexo s 本地测试</li><li>检查浏览器控制台是否还有错误</li><li>逐一测试各功能是否恢复正常</li></ol><h2 id="验证结果">验证结果</h2><p>功能状态备注<br>图片懒加载✅ 正常需确保初始化代码正确<br>音乐播放器✅ 正常APlayer样式和功能均恢复<br>Font Awesome图标✅ 正常注意版本6的类名变化<br>打字机效果✅ 正常Typed.js工作正常<br>页面预加载✅ 正常Instant.page生效</p><h1>第四阶段：复盘与优化建议</h1><h2 id="问题根源">问题根源</h2><p>过度依赖第三方CDN服务，没有考虑其稳定性和长期可用性。</p><h2 id="长期解决方案">长期解决方案</h2><ol><li>自托管关键资源（推荐）<br>将第三方库下载到本地，使用相对路径引用：</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 目录结构</span></span><br><span class="line"><span class="built_in">source</span>/</span><br><span class="line">├── css/</span><br><span class="line">│   ├── APlayer.min.css</span><br><span class="line">│   └── all.min.css</span><br><span class="line">└── js/</span><br><span class="line">    ├── instantpage.js</span><br><span class="line">    ├── lazyload.iife.min.js</span><br><span class="line">    ├── APlayer.min.js</span><br><span class="line">    └── typed.min.js</span><br></pre></td></tr></table></figure><p>配置引用：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/APlayer.min.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/all.min.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;/js/instantpage.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;/js/lazyload.iife.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;/js/APlayer.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;/js/typed.min.js&quot;&gt;&lt;/script&gt;</span></span><br></pre></td></tr></table></figure><ol start="2"><li>使用多种CDN备用方案<br>通过JavaScript实现CDN回退策略：</li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="variable language_">window</span>.<span class="property">WebFontConfig</span> = &#123;</span></span><br><span class="line"><span class="language-javascript">  <span class="attr">custom</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">families</span>: [<span class="string">&#x27;Font Awesome&#x27;</span>],</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">urls</span>: [<span class="string">&#x27;https://cdn1.example.com/font-awesome.min.css&#x27;</span>]</span></span><br><span class="line"><span class="language-javascript">  &#125;,</span></span><br><span class="line"><span class="language-javascript">  <span class="attr">timeout</span>: <span class="number">2000</span>,</span></span><br><span class="line"><span class="language-javascript">  <span class="attr">active</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Font loaded successfully&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">  &#125;,</span></span><br><span class="line"><span class="language-javascript">  <span class="attr">inactive</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 加载失败，使用备用CDN</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> link = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;link&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">    link.<span class="property">rel</span> = <span class="string">&#x27;stylesheet&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">    link.<span class="property">href</span> = <span class="string">&#x27;https://cdn2.example.com/font-awesome.min.css&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">    <span class="variable language_">document</span>.<span class="property">head</span>.<span class="title function_">appendChild</span>(link);</span></span><br><span class="line"><span class="language-javascript">  &#125;</span></span><br><span class="line"><span class="language-javascript">&#125;;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">(<span class="keyword">function</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> wf = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;script&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">  wf.<span class="property">src</span> = <span class="string">&#x27;https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">  wf.<span class="property">type</span> = <span class="string">&#x27;text/javascript&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">  wf.<span class="property">async</span> = <span class="string">&#x27;true&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> s = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&#x27;script&#x27;</span>)[<span class="number">0</span>];</span></span><br><span class="line"><span class="language-javascript">  s.<span class="property">parentNode</span>.<span class="title function_">insertBefore</span>(wf, s);</span></span><br><span class="line"><span class="language-javascript">&#125;)();</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ol start="3"><li>定期检查与监控<br>使用浏览器开发者工具定期检查资源加载情况<br>考虑使用自动化监控工具如UptimeRobot<br>建立资源健康检查清单</li></ol><h1>经验总结</h1><ol><li>不要过度依赖单一CDN：公共CDN服务可能随时变更或停止服务</li><li>自托管是最稳定的方案：对于关键资源，本地化是最可靠的选择</li><li>版本控制很重要：记录所有第三方库的版本号，便于问题排查</li><li>备用方案是必须的：始终为关键资源准备备用加载方案</li><li>定期检查是预防之道：建立定期检查机制，防患于未然</li></ol><h1>附录：常用CDN服务对比</h1><p>CDN服务优点缺点适用场景<br>jsDelivr免费、可靠、支持npm国内访问偶尔不稳定通用项目<br>UNPKG简单易用、更新及时无国内节点国际项目<br>BootCDN国内访问快、稳定库版本可能不全国内项目<br>自托管最稳定、完全可控需要手动更新生产环境</p>]]></content>
    
    
    <summary type="html">问题的发现、分析、解决和复盘全过程</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="资源失效" scheme="https://home.y1xuanyun.cn/tags/%E8%B5%84%E6%BA%90%E5%A4%B1%E6%95%88/"/>
    
    <category term="计算机网络" scheme="https://home.y1xuanyun.cn/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
    
    <category term="CDN" scheme="https://home.y1xuanyun.cn/tags/CDN/"/>
    
  </entry>
  
  <entry>
    <title>内网穿透介绍及教务系统上的应用</title>
    <link href="https://home.y1xuanyun.cn/posts/25int01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25int01.html</id>
    <published>2025-07-10T02:00:00.000Z</published>
    <updated>2025-07-10T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>什么是内网穿透？</h1><p>内网穿透（NAT Traversal）是一种通过公网服务器访问内网服务的技术。由于校园网、企业局域网等内部网络通常采用NAT（网络地址转换）隔离外部互联网，导致外部用户无法直接访问内网资源。内网穿透通过建立加密隧道，将内网服务的端口映射到公网服务器的指定端口，从而实现外部访问。</p><h1>SSH与内网穿透</h1><p>SSH（Secure Shell）不仅是安全的远程登录协议，还支持端口转发功能（SSH Tunnel），使其成为实现轻量级内网穿透的理想工具。通过SSH的本地端口转发（Local Port Forwarding）和远程端口转发（Remote Port Forwarding），可以安全地将内网服务暴露到公网。</p><hr><h1>实践：将校内教务系统映射至阿里云服务器</h1><h2 id="场景描述">场景描述</h2><ul><li><strong>目标内网服务</strong>：教务系统（<code>194.168.4.17:80</code>，假设为HTTP服务）</li><li><strong>公网服务器</strong>：阿里云（<code>182.92.83.1:30226</code>）</li><li><strong>使用工具</strong>：SSH（需一台可访问校内服务的机器和公网服务器）</li></ul><h2 id="步骤1：建立SSH远程端口转发">步骤1：建立SSH远程端口转发</h2><p>在能访问校内教务系统的机器（如实验室电脑）上执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -R 30226:194.168.4.17:80 root@182.92.83.1-N</span><br></pre></td></tr></table></figure><ul><li><code>-R 30226:194.168.4.17:80</code>：将公网服务器的30226端口转发到内网服务的80端口</li><li><code>root@182.92.83.1</code>：公网服务器的登录账号和地址</li><li><code>-N</code>：不执行远程命令，仅建立隧道</li></ul><h2 id="步骤2：通过公网访问服务">步骤2：通过公网访问服务</h2><p>此时通过浏览器访问 <code>http://182.92.83.1:30226</code> 即可间接访问校内教务系统。</p><hr><h1>解决资源加载失败问题：额外端口转发</h1><p>若教务系统页面加载时出现CSS/JS等静态资源失败（可能因为资源使用<strong>绝对路径</strong>指向其他内网端口），需进一步转发相关端口。</p><h2 id="示例：资源端口为8080">示例：资源端口为8080</h2><p>假设发现资源请求指向 <code>194.168.4.17:8080</code>，需额外映射该端口到公网（如30227）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -R 30226:194.168.4.17:80 -R 30227:194.168.4.17:8080 root@182.92.83.1-N</span><br></pre></td></tr></table></figure><h2 id="优化方案：反向代理">优化方案：反向代理</h2><p>若资源端口不固定，可在公网服务器配置Nginx反向代理，统一将请求转发到内网：</p><p>nginx</p><p>Nginx配置示例（公网服务器）</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line">    listen <span class="number">30226</span>;</span><br><span class="line">    location / &#123;</span><br><span class="line">    proxy_pass <span class="attr">http</span>:<span class="comment">//194.168.4.17:80;</span></span><br><span class="line">    proxy_set_header <span class="title class_">Host</span> $host;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>随后通过SSH建立基础隧道即可：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -L 本地端口:194.168.4.17:80 root@182.92.83.1-N</span><br></pre></td></tr></table></figure><hr><h1>注意事项</h1><ol><li><strong>网络安全</strong>：暴露内网服务到公网需获得授权，并配置防火墙限制访问IP。</li><li><strong>稳定性</strong>：SSH隧道可能因网络波动中断，建议使用autossh等工具自动重连。</li><li><strong>性能</strong>：公网服务器带宽和延迟会影响访问速度。</li></ol><hr><h1>总结</h1><p>通过SSH端口转发，可快速实现内网穿透，但需注意资源路径和端口问题。对于复杂场景，结合反向代理能更灵活地解决多端口或协议转换需求。</p>]]></content>
    
    
    <summary type="html">使用SSH实现内网穿透：将校内教务系统映射至公网</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="IP" scheme="https://home.y1xuanyun.cn/tags/IP/"/>
    
    <category term="内网穿透" scheme="https://home.y1xuanyun.cn/tags/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
    
    <category term="端口转发" scheme="https://home.y1xuanyun.cn/tags/%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91/"/>
    
    <category term="SSH" scheme="https://home.y1xuanyun.cn/tags/SSH/"/>
    
    <category term="资源失效" scheme="https://home.y1xuanyun.cn/tags/%E8%B5%84%E6%BA%90%E5%A4%B1%E6%95%88/"/>
    
    <category term="计算机网络" scheme="https://home.y1xuanyun.cn/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
    
    <category term="内网" scheme="https://home.y1xuanyun.cn/tags/%E5%86%85%E7%BD%91/"/>
    
    <category term="公网" scheme="https://home.y1xuanyun.cn/tags/%E5%85%AC%E7%BD%91/"/>
    
  </entry>
  
  <entry>
    <title>基于Unity3D的AiChat模块</title>
    <link href="https://home.y1xuanyun.cn/posts/25u3d02.html"/>
    <id>https://home.y1xuanyun.cn/posts/25u3d02.html</id>
    <published>2025-07-01T03:00:00.000Z</published>
    <updated>2025-07-01T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>引言</h1><p>随着人工智能技术的快速发展，语音识别已成为现代应用的重要组成部分。在Unity开发中，集成语音识别功能可以极大提升用户体验，特别是在游戏、VR/AR应用和交互式展示中。与传统云端语音识别方案不同，<strong>离线语音识别</strong>无需网络连接，具有更好的隐私保护性和实时性。Vosk作为一款开源的离线语音识别库，凭借其轻量级、高精度和跨平台特性，成为Unity开发者的理想选择。</p><p>Vosk基于深度神经网络和隐马尔可夫模型（DNN-HMM），支持<strong>20多种语言</strong>，包括中文、英语、法语、德语等，并提供多种规模的预训练模型以满足不同场景的需求。其完全离线的特性使其特别适合对数据隐私要求较高的应用场景。</p><p>本文将详细介绍如何在Unity项目中配置Vosk环境，为实现语音识别功能奠定基础。</p><h1>1. Vosk简介与特点</h1><p>Vosk是一个基于Kaldi语音识别工具包构建的开源离线语音识别引擎，具有以下核心特点：</p><ul><li><strong>完全离线工作</strong>：无需网络连接，所有数据处理均在设备本地完成，保证了数据安全和隐私保护</li><li><strong>多语言支持</strong>：支持中文、英文、法文、德文等20多种语言，满足国际化项目需求</li><li><strong>轻量高效</strong>：模型体积小（最小仅12MB），内存占用低，在树莓派等嵌入式设备上也能流畅运行</li><li><strong>高准确率</strong>：基于深度学习算法，在安静环境下识别准确率可达95%以上</li><li><strong>跨平台兼容</strong>：支持Windows、Linux、macOS、Android和iOS等多个平台</li><li><strong>实时识别</strong>：提供流式API，支持实时语音识别，延迟控制在200ms以内</li></ul><p>与其他语音识别方案相比，Vosk在资源消耗和响应速度方面表现优异，特别适合集成到Unity项目中实现实时语音交互功能。</p><h1>2. 环境配置准备工作</h1><p>在开始集成Vosk前，需要完成以下准备工作：</p><h2 id="2-1-系统与Unity要求">2.1 系统与Unity要求</h2><ul><li><strong>Unity版本</strong>：建议使用2019.4或更高版本，<a href="http://xn--ruu81c.NET">支持.NET</a> 4.x或更高版本</li><li><strong>操作系统</strong>：Windows、macOS或Linux开发环境</li><li><strong>存储空间</strong>：至少1GB可用空间（用于存放模型文件）</li></ul><h2 id="2-2-下载Vosk相关文件">2.2 下载Vosk相关文件</h2><ol><li><strong>Vosk Unity插件</strong>：从GitHub获取Vosk的C#绑定库（<a href="https://github.com/alphacep/vosk-unity-asr%EF%BC%89">https://github.com/alphacep/vosk-unity-asr）</a></li><li><strong>语音模型</strong>：从Vosk模型库（<a href="https://alphacephei.com/vosk/models%EF%BC%89%E4%B8%8B%E8%BD%BD%E6%89%80%E9%9C%80%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%EF%BC%9A">https://alphacephei.com/vosk/models）下载所需语言模型：</a><ul><li><strong>中文小型模型</strong>（vosk-model-small-cn-0.22，约42MB）：适合移动设备和嵌入式系统</li><li><strong>中文标准模型</strong>（vosk-model-cn-0.22，约1.3GB）：提供更高精度，适合服务器或高性能设备</li></ul></li></ol><h1>3. Unity项目配置步骤</h1><h2 id="3-1-创建Unity项目并导入Vosk">3.1 创建Unity项目并导入Vosk</h2><ol><li>新建Unity项目或打开现有项目</li><li>在Assets文件夹中创建<code>Plugins</code>文件夹，存放Vosk的DLL文件（如<code>libvosk.dll</code>、<code>vosk.dll</code>等）</li><li>将下载的Vosk Unity插件文件导入到项目中</li></ol><h2 id="3-2-导入模型文件">3.2 导入模型文件</h2><ol><li>在Assets目录下创建<code>StreamingAssets</code>文件夹（如果尚未存在）</li><li>将下载的模型压缩包（如<code>vosk-model-small-cn-0.22.zip</code>）直接放入<code>StreamingAssets</code>文件夹中<ul><li>注意：<strong>无需解压</strong>模型文件，Vosk可以直接读取压缩包内容</li></ul></li></ol><h2 id="3-3-配置播放器设置">3.3 配置播放器设置</h2><ol><li>打开&quot;File &gt; Build Settings &gt; Player Settings&quot;</li><li>在&quot;Configuration&quot;选项中，确保&quot;.NET Runtime Version&quot;设置为&quot;.NET 4.x&quot;或更高版本</li><li>根据目标平台进行相应设置：<ul><li><strong>Windows</strong>：无需特殊配置</li><li><strong>Android</strong>：确保设置适当的权限（麦克风访问权限）</li><li><strong>iOS</strong>：需要额外配置麦克风使用描述</li></ul></li></ol><h1>4. 模型选择与优化建议</h1><h2 id="4-1-模型选择策略">4.1 模型选择策略</h2><p>根据应用场景选择合适的模型至关重要：</p><table><thead><tr><th>模型类型</th><th>大小</th><th>适用场景</th><th>硬件要求</th></tr></thead><tbody><tr><td>小型模型</td><td>40-50MB</td><td>移动设备、嵌入式系统</td><td>低端CPU，256MB+内存</td></tr><tr><td>标准模型</td><td>1.3-1.5GB</td><td>桌面应用、服务器</td><td>多核CPU，2GB+内存</td></tr><tr><td>专业模型</td><td>1.5GB+</td><td>专业语音识别</td><td>高性能CPU，8GB+内存</td></tr></tbody></table><h2 id="4-2-性能优化建议">4.2 性能优化建议</h2><ul><li><strong>音频格式配置</strong>：确保音频输入为16kHz、16位单声道格式，这是Vosk模型的标准输入格式</li><li><strong>预处理优化</strong>：使用音频滤波算法减少背景噪音干扰</li><li><strong>资源管理</strong>：在不需要语音识别时及时释放识别器资源，减少内存占用</li><li><strong>多线程处理</strong>：将语音识别处理放在单独线程中，避免阻塞主线程</li></ul><h1>5. 常见问题与解决方案</h1><p>在配置和使用Vosk过程中可能会遇到以下常见问题：</p><ol><li><p><strong>模型加载失败</strong></p><ul><li><em>原因</em>：模型路径错误或模型文件不完整</li><li><em>解决</em>：检查模型文件是否放置在<code>StreamingAssets</code>文件夹中，并确认文件完整性</li></ul></li><li><p><strong>识别准确率低</strong></p><ul><li><em>原因</em>：环境噪音或音频格式不匹配</li><li><em>解决</em>：添加音频预处理环节，确保输入音频符合16kHz、16位单声道要求</li></ul></li><li><p><strong>性能问题</strong></p><ul><li><em>原因</em>：模型过大或硬件资源不足</li><li><em>解决</em>：根据设备性能选择合适的模型规模，或考虑添加加载屏幕</li></ul></li><li><p><strong>平台兼容性问题</strong></p><ul><li><em>原因</em>：不同平台的库文件不兼容</li><li><em>解决</em>：确保使用针对目标平台编译的Vosk库文件</li></ul></li></ol><h1>6. 基于Vosk的AI聊天代码实现</h1><h2 id="主控模块">主控模块</h2><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> UnityEngine;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.Networking;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.UI;</span><br><span class="line"><span class="keyword">using</span> TMPro;</span><br><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"><span class="keyword">using</span> System.Collections;</span><br><span class="line"><span class="keyword">using</span> System.Collections.Generic;</span><br><span class="line"><span class="keyword">using</span> System.Text;</span><br><span class="line"><span class="keyword">using</span> System.Text.RegularExpressions;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">AiChat</span> : <span class="title">MonoBehaviour</span></span><br><span class="line">&#123;</span><br><span class="line">    [<span class="meta">Header(<span class="string">&quot;UI 绑定&quot;</span>)</span>]</span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="keyword">public</span> TMP_InputField inputField;       <span class="comment">// 问题输入框</span></span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="keyword">public</span> Button submitButton;             <span class="comment">// 提交按钮</span></span><br><span class="line">    [<span class="meta">SerializeField</span>] Text answerText;                 <span class="comment">// 答案文本框</span></span><br><span class="line">    [<span class="meta">SerializeField</span>] Toggle ttsToggle;                <span class="comment">// 语音合成开关</span></span><br><span class="line"></span><br><span class="line">    [<span class="meta">Header(<span class="string">&quot;API Settings&quot;</span>)</span>]</span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="built_in">string</span> apiUrl = <span class="string">&quot;接口链接&quot;</span>;</span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="built_in">string</span> apiKey = <span class="string">&quot;密钥&quot;</span>;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">Header(<span class="string">&quot;Chat Settings&quot;</span>)</span>]</span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="keyword">public</span> <span class="built_in">string</span> askTag = <span class="string">&quot;&quot;</span>;</span><br><span class="line">    [<span class="meta">SerializeField</span>] <span class="keyword">public</span> AIChatAssistant getRAGChat;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">bool</span> isStreaming = <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">private</span> Coroutine streamCoroutine;</span><br><span class="line">    <span class="keyword">private</span> StringBuilder fullResponse = <span class="keyword">new</span> StringBuilder();</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Start</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">//判断网络状态</span></span><br><span class="line">        <span class="keyword">if</span> (Application.internetReachability != NetworkReachability.NotReachable)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 原：绑定按钮点击事件</span></span><br><span class="line">            <span class="comment">// submitButton.onClick.AddListener(OnSubmitClicked);</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">// 当前已被RAGC模块劫持</span></span><br><span class="line">            submitButton.onClick.AddListener(OnSubmitClick);</span><br><span class="line">            <span class="comment">// 直接监听RAGChat组件</span></span><br><span class="line">            submitButton.onClick.AddListener(() =&gt; StartCoroutine(getRAGChat.SubmitQuestion()));</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 初始状态设置</span></span><br><span class="line">            submitButton.interactable = <span class="literal">true</span>;</span><br><span class="line">            answerText.text = <span class="string">&quot;等待输入问题...&quot;</span>;</span><br><span class="line">            <span class="comment">//默认打开语音合成开关</span></span><br><span class="line">            ttsToggle.isOn = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            answerText.text = <span class="string">&quot;请检查网络连接！&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 点击劫持方法</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">OnSubmitClick</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        getRAGChat.questionInput = inputField.text;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">OnSubmitClicked</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">string</span>.IsNullOrWhiteSpace(inputField.text))</span><br><span class="line">        &#123;</span><br><span class="line">            answerText.text = <span class="string">&quot;&lt;color=#FF0000&gt;请输入有效问题！&lt;/color&gt;&quot;</span>;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 如果已有请求在进行中，先停止</span></span><br><span class="line">        <span class="keyword">if</span> (isStreaming &amp;&amp; streamCoroutine != <span class="literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            StopCoroutine(streamCoroutine);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 重置状态</span></span><br><span class="line">        isStreaming = <span class="literal">true</span>;</span><br><span class="line">        fullResponse.Clear();</span><br><span class="line">        answerText.text = <span class="string">&quot;思考中...&quot;</span>;</span><br><span class="line">        submitButton.interactable = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 开始流式请求</span></span><br><span class="line">        streamCoroutine = StartCoroutine(StreamChatCompletion(inputField.text));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">StreamChatCompletion</span>(<span class="params"><span class="built_in">string</span> userMessage</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 准备请求数据</span></span><br><span class="line">        <span class="keyword">var</span> requestData = <span class="keyword">new</span> RequestData</span><br><span class="line">        &#123;</span><br><span class="line">            messages = <span class="keyword">new</span> List&lt;Message&gt;</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">new</span> Message &#123; role = <span class="string">&quot;user&quot;</span>, content = userMessage + <span class="string">&quot;，&quot;</span> + askTag &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            stream = <span class="literal">true</span></span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        <span class="built_in">string</span> jsonPayload = JsonUtility.ToJson(requestData);</span><br><span class="line">        <span class="built_in">byte</span>[] payloadBytes = Encoding.UTF8.GetBytes(jsonPayload);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建Web请求</span></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest request = <span class="keyword">new</span> UnityWebRequest(apiUrl, <span class="string">&quot;POST&quot;</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            request.uploadHandler = <span class="keyword">new</span> UploadHandlerRaw(payloadBytes);</span><br><span class="line">            request.downloadHandler = <span class="keyword">new</span> DownloadHandlerBuffer();</span><br><span class="line">            request.SetRequestHeader(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;application/json&quot;</span>);</span><br><span class="line">            request.SetRequestHeader(<span class="string">&quot;Authorization&quot;</span>, <span class="string">&quot;Bearer &quot;</span> + apiKey);</span><br><span class="line">            request.disposeDownloadHandlerOnDispose = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 发送请求</span></span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> request.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (request.result == UnityWebRequest.Result.ConnectionError ||</span><br><span class="line">                request.result == UnityWebRequest.Result.ProtocolError)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;API Error: <span class="subst">&#123;request.error&#125;</span>&quot;</span>);</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;Response Code: <span class="subst">&#123;request.responseCode&#125;</span>&quot;</span>);</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;Response: <span class="subst">&#123;request.downloadHandler.text&#125;</span>&quot;</span>);</span><br><span class="line">                answerText.text = <span class="string">$&quot;&lt;color=#FF0000&gt;请求失败: <span class="subst">&#123;request.error&#125;</span>&lt;/color&gt;&quot;</span>;</span><br><span class="line">                isStreaming = <span class="literal">false</span>;</span><br><span class="line">                submitButton.interactable = <span class="literal">true</span>;</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 获取完整响应</span></span><br><span class="line">            <span class="built_in">string</span> rawResponse = request.downloadHandler.text;</span><br><span class="line">            Debug.Log(<span class="string">$&quot;Raw API Response: <span class="subst">&#123;rawResponse&#125;</span>&quot;</span>);</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 处理响应</span></span><br><span class="line">            <span class="keyword">if</span> (<span class="built_in">string</span>.IsNullOrEmpty(rawResponse))</span><br><span class="line">            &#123;</span><br><span class="line">                answerText.text = <span class="string">&quot;&lt;color=#FFA500&gt;服务器返回空响应&lt;/color&gt;&quot;</span>;</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 分割响应行</span></span><br><span class="line">            <span class="built_in">string</span>[] responseLines = rawResponse.Split(<span class="string">&#x27;\n&#x27;</span>);</span><br><span class="line">            <span class="built_in">bool</span> receivedValidResponse = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">foreach</span> (<span class="built_in">string</span> line <span class="keyword">in</span> responseLines)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">if</span> (<span class="built_in">string</span>.IsNullOrWhiteSpace(line)) <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">                <span class="built_in">string</span> trimmedLine = line.Trim();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// 检查结束标记</span></span><br><span class="line">                <span class="keyword">if</span> (trimmedLine == <span class="string">&quot;[DONE]&quot;</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    Debug.Log(<span class="string">&quot;Received [DONE] marker&quot;</span>);</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// 处理SSE格式 (data: &#123;...&#125;)</span></span><br><span class="line">                <span class="built_in">string</span> jsonStr = trimmedLine;</span><br><span class="line">                <span class="keyword">if</span> (trimmedLine.StartsWith(<span class="string">&quot;data:&quot;</span>))</span><br><span class="line">                &#123;</span><br><span class="line">                    jsonStr = trimmedLine.Substring(<span class="number">5</span>).Trim();</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// 跳过事件标记</span></span><br><span class="line">                <span class="keyword">if</span> (jsonStr == <span class="string">&quot;event:message&quot;</span>) <span class="keyword">continue</span>;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">try</span></span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="comment">// 反转义处理</span></span><br><span class="line">                    <span class="built_in">string</span> unescapedStr = jsonStr</span><br><span class="line">                        .Replace(<span class="string">&quot;\\\&quot;&quot;</span>, <span class="string">&quot;\&quot;&quot;</span>)</span><br><span class="line">                        .Replace(<span class="string">&quot;\\\\&quot;</span>, <span class="string">&quot;\\&quot;</span>)</span><br><span class="line">                        .Replace(<span class="string">&quot;\\n&quot;</span>, <span class="string">&quot;\n&quot;</span>)</span><br><span class="line">                        .Replace(<span class="string">&quot;\\r&quot;</span>, <span class="string">&quot;\r&quot;</span>)</span><br><span class="line">                        .Replace(<span class="string">&quot;\\t&quot;</span>, <span class="string">&quot;\t&quot;</span>);</span><br><span class="line"></span><br><span class="line">                    <span class="comment">// 移除多余的双引号</span></span><br><span class="line">                    <span class="keyword">if</span> (unescapedStr.StartsWith(<span class="string">&quot;\&quot;&quot;</span>) &amp;&amp; unescapedStr.EndsWith(<span class="string">&quot;\&quot;&quot;</span>))</span><br><span class="line">                    &#123;</span><br><span class="line">                        unescapedStr = unescapedStr.Substring(<span class="number">1</span>, unescapedStr.Length - <span class="number">2</span>);</span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    <span class="comment">// 调试输出</span></span><br><span class="line">                    Debug.Log(<span class="string">$&quot;Processing line: <span class="subst">&#123;unescapedStr&#125;</span>&quot;</span>);</span><br><span class="line"></span><br><span class="line">                    <span class="comment">// 解析JSON</span></span><br><span class="line">                    <span class="keyword">var</span> response = JsonUtility.FromJson&lt;StreamResponse&gt;(unescapedStr);</span><br><span class="line"></span><br><span class="line">                    <span class="comment">// 提取内容</span></span><br><span class="line">                    <span class="keyword">if</span> (response.choices != <span class="literal">null</span> &amp;&amp; response.choices.Length &gt; <span class="number">0</span>)</span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="keyword">if</span> (response.choices[<span class="number">0</span>].delta != <span class="literal">null</span> &amp;&amp;</span><br><span class="line">                            !<span class="built_in">string</span>.IsNullOrEmpty(response.choices[<span class="number">0</span>].delta.content))</span><br><span class="line">                        &#123;</span><br><span class="line">                            <span class="built_in">string</span> content = response.choices[<span class="number">0</span>].delta.content;</span><br><span class="line">                            fullResponse.Append(content);</span><br><span class="line">                            answerText.text = fullResponse.ToString();</span><br><span class="line">                            receivedValidResponse = <span class="literal">true</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">catch</span> (Exception e)</span><br><span class="line">                &#123;</span><br><span class="line">                    Debug.LogWarning(<span class="string">$&quot;解析错误: <span class="subst">&#123;e.Message&#125;</span>\n原始数据: <span class="subst">&#123;jsonStr&#125;</span>&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">return</span> <span class="literal">null</span>; <span class="comment">// 确保UI更新</span></span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 完成处理</span></span><br><span class="line">            isStreaming = <span class="literal">false</span>;</span><br><span class="line">            submitButton.interactable = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 文本转语音 —————————</span></span><br><span class="line">            <span class="comment">// 校验是否打开自动语音合成 —————————————————————————————————</span></span><br><span class="line">            <span class="keyword">if</span> (ttsToggle.isOn) UITTSController.Instance.OnConvertClick();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (!receivedValidResponse)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="comment">// 尝试提取错误信息</span></span><br><span class="line">                <span class="keyword">if</span> (rawResponse.Contains(<span class="string">&quot;error&quot;</span>))</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">try</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="keyword">var</span> errorResponse = JsonUtility.FromJson&lt;ErrorResponse&gt;(rawResponse);</span><br><span class="line">                        answerText.text = <span class="string">$&quot;&lt;color=#FF0000&gt;API错误: <span class="subst">&#123;errorResponse.error.message&#125;</span>&lt;/color&gt;&quot;</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">catch</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        answerText.text = <span class="string">$&quot;&lt;color=#FF0000&gt;未知API错误: <span class="subst">&#123;rawResponse&#125;</span>&lt;/color&gt;&quot;</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span> <span class="keyword">if</span> (fullResponse.Length &gt; <span class="number">0</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    answerText.text = fullResponse.ToString();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span></span><br><span class="line">                &#123;</span><br><span class="line">                    answerText.text = <span class="string">$&quot;&lt;color=#FFA500&gt;未收到有效响应，原始数据:\n<span class="subst">&#123;rawResponse&#125;</span>&lt;/color&gt;&quot;</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 请求数据结构</span></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">RequestData</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> List&lt;Message&gt; messages;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">bool</span> stream;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">Message</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> role;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 响应数据结构</span></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">StreamResponse</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> id;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> @object;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> created;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> model;</span><br><span class="line">        <span class="keyword">public</span> Choice[] choices;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">Choice</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> index;</span><br><span class="line">        <span class="keyword">public</span> Delta delta;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">object</span> logprobs;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> finish_reason;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">Delta</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 错误响应结构</span></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">ErrorResponse</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> ErrorInfo error;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">ErrorInfo</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> message;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> type;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> code;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="TTS语音合成模块">TTS语音合成模块</h2><h3 id="AudioManager-cs">AudioManager.cs</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System.Collections;</span><br><span class="line"><span class="keyword">using</span> UnityEngine;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.Networking;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">AudioManager</span> : <span class="title">MonoBehaviour</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">private</span> AudioSource audioSource;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Awake</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        audioSource = gameObject.AddComponent&lt;AudioSource&gt;();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> IEnumerator <span class="title">DownloadAndPlayAudio</span>(<span class="params"><span class="built_in">string</span> url</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        Debug.Log(<span class="string">$&quot;开始下载音频: <span class="subst">&#123;url&#125;</span>&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 强制指定MIME类型</span></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.MPEG))</span><br><span class="line">        &#123;</span><br><span class="line">            ((DownloadHandlerAudioClip)www.downloadHandler).streamAudio = <span class="literal">true</span>;</span><br><span class="line">            ((DownloadHandlerAudioClip)www.downloadHandler).compressed = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 添加超时控制</span></span><br><span class="line">            www.timeout = <span class="number">15</span>;</span><br><span class="line">            <span class="keyword">var</span> operation = www.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">while</span> (!operation.isDone)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.Log(<span class="string">$&quot;下载进度: <span class="subst">&#123;www.downloadProgress:P&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (www.result != UnityWebRequest.Result.Success)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;下载失败: <span class="subst">&#123;www.error&#125;</span>，响应头: <span class="subst">&#123;www.GetResponseHeaders()&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            Debug.Log(<span class="string">$&quot;音频下载完成，长度: <span class="subst">&#123;www.downloadedBytes&#125;</span> bytes&quot;</span>);</span><br><span class="line">            AudioClip clip = DownloadHandlerAudioClip.GetContent(www);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (clip == <span class="literal">null</span> || clip.length == <span class="number">0</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">&quot;音频解码失败&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            audioSource.clip = clip;</span><br><span class="line">            audioSource.Play();</span><br><span class="line">            Debug.Log(<span class="string">&quot;音频开始播放&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.MPEG))</span><br><span class="line">        &#123;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> www.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (www.result != UnityWebRequest.Result.Success)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;音频下载失败: <span class="subst">&#123;www.error&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            AudioClip clip = DownloadHandlerAudioClip.GetContent(www);</span><br><span class="line">            audioSource.clip = clip;</span><br><span class="line">            audioSource.Play();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">TogglePause</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (audioSource.isPlaying)</span><br><span class="line">        &#123;</span><br><span class="line">            audioSource.Pause();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            audioSource.UnPause();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">StopPlayback</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        audioSource.Stop();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="built_in">bool</span> <span class="title">IsPlaying</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> audioSource.isPlaying;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="built_in">float</span> <span class="title">GetPlaybackProgress</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (audioSource.clip == <span class="literal">null</span> || Mathf.Approximately(audioSource.clip.length, <span class="number">0f</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0f</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> Mathf.Clamp01(audioSource.time / audioSource.clip.length);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="BaiduTTSController-cs">BaiduTTSController.cs</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System.Collections;</span><br><span class="line"><span class="keyword">using</span> UnityEngine;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.Networking;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">BaiduTTSController</span> : <span class="title">MonoBehaviour</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">// 在百度云控制台获取的实际凭证</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">const</span> <span class="built_in">string</span> CLIENT_ID = <span class="string">&quot;ID&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">const</span> <span class="built_in">string</span> CLIENT_SECRET = <span class="string">&quot;密钥&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">string</span> accessToken = <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 异步获取Access Token</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> IEnumerator <span class="title">GetAccessToken</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">string</span> url = <span class="string">$&quot;百度智能云链接client_id=<span class="subst">&#123;CLIENT_ID&#125;</span>&amp;client_secret=<span class="subst">&#123;CLIENT_SECRET&#125;</span>&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest www = UnityWebRequest.Get(url))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> www.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (www.result != UnityWebRequest.Result.Success)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;Token请求失败: <span class="subst">&#123;www.error&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            TokenResponse response = JsonUtility.FromJson&lt;TokenResponse&gt;(www.downloadHandler.text);</span><br><span class="line">            accessToken = response.access_token;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 创建语音合成任务</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> IEnumerator <span class="title">CreateTTSTask</span>(<span class="params"><span class="built_in">string</span> text, System.Action&lt;<span class="built_in">string</span>&gt; callback</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">string</span> apiUrl = <span class="string">$&quot;接口链接access_token=<span class="subst">&#123;accessToken&#125;</span>&quot;</span>;</span><br><span class="line"></span><br><span class="line">        CreateTaskRequest requestData = <span class="keyword">new</span> CreateTaskRequest</span><br><span class="line">        &#123;</span><br><span class="line">            text = text,</span><br><span class="line">            format = <span class="string">&quot;mp3-16k&quot;</span>,</span><br><span class="line">            voice = <span class="number">0</span>,</span><br><span class="line">            lang = <span class="string">&quot;zh&quot;</span>,</span><br><span class="line">            speed = <span class="number">5</span>,</span><br><span class="line">            pitch = <span class="number">5</span>,</span><br><span class="line">            volume = <span class="number">5</span></span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest www = <span class="keyword">new</span> UnityWebRequest(apiUrl, <span class="string">&quot;POST&quot;</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">byte</span>[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));</span><br><span class="line">            www.uploadHandler = <span class="keyword">new</span> UploadHandlerRaw(bodyRaw);</span><br><span class="line">            www.downloadHandler = <span class="keyword">new</span> DownloadHandlerBuffer();</span><br><span class="line">            www.SetRequestHeader(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;application/json&quot;</span>);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> www.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (www.result != UnityWebRequest.Result.Success)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;任务创建失败: <span class="subst">&#123;www.error&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            TaskCreateResponse response = JsonUtility.FromJson&lt;TaskCreateResponse&gt;(www.downloadHandler.text);</span><br><span class="line">            callback?.Invoke(response.task_id);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 查询任务状态</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> IEnumerator <span class="title">QueryTaskStatus</span>(<span class="params"><span class="built_in">string</span> taskId, System.Action&lt;<span class="built_in">string</span>&gt; callback</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">string</span> apiUrl = <span class="string">$&quot;接口链接access_token=<span class="subst">&#123;accessToken&#125;</span>&quot;</span>;</span><br><span class="line"></span><br><span class="line">        QueryTaskRequest requestData = <span class="keyword">new</span> QueryTaskRequest</span><br><span class="line">        &#123;</span><br><span class="line">            task_ids = <span class="keyword">new</span> <span class="built_in">string</span>[] &#123; taskId &#125;</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">using</span> (UnityWebRequest www = <span class="keyword">new</span> UnityWebRequest(apiUrl, <span class="string">&quot;POST&quot;</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">byte</span>[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(JsonUtility.ToJson(requestData));</span><br><span class="line">            www.uploadHandler = <span class="keyword">new</span> UploadHandlerRaw(bodyRaw);</span><br><span class="line">            www.downloadHandler = <span class="keyword">new</span> DownloadHandlerBuffer();</span><br><span class="line">            www.SetRequestHeader(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;application/json&quot;</span>);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> www.SendWebRequest();</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (www.result != UnityWebRequest.Result.Success)</span><br><span class="line">            &#123;</span><br><span class="line">                Debug.LogError(<span class="string">$&quot;状态查询失败: <span class="subst">&#123;www.error&#125;</span>&quot;</span>);</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            TaskQueryResponse response = JsonUtility.FromJson&lt;TaskQueryResponse&gt;(www.downloadHandler.text);</span><br><span class="line">            <span class="keyword">if</span> (response.tasks_info.Length &gt; <span class="number">0</span> &amp;&amp; response.tasks_info[<span class="number">0</span>].task_status == <span class="string">&quot;Success&quot;</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                callback?.Invoke(response.tasks_info[<span class="number">0</span>].task_result.speech_url);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (response.tasks_info.Length &gt; <span class="number">0</span> &amp;&amp; response.tasks_info[<span class="number">0</span>].task_status == <span class="string">&quot;Success&quot;</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="built_in">string</span> audioUrl = response.tasks_info[<span class="number">0</span>].task_result.speech_url;</span><br><span class="line"></span><br><span class="line">                Debug.Log(<span class="string">$&quot;获取音频地址: <span class="subst">&#123;audioUrl&#125;</span>&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">                <span class="comment">// 添加URL预验证</span></span><br><span class="line">                <span class="keyword">using</span> (UnityWebRequest headRequest = UnityWebRequest.Head(audioUrl))</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">yield</span> <span class="keyword">return</span> headRequest.SendWebRequest();</span><br><span class="line">                    <span class="keyword">if</span> (headRequest.result == UnityWebRequest.Result.Success)</span><br><span class="line">                    &#123;</span><br><span class="line">                        callback?.Invoke(audioUrl);</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        Debug.LogError(<span class="string">$&quot;音频地址不可用: <span class="subst">&#123;headRequest.error&#125;</span>&quot;</span>);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 数据模型</span></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">TokenResponse</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> access_token;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">CreateTaskRequest</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> text;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> format;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> voice;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> lang;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> speed;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> pitch;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">int</span> volume;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">TaskCreateResponse</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> task_id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">QueryTaskRequest</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span>[] task_ids;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">TaskQueryResponse</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> TaskInfo[] tasks_info;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">TaskInfo</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> task_status;</span><br><span class="line">        <span class="keyword">public</span> TaskResult task_result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">System.Serializable</span>]</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title">TaskResult</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="built_in">string</span> speech_url;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="UITTSController-cs">UITTSController.cs</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System.Collections;</span><br><span class="line"><span class="keyword">using</span> TMPro;</span><br><span class="line"><span class="keyword">using</span> UnityEngine;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.UI;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">UITTSController</span> : <span class="title">MonoBehaviour</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> UITTSController Instance &#123; <span class="keyword">get</span>; <span class="keyword">private</span> <span class="keyword">set</span>; &#125;</span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Awake</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (Instance != <span class="literal">null</span> &amp;&amp; Instance != <span class="keyword">this</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            Destroy(gameObject);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        Instance = <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    [<span class="meta">Header(<span class="string">&quot;UI Components&quot;</span>)</span>]</span><br><span class="line">    <span class="keyword">public</span> Text inputField;</span><br><span class="line">    <span class="keyword">public</span> Button convertButton;</span><br><span class="line">    <span class="keyword">public</span> Text statusText;</span><br><span class="line">    <span class="keyword">public</span> Slider progressSlider;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> BaiduTTSController ttsController;</span><br><span class="line">    <span class="keyword">private</span> AudioManager audioManager;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Start</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        ttsController = gameObject.AddComponent&lt;BaiduTTSController&gt;();</span><br><span class="line">        audioManager = gameObject.AddComponent&lt;AudioManager&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//判断网络状态</span></span><br><span class="line">        <span class="keyword">if</span>(Application.internetReachability != NetworkReachability.NotReachable)&#123;</span><br><span class="line">            StartCoroutine(InitializeSystem());</span><br><span class="line">            <span class="comment">// 按钮事件绑定</span></span><br><span class="line">            convertButton.onClick.AddListener(OnConvertClick);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            statusText.text = <span class="string">&quot;网络连接失败&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">InitializeSystem</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        statusText.text = <span class="string">&quot;正在初始化&quot;</span>;</span><br><span class="line">        <span class="keyword">yield</span> <span class="keyword">return</span> ttsController.GetAccessToken();</span><br><span class="line">        statusText.text = <span class="string">&quot;朗读语音就绪&quot;</span>;</span><br><span class="line">        convertButton.interactable = <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">OnConvertClick</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">string</span>.IsNullOrEmpty(inputField.text)) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">        StartCoroutine(ConvertProcess());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">ConvertProcess</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        convertButton.interactable = <span class="literal">false</span>;</span><br><span class="line">        statusText.text = <span class="string">&quot;正在生成语音&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建任务</span></span><br><span class="line">        <span class="keyword">yield</span> <span class="keyword">return</span> ttsController.CreateTTSTask(inputField.text, (taskId) =&gt; &#123;</span><br><span class="line">            StartCoroutine(PollTaskStatus(taskId));</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">PollTaskStatus</span>(<span class="params"><span class="built_in">string</span> taskId</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">float</span> timeout = <span class="number">30f</span>;</span><br><span class="line">        <span class="built_in">float</span> pollInterval = <span class="number">1f</span>;</span><br><span class="line">        <span class="built_in">bool</span> isCompleted = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (timeout &gt; <span class="number">0</span> &amp;&amp; !isCompleted)</span><br><span class="line">        &#123;</span><br><span class="line">            statusText.text = <span class="string">$&quot;处理中...<span class="subst">&#123;timeout&#125;</span>秒&quot;</span>;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 使用Coroutine等待单次查询完成</span></span><br><span class="line">            <span class="function"><span class="keyword">yield</span> <span class="keyword">return</span> <span class="title">StartCoroutine</span>(<span class="params">ttsController.QueryTaskStatus(taskId, (audioUrl</span>)</span> =&gt; &#123;</span><br><span class="line">                StartCoroutine(PlayAudio(audioUrl));</span><br><span class="line">                isCompleted = <span class="literal">true</span>;</span><br><span class="line">            &#125;));</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (isCompleted) <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">            <span class="function"><span class="keyword">yield</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title">WaitForSeconds</span>(<span class="params">pollInterval</span>)</span>;</span><br><span class="line">            timeout -= pollInterval;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!isCompleted)</span><br><span class="line">        &#123;</span><br><span class="line">            statusText.text = <span class="string">&quot;请求超时&quot;</span>;</span><br><span class="line">            Debug.LogError(<span class="string">&quot;状态轮询超时，最后响应数据：&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        convertButton.interactable = <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">PlayAudio</span>(<span class="params"><span class="built_in">string</span> url</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        statusText.text = <span class="string">&quot;正在转载...&quot;</span>;</span><br><span class="line">        <span class="keyword">yield</span> <span class="keyword">return</span> audioManager.DownloadAndPlayAudio(url);</span><br><span class="line"></span><br><span class="line">        statusText.text = <span class="string">&quot;播放中&quot;</span>;</span><br><span class="line">        convertButton.interactable = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 更新进度条</span></span><br><span class="line">        <span class="keyword">while</span> (audioManager.IsPlaying())</span><br><span class="line">        &#123;</span><br><span class="line">            progressSlider.<span class="keyword">value</span> = audioManager.GetPlaybackProgress();</span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="Vosk语音识别模块">Vosk语音识别模块</h2><h3 id="VoskSpeechRecognizer-cs">VoskSpeechRecognizer.cs</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> UnityEngine;</span><br><span class="line"><span class="keyword">using</span> UnityEngine.UI;</span><br><span class="line"><span class="keyword">using</span> System.Threading;</span><br><span class="line"><span class="keyword">using</span> System.Collections.Concurrent;</span><br><span class="line"><span class="keyword">using</span> System.Collections;</span><br><span class="line"><span class="keyword">using</span> Vosk;</span><br><span class="line"><span class="keyword">using</span> Newtonsoft.Json.Linq;</span><br><span class="line"><span class="keyword">using</span> TMPro;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">VoskSpeechRecognizer</span> : <span class="title">MonoBehaviour</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">public</span> Button toggleButton;</span><br><span class="line">    <span class="keyword">public</span> Text resultText;</span><br><span class="line">    <span class="keyword">public</span> TMP_InputField outputText;</span><br><span class="line">    <span class="keyword">public</span> <span class="built_in">string</span> modelPath = Application.streamingAssetsPath + <span class="string">&quot;/Assets/vosk-model-small-cn-0.22&quot;</span>; <span class="comment">// 替换为你的模型路径</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> VoskRecognizer recognizer;</span><br><span class="line">    <span class="keyword">private</span> AudioClip recordingClip;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">bool</span> isRecording;</span><br><span class="line">    <span class="keyword">private</span> Thread recognitionThread;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">int</span> sampleRate = <span class="number">16000</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 主线程安全的变量</span></span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">string</span> displayText = <span class="string">&quot;语音识别就绪&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">string</span> threadStatus = <span class="string">&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">string</span> partialResult = <span class="string">&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">string</span> finalResult = <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> ConcurrentQueue&lt;<span class="built_in">float</span>[]&gt; audioDataQueue = <span class="keyword">new</span> ConcurrentQueue&lt;<span class="built_in">float</span>[]&gt;();</span><br><span class="line">    <span class="keyword">private</span> ConcurrentQueue&lt;<span class="built_in">string</span>&gt; statusQueue = <span class="keyword">new</span> ConcurrentQueue&lt;<span class="built_in">string</span>&gt;();</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">int</span> lastPosition = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">bool</span> modelInitialized = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Start</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        displayText = <span class="string">&quot;初始化中...&quot;</span>;</span><br><span class="line">        resultText.text = displayText;</span><br><span class="line">        StartCoroutine(InitializeModel());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">IEnumerator <span class="title">InitializeModel</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">try</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 初始化Vosk环境</span></span><br><span class="line">            Vosk.Vosk.SetLogLevel(<span class="number">0</span>);</span><br><span class="line">            Model model = <span class="keyword">new</span> Model(modelPath);</span><br><span class="line">            recognizer = <span class="keyword">new</span> VoskRecognizer(model, sampleRate);</span><br><span class="line">            modelInitialized = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">            displayText = <span class="string">&quot;就绪，点击按钮开始识别&quot;</span>;</span><br><span class="line">            toggleButton.interactable = <span class="literal">true</span>;</span><br><span class="line">            toggleButton.onClick.AddListener(ToggleRecording);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span> (System.Exception e)</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = <span class="string">$&quot;初始化失败: <span class="subst">&#123;e.Message&#125;</span>&quot;</span>;</span><br><span class="line">            Debug.LogError(e);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">yield</span> <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Update</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 1. 在主线程收集音频数据</span></span><br><span class="line">        <span class="keyword">if</span> (isRecording &amp;&amp; Microphone.IsRecording(<span class="literal">null</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">int</span> currentPosition = Microphone.GetPosition(<span class="literal">null</span>);</span><br><span class="line">            <span class="keyword">if</span> (currentPosition &lt; lastPosition)</span><br><span class="line">            &#123;</span><br><span class="line">                statusQueue.Enqueue(<span class="string">&quot;检测到音频缓冲区循环&quot;</span>);</span><br><span class="line">                lastPosition = <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (currentPosition &gt; lastPosition)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="built_in">int</span> sampleCount = currentPosition - lastPosition;</span><br><span class="line">                <span class="built_in">float</span>[] samples = <span class="keyword">new</span> <span class="built_in">float</span>[sampleCount];</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (recordingClip != <span class="literal">null</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    recordingClip.GetData(samples, lastPosition);</span><br><span class="line">                    audioDataQueue.Enqueue(samples);</span><br><span class="line">                    lastPosition = currentPosition;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span></span><br><span class="line">                &#123;</span><br><span class="line">                    statusQueue.Enqueue(<span class="string">&quot;错误：录音Clip为空&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 2. 处理来自后台线程的状态更新</span></span><br><span class="line">        <span class="keyword">while</span> (statusQueue.TryDequeue(<span class="keyword">out</span> <span class="built_in">string</span> status))</span><br><span class="line">        &#123;</span><br><span class="line">            threadStatus = status;</span><br><span class="line">            Debug.Log(status);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 3. 更新显示文本（优先级：最终结果 &gt; 部分结果 &gt; 线程状态 &gt; 默认文本）</span></span><br><span class="line">        <span class="keyword">if</span> (!<span class="built_in">string</span>.IsNullOrEmpty(finalResult))</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = <span class="string">$&quot;最终结果: <span class="subst">&#123;finalResult&#125;</span>&quot;</span>;</span><br><span class="line">            outputText.text = finalResult;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (!<span class="built_in">string</span>.IsNullOrEmpty(partialResult))</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = <span class="string">$&quot;实时识别: <span class="subst">&#123;partialResult&#125;</span>&quot;</span>;</span><br><span class="line">            outputText.text = partialResult;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (!<span class="built_in">string</span>.IsNullOrEmpty(threadStatus))</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = threadStatus;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 4. 更新UI</span></span><br><span class="line">        resultText.text = displayText;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">ToggleRecording</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (!modelInitialized)</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = <span class="string">&quot;模型未初始化完成&quot;</span>;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        isRecording = !isRecording;</span><br><span class="line">        toggleButton.GetComponentInChildren&lt;Text&gt;().text = isRecording ? <span class="string">&quot;停止&quot;</span> : <span class="string">&quot;开始&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (isRecording)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 开始录音</span></span><br><span class="line">            <span class="keyword">try</span></span><br><span class="line">            &#123;</span><br><span class="line">                displayText = <span class="string">&quot;正在启动麦克风...&quot;</span>;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// 重置状态</span></span><br><span class="line">                partialResult = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                finalResult = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                threadStatus = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                audioDataQueue = <span class="keyword">new</span> ConcurrentQueue&lt;<span class="built_in">float</span>[]&gt;();</span><br><span class="line">                lastPosition = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">                recordingClip = Microphone.Start(<span class="literal">null</span>, <span class="literal">true</span>, <span class="number">10</span>, sampleRate);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (recordingClip == <span class="literal">null</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    displayText = <span class="string">&quot;无法创建录音Clip&quot;</span>;</span><br><span class="line">                    isRecording = <span class="literal">false</span>;</span><br><span class="line">                    <span class="keyword">return</span>;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                statusQueue.Enqueue(<span class="string">&quot;音频处理线程启动&quot;</span>);</span><br><span class="line"></span><br><span class="line">                recognitionThread = <span class="keyword">new</span> Thread(ProcessAudio);</span><br><span class="line">                recognitionThread.IsBackground = <span class="literal">true</span>;</span><br><span class="line">                recognitionThread.Start();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">catch</span> (System.Exception e)</span><br><span class="line">            &#123;</span><br><span class="line">                displayText = <span class="string">$&quot;启动录音失败: <span class="subst">&#123;e.Message&#125;</span>&quot;</span>;</span><br><span class="line">                isRecording = <span class="literal">false</span>;</span><br><span class="line">                Debug.LogError(e);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 停止录音</span></span><br><span class="line">            displayText = <span class="string">&quot;正在停止录音...&quot;</span>;</span><br><span class="line">            Microphone.End(<span class="literal">null</span>);</span><br><span class="line">            isRecording = <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (recognitionThread != <span class="literal">null</span> &amp;&amp; recognitionThread.IsAlive)</span><br><span class="line">            &#123;</span><br><span class="line">                recognitionThread.Abort();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (!<span class="built_in">string</span>.IsNullOrEmpty(finalResult))</span><br><span class="line">            &#123;</span><br><span class="line">                displayText = <span class="string">$&quot;最终结果: <span class="subst">&#123;finalResult&#125;</span>&quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                displayText = <span class="string">&quot;识别结束，无结果&quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">ProcessAudio</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        statusQueue.Enqueue(<span class="string">&quot;音频处理线程启动&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (isRecording)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> (audioDataQueue.TryDequeue(<span class="keyword">out</span> <span class="built_in">float</span>[] samples))</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="comment">// 转换为字节数据</span></span><br><span class="line">                <span class="built_in">byte</span>[] audioBytes = <span class="keyword">new</span> <span class="built_in">byte</span>[samples.Length * <span class="number">2</span>];</span><br><span class="line">                <span class="keyword">for</span> (<span class="built_in">int</span> i = <span class="number">0</span>; i &lt; samples.Length; i++)</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="built_in">short</span> sample = (<span class="built_in">short</span>)(samples[i] * <span class="built_in">short</span>.MaxValue);</span><br><span class="line">                    audioBytes[i * <span class="number">2</span>] = (<span class="built_in">byte</span>)(sample &amp; <span class="number">0xFF</span>);</span><br><span class="line">                    audioBytes[i * <span class="number">2</span> + <span class="number">1</span>] = (<span class="built_in">byte</span>)(sample &gt;&gt; <span class="number">8</span>);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">try</span></span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="comment">// 语音识别处理</span></span><br><span class="line">                    <span class="keyword">if</span> (recognizer.AcceptWaveform(audioBytes, audioBytes.Length))</span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="keyword">var</span> result = recognizer.Result();</span><br><span class="line">                        finalResult = JObject.Parse(result)[<span class="string">&quot;text&quot;</span>]?.ToString() ?? <span class="string">&quot;无文本结果&quot;</span>;</span><br><span class="line">                        partialResult = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                        statusQueue.Enqueue(<span class="string">$&quot;最终结果: <span class="subst">&#123;finalResult&#125;</span>&quot;</span>);</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="keyword">var</span> <span class="keyword">partial</span> = recognizer.PartialResult();</span><br><span class="line">                        partialResult = JObject.Parse(<span class="keyword">partial</span>)[<span class="string">&quot;partial&quot;</span>]?.ToString() ?? <span class="string">&quot;解析部分结果失败&quot;</span>;</span><br><span class="line">                        statusQueue.Enqueue(<span class="string">$&quot;部分结果: <span class="subst">&#123;partialResult&#125;</span>&quot;</span>);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">catch</span> (System.Exception e)</span><br><span class="line">                &#123;</span><br><span class="line">                    statusQueue.Enqueue(<span class="string">$&quot;识别错误: <span class="subst">&#123;e.Message&#125;</span>&quot;</span>);</span><br><span class="line">                    Debug.LogError(e);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                Thread.Sleep(<span class="number">10</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">OnApplicationQuit</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        isRecording = <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span> (recognitionThread != <span class="literal">null</span> &amp;&amp; recognitionThread.IsAlive)</span><br><span class="line">        &#123;</span><br><span class="line">            recognitionThread.Abort();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (recognizer != <span class="literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            recognizer.Dispose();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        Debug.Log(<span class="string">&quot;Vosk资源已释放&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 添加移动端麦克风权限检查</span></span><br><span class="line">    <span class="function">IEnumerator <span class="title">RequestMicrophonePermission</span>()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (Application.platform == RuntimePlatform.Android ||</span><br><span class="line">            Application.platform == RuntimePlatform.IPhonePlayer)</span><br><span class="line">        &#123;</span><br><span class="line">            displayText = <span class="string">&quot;请求麦克风权限...&quot;</span>;</span><br><span class="line">            <span class="keyword">yield</span> <span class="keyword">return</span> Application.RequestUserAuthorization(UserAuthorization.Microphone);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (!Application.HasUserAuthorization(UserAuthorization.Microphone))</span><br><span class="line">            &#123;</span><br><span class="line">                displayText = <span class="string">&quot;需要麦克风权限&quot;</span>;</span><br><span class="line">                <span class="keyword">yield</span> <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 继续初始化</span></span><br><span class="line">        StartCoroutine(InitializeModel());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>结语</h1><p>通过以上步骤，我们成功在Unity项目中配置了Vosk离线语音识别环境。Vosk作为一个轻量级、高精度的离线语音识别解决方案，为Unity开发者提供了实现语音交互功能的强大工具。其离线特性特别适合对数据隐私要求高的应用场景，而跨平台支持则使得一次开发即可部署到多种设备。</p><p>正确配置环境只是实现语音识别的第一步，在实际开发中还需要根据具体应用场景调整参数和优化性能。建议从小型模型开始测试，逐步优化识别效果，再根据需求决定是否需要升级到更大规模的模型。</p><p>随着语音交互技术的不断发展，Vosk这样的离线识别方案将在更多应用场景中发挥重要作用，为用户提供更自然、更安全的交互体验。</p><h1>参考资料</h1><ol><li><a href="https://alphacephei.com/vosk/models">Vosk官方模型库</a></li><li><a href="https://github.com/alphacep/vosk-unity-asr">Vosk Unity插件GitHub页面</a></li><li><a href="https://docs.unity3d.com/Manual/Audio.html">Unity音频系统文档</a></li></ol><blockquote><p><strong>注意</strong>：本文仅涉及环境配置部分，实际语音识别功能的实现需要编写C#脚本处理音频输入和调用Vosk接口。请参考Vosk官方文档和示例代码了解具体实现方法。</p></blockquote>]]></content>
    
    
    <summary type="html">借助Vosk和百度智能云接口实现语音实时交流智能助手</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="Unity" scheme="https://home.y1xuanyun.cn/tags/Unity/"/>
    
    <category term="3D" scheme="https://home.y1xuanyun.cn/tags/3D/"/>
    
    <category term="模型" scheme="https://home.y1xuanyun.cn/tags/%E6%A8%A1%E5%9E%8B/"/>
    
    <category term="AiChat" scheme="https://home.y1xuanyun.cn/tags/AiChat/"/>
    
    <category term="聊天" scheme="https://home.y1xuanyun.cn/tags/%E8%81%8A%E5%A4%A9/"/>
    
    <category term="智能" scheme="https://home.y1xuanyun.cn/tags/%E6%99%BA%E8%83%BD/"/>
    
    <category term="API" scheme="https://home.y1xuanyun.cn/tags/API/"/>
    
    <category term="Vosk" scheme="https://home.y1xuanyun.cn/tags/Vosk/"/>
    
  </entry>
  
  <entry>
    <title>算法整理2025新编（C++）</title>
    <link href="https://home.y1xuanyun.cn/posts/25cpp02.html"/>
    <id>https://home.y1xuanyun.cn/posts/25cpp02.html</id>
    <published>2025-04-15T06:00:00.000Z</published>
    <updated>2025-04-25T06:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-blue"  style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><p>该文章长期更新</p></div></div><h1>1. STL</h1><h2 id="1-vector（万能动态数组）">1. vector（万能动态数组）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;<span class="type">int</span>&gt; v;          <span class="comment">// 声明</span></span><br><span class="line">v.<span class="built_in">push_back</span>(<span class="number">3</span>);         <span class="comment">// 尾部插入</span></span><br><span class="line">v.<span class="built_in">pop_back</span>();           <span class="comment">// 尾部删除</span></span><br><span class="line">v.<span class="built_in">size</span>();               <span class="comment">// 元素个数</span></span><br><span class="line">v[<span class="number">0</span>] = <span class="number">5</span>;               <span class="comment">// 随机访问（不检查越界）</span></span><br><span class="line"><span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());<span class="comment">// 排序</span></span><br><span class="line">range::<span class="built_in">sort</span>(v);          <span class="comment">// 排序 C++20新特性</span></span><br></pre></td></tr></table></figure><h2 id="2-string（字符串处理）">2. string（字符串处理）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">string s = <span class="string">&quot;abc&quot;</span>;</span><br><span class="line">s += <span class="string">&quot;def&quot;</span>;             <span class="comment">// 拼接</span></span><br><span class="line">s.<span class="built_in">substr</span>(<span class="number">1</span>, <span class="number">2</span>);         <span class="comment">// 取子串（位置,长度）</span></span><br><span class="line">s.<span class="built_in">find</span>(<span class="string">&quot;cd&quot;</span>);           <span class="comment">// 查找（返回位置）</span></span><br><span class="line"><span class="built_in">stoi</span>(s);                <span class="comment">// 字符串转数字</span></span><br><span class="line">s = <span class="built_in">to_string</span>(<span class="number">123</span>);     <span class="comment">// 数字转字符串</span></span><br></pre></td></tr></table></figure><h2 id="3-priority-queue（优先队列-堆–最小堆）">3. priority_queue（优先队列/堆–最小堆）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">priority_queue&lt;<span class="type">int</span>&gt; pq;  <span class="comment">// 默认大根堆</span></span><br><span class="line">pq.<span class="built_in">push</span>(<span class="number">3</span>);             <span class="comment">// 插入</span></span><br><span class="line">pq.<span class="built_in">top</span>();               <span class="comment">// 取堆顶</span></span><br><span class="line">pq.<span class="built_in">pop</span>();               <span class="comment">// 弹出堆顶</span></span><br><span class="line"><span class="comment">// 小根堆定义</span></span><br><span class="line">priority_queue&lt;<span class="type">int</span>, vector&lt;<span class="type">int</span>&gt;, greater&lt;<span class="type">int</span>&gt;&gt; min_pq;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="4-1-map（红黑树–平衡二叉搜索树）">4.(1). map（红黑树–平衡二叉搜索树）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">map&lt;string, <span class="type">int</span>&gt; mp;</span><br><span class="line">mp[<span class="string">&quot;apple&quot;</span>] = <span class="number">5</span>;        <span class="comment">// 插入/修改</span></span><br><span class="line"><span class="keyword">auto</span> it = mp.<span class="built_in">find</span>(<span class="string">&quot;apple&quot;</span>);  <span class="comment">// 查找（返回迭代器）</span></span><br></pre></td></tr></table></figure><h2 id="4-2-unordered-map（哈希表–数组-链表-红黑树桶）">4.(2). unordered_map（哈希表–数组 + 链表/红黑树桶）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">unordered_map&lt;string, <span class="type">int</span>&gt; mp;</span><br><span class="line">mp[<span class="string">&quot;apple&quot;</span>] = <span class="number">5</span>;        <span class="comment">// 插入/修改</span></span><br><span class="line">mp.<span class="built_in">count</span>(<span class="string">&quot;apple&quot;</span>);      <span class="comment">// 判断是否存在</span></span><br><span class="line">mp.<span class="built_in">erase</span>(<span class="string">&quot;apple&quot;</span>);      <span class="comment">// 删除</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">auto</span> &amp;[k,v] : mp)   <span class="comment">// 遍历（C++17）</span></span><br><span class="line">    cout &lt;&lt; k &lt;&lt; <span class="string">&quot; &quot;</span> &lt;&lt; v;</span><br></pre></td></tr></table></figure><h2 id="5-set（自动排序集合）">5. set（自动排序集合）</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">set&lt;<span class="type">int</span>&gt; s;</span><br><span class="line">s.<span class="built_in">insert</span>(<span class="number">3</span>);            <span class="comment">// 插入</span></span><br><span class="line">s.<span class="built_in">count</span>(<span class="number">3</span>);             <span class="comment">// 是否存在</span></span><br><span class="line">s.<span class="built_in">erase</span>(<span class="number">3</span>);             <span class="comment">// 删除</span></span><br><span class="line"><span class="comment">// 自动排序，可直接用*s.begin()取最小值</span></span><br></pre></td></tr></table></figure><h1>2. 排序</h1><h2 id="最简模板">最简模板</h2><ol><li><strong>二分查找</strong></li></ol><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line"><span class="keyword">auto</span> it = <span class="built_in">lower_bound</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), x);</span><br><span class="line"><span class="keyword">if</span>(it != v.<span class="built_in">end</span>() &amp;&amp; *it == x) <span class="comment">// 找到x</span></span><br></pre></td></tr></table></figure><ol start="2"><li><strong>自定义排序</strong>（贪心常用）</li></ol><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> </span>&#123; <span class="keyword">return</span> a &gt; b; &#125;</span><br><span class="line"><span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), cmp);</span><br></pre></td></tr></table></figure><ol start="3"><li><strong>结构体排序</strong></li></ol><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span> &#123; <span class="type">int</span> x, y; &#125;;</span><br><span class="line">vector&lt;Node&gt; v;</span><br><span class="line"><span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), [](Node a, Node b)&#123;</span><br><span class="line">    <span class="keyword">return</span> a.x == b.x ? a.y &lt; b.y : a.x &gt; b.x;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>💡 优先掌握 <code>vector</code> + <code>sort</code> + <code>priority_queue</code>，其他遇到现查即可！</p><p>在快速的时间下，三种重要的排序，计数排序，快速排序，自定义排序</p><h2 id="计数排序">计数排序</h2><p>计数排序是一种特殊的桶排序。<br>计数排序的工作原理是使用一个额外的数组 C，其中第 i 个元素是待排序数组 A 中值等于 i 的元素的个数，然后根据数组 C 来将 A 中的元素排到正确的位置。<br>它的工作过程分为三个步骤：</p><ol><li>计算每个数出现了几次；</li><li>求出每个数出现次数的前缀和；</li><li>利用出现次数的前缀和，从右至左计算每个数的排名。<br>这样时间复杂度是 $O(max(n,w))$，<code>w</code> 表示排序中最大的那个数。<br>计数排序的时间复杂度小，但空间复杂度极大，当 <code>w</code> 是大于 $10^7$ 时就不建议使用计数排序，会导致空间溢出。</li></ol><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="type">int</span> a[N];</span><br><span class="line"><span class="type">int</span> C[N];<span class="comment">//此时的N要保证比a数组中的任何一个数都要大。</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n;i++)c[a[i]]++;</span><br><span class="line"><span class="type">int</span> t=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;=w;i++)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span>(c[i]&gt;<span class="number">0</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">while</span>(c[i]&gt;<span class="number">0</span>)&#123;</span><br><span class="line">a[++t]=i;</span><br><span class="line">c[i]--;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>时间复杂度 $O(max(n,w))$。</p><h2 id="快速排序">快速排序</h2><h3 id="定义：">定义：</h3><p>快速排序（英语：Quicksort），又称分区交换排序（英语：partition-exchange sort），简称「快排」，是一种被广泛运用的排序算法。</p><h3 id="过程：">过程：</h3><p>快速排序的工作原理是通过分治的方式来将一个数组排序。<br>对于一个数列，我们找到一个<strong>中间位置的值</strong> $x$ ，通过划分区间，比 $x$ 小的放在左边，比 $x$ 大的放在右边。然后在分别递归这两个区间，按照上述做法，直到递归到区间只有 $1$ 个数时，终止递归，再由开始分出来的区间，依次合并，构成的序列就是一个完美的拍好序的数列，完结撒花。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">k_sort</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> mid = a[(x + y) &gt;&gt; <span class="number">1</span>];</span><br><span class="line">    <span class="type">int</span> i = x, j = y;</span><br><span class="line">    <span class="keyword">while</span> (i &lt;= j)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">while</span> (a[i] &lt; mid)</span><br><span class="line">            i++;</span><br><span class="line">        <span class="keyword">while</span> (a[j] &gt; mid)</span><br><span class="line">            j--;</span><br><span class="line">        <span class="keyword">if</span> (i &lt;= j)</span><br><span class="line">        &#123;</span><br><span class="line">            q = a[i], a[i] = a[j], a[j] = q, i++, j--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (x &lt; j)</span><br><span class="line">        <span class="built_in">k_sort</span>(x, j);</span><br><span class="line">    <span class="keyword">if</span> (i &lt; y)</span><br><span class="line">        <span class="built_in">k_sort</span>(i, y);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>时间复杂度分析：<br>在平均情况下，快速排序的时间复杂度是 $O(n \log n)$ 。这是因为每次划分都将数组分成两个大致相等的部分，递归的深度是 $log\ n$（其中  $n$ 是数组的长度），而每一层的划分操作需要 $O(n)$  的时间。</p><p>快排在极端最坏情况下会退化成 $n^2$，当然这种情况很少，如果用到快排做题最好直接使用 <code>sort</code> 函数。</p><p>这边建议如果快排不太懂可以直接使用 <code>sort</code> 函数，很好用，后面的自定义排序也是基于这个函数<s>当然比赛你也可以手搓快排</s>。</p><h2 id="自定义排序">自定义排序</h2><h3 id="自定义排序是排序中最重要的一部分">自定义排序是排序中最重要的一部分</h3><p>自定义排序主要是基于 <code>sort</code> 函数。</p><h3 id="sort函数">sort函数</h3><p>在 <code>sort</code> 函数里不加别的参数时，默认是按权值从小到大排。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sort</span>(a<span class="number">+1</span>,a+n<span class="number">+1</span>);<span class="comment">//表示把数组 a 从 1-n 按从小到大排好序</span></span><br><span class="line"><span class="comment">//两参数：[数组名+初始位置下标,数组名+元素个数+初始位置下标]</span></span><br></pre></td></tr></table></figure><p><code>sort</code> 里面可以加一个函数名用来实习自定义排序</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(<span class="type">int</span> x,<span class="type">int</span> y)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> x&gt;y;<span class="comment">//实现从大到小排序</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//return abs(x-1000)&gt;abs(y-1000);实现f(x) = |x-100| 的排序</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">sort</span>(a<span class="number">+1</span>,a+n<span class="number">+1</span>,cmp);</span><br></pre></td></tr></table></figure><p>同样自定义函数可以是调用一个结构体函数</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">123456</span>;</span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">student</span> &#123;</span><br><span class="line"><span class="type">int</span> score;</span><br><span class="line"><span class="type">int</span> math,chinese,english;</span><br><span class="line">&#125;;</span><br><span class="line">student a[N];</span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(student x,student y)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span>(x.score==y.score)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span>(x.math==y.math)<span class="keyword">return</span> x.chinese&gt;y.chinese;</span><br><span class="line"><span class="keyword">return</span> x.math&gt;y.math;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> x.score&gt;y.score;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">sort</span>(a<span class="number">+1</span>,a+n<span class="number">+1</span>,cmp);</span><br></pre></td></tr></table></figure><p>自定义排序可以很复杂，配合上结构体可以完成很多的操作，很重要。</p><h1>3. 二分</h1><h2 id="定义">定义</h2><p>二分查找（英语：<strong>binary search</strong>），也称折半搜索（英语：<strong>half-interval search</strong>）、对数搜索（英语：<strong>logarithmic search</strong>），是用来在一个有序数组中查找某一元素的算法。</p><h2 id="过程">过程</h2><p>以在一个升序数组中查找一个数为例。</p><p>它每次考察数组当前部分的中间元素，如果中间元素刚好是要找的，就结束搜索过程；如果中间元素小于所查找的值，那么左侧的只会更小，不会有所查找的元素，只需到右侧查找；如果中间元素大于所查找的值同理，只需到左侧查找。</p><h2 id="示例概念">示例概念</h2><p>二分是什么概念呢，举个例子，比如你在心里想一个 $1000$ 以内的正整数，让我猜，我每次猜一个数，你需要回答大了还是小了，这样，我可以做到最多 $10$ 次我就可以猜到这个数字是多少。<br>它的猜数路线是这样的，比如你猜的一个数是 $147$ ，我第一次猜 $500$ ，发现是大了，那么下次我猜的范围就是 $1-499$ ，我再猜 $250$ ，那么下次范围就是 $1-249$ ，再猜 $125$ ，下次范围是 $126-149$ ，再猜 $138$ ，下次范围 $139-149$ ，再猜 $144$ ，下次范围就是 $145-149$ ，再猜 $147$ ，这样就猜中了，只用了 $6$ 次就出结果了。换成 $1000$ 以内的任何数都是这样，都可以保证在 $10$ 次以内猜中。倘若一个个的试探的话，最坏可能会 $1000$ 次才能猜出来结果。这样对比二分的效率就来了，对应到代码上：</p><h2 id="非二分">非二分</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> x;</span><br><span class="line">cin&gt;&gt;x;<span class="comment">//要猜的数</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">1000</span>;i++)</span><br><span class="line"><span class="keyword">if</span>(i==x)</span><br><span class="line">&#123;</span><br><span class="line">cout&lt;&lt;<span class="string">&quot;猜对了&quot;</span>;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="二分">二分</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> x;</span><br><span class="line">cin&gt;&gt;x;<span class="comment">//要猜的数</span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> l=<span class="number">1</span>,r=<span class="number">1000</span>;<span class="comment">//猜数的左右边界</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span>(l&lt;=r)</span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> mid = (l+r)/<span class="number">2</span>;<span class="comment">//每次猜的数是中间值，依次可以对半划分范围</span></span><br><span class="line"><span class="keyword">if</span> (mid==x)&#123;</span><br><span class="line">cout&lt;&lt;<span class="string">&quot;猜对了&quot;</span>;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (mid&gt;x) r=mid<span class="number">-1</span>;<span class="comment">//mid比x大，说明下次猜数要从 [l,mid-1]中选择</span></span><br><span class="line"><span class="keyword">else</span> l=mid<span class="number">+1</span>; <span class="comment">//mid比x小，说明下次猜数要从 [mid+1,r]中选择</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>那么假设我们猜的数范围是 $[1,n]$ ，那么非二分的做法时间复杂度就是 $O(n)$ ，而对于二分做法，每次猜都会缩减一半的范围，一直缩到范围为这个数本身，那么设时间为 $t$ ，那么 ， $2^t=n,t=\log_2(n)$，即时间复杂度为 $O(log(n))$ 。</p><h2 id="如何观察到需要用二分">如何观察到需要用二分</h2><p>观察上个例子，为什么二分可以比一个个查询的速度快，其实就是它舍弃了一些不用查的数据，而且可以保证这部分数据绝对不会在答案中，而如何可以保证我们舍弃的数据绝对不会被查到，所以需要满足<strong>单调性</strong>，对于这个猜数问题它满足的是数据的单调性，还有一种单调性是状态决策的单调性（即答案的单调性），<a href="http://www.djtu.com.cn/problem/P0003">例题：P0003 拍照分组</a>。</p><p>当一个<strong>状态的决策过程或者序列满足单调性</strong>它往往可以考虑使用二分来解决。</p><p>STL 形式：</p><ul><li>lower_bound(a,a+n,x)-a; 表示在 $a$ 数组中找到第一个大于等于 $x$ 数的位置。</li><li>upper_bound(a,a+n,x)-a; 表示在 $a$ 数组中找到第一个大于 $x$ 数的位置。</li></ul><h2 id="参考模版">参考模版</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> l=<span class="number">1</span>;r=n;</span><br><span class="line"><span class="type">int</span> ans;<span class="comment">//个人习惯，ans表示当前答案满足时的最优解</span></span><br><span class="line"><span class="keyword">while</span>(l&lt;=r)</span><br><span class="line">&#123;</span><br><span class="line">   <span class="type">int</span> mid=(l+r)&gt;&gt;<span class="number">1</span>;</span><br><span class="line">   <span class="keyword">if</span>(<span class="built_in">check</span>(mid))</span><br><span class="line">    l=mid<span class="number">+1</span>,ans=mid;</span><br><span class="line">    <span class="keyword">else</span> r=mid<span class="number">-1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>4.1 前缀和</h1><p><strong>定义</strong>：前缀和数组 <code>s[i]</code> 表示从数组开始到第 <code>i</code> 个元素的累加和。</p><h2 id="使用场景：">使用场景：</h2><ul><li>快速计算区间和。</li></ul><h2 id="示例问题：区间和查询">示例问题：区间和查询</h2><p><strong>问题描述</strong>：给定一个数组和若干查询，每次查询给出区间 <code>[l, r]</code>，求该区间的和。</p><h2 id="实现步骤：">实现步骤：</h2><ul><li>预处理前缀和数组。</li><li>对于每次查询，利用公式 <code>sum[l, r] = s[r] - s[l-1]</code> 计算区间和。</li></ul><h2 id="示例代码：">示例代码：</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">10000001</span>;</span><br><span class="line"><span class="type">int</span> a[N];</span><br><span class="line"><span class="type">int</span> s[N];</span><br><span class="line"><span class="type">int</span> n, m, ans;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">        cin &gt;&gt; a[i], s[i] = s[i - <span class="number">1</span>]+a[i];</span><br><span class="line">    <span class="keyword">while</span> (m--)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="type">int</span> x, y;</span><br><span class="line">        cin &gt;&gt; x &gt;&gt; y;</span><br><span class="line">        cout &lt;&lt; s[y] - s[x - <span class="number">1</span>] &lt;&lt; <span class="string">&quot;\n&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><hr><h1>4.2 差分</h1><p><strong>定义</strong>：差分数组 <code>d[i]</code> 表示原数组相邻两项的差值。</p><h2 id="使用场景：-2">使用场景：</h2><ul><li>修改区间值时避免暴力遍历。</li></ul><h2 id="示例问题：区间加法">示例问题：区间加法</h2><p><strong>问题描述</strong>：给定一个数组和若干操作，每次操作对区间 <code>[l, r]</code> 的每个元素加上一个值 <code>k</code>。</p><h2 id="实现步骤：-2">实现步骤：</h2><ul><li>初始化差分数组。</li><li>对每次操作，在差分数组中修改对应位置。</li><li>根据差分数组还原原数组。</li></ul><h2 id="示例代码：-2">示例代码：</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">101001</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, m, ans;</span><br><span class="line"><span class="type">int</span> a[N], d[N],q[N];</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">        cin &gt;&gt; a[i];</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">        d[i] = a[i] - a[i - <span class="number">1</span>];</span><br><span class="line">    <span class="keyword">while</span> (m--)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="type">int</span> l, r, c;</span><br><span class="line">        cin &gt;&gt; l &gt;&gt; r &gt;&gt; c;</span><br><span class="line">        d[l] += c;     <span class="comment">// 给l端点的差分值+c</span></span><br><span class="line">        d[r + <span class="number">1</span>] -= c; <span class="comment">// 给r+1端点的差分值-c</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">        q[i] = q[i - <span class="number">1</span>] + d[i];</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        cout &lt;&lt; q[i] &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>前缀和和差分主要用于思想优化和一些别的算法结合到一起。</p><h1>5.数学</h1><h2 id="筛质数">筛质数</h2><h3 id="埃氏筛素数">埃氏筛素数</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;<span class="type">int</span>&gt;p;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">2</span>; i &lt;= N; i++)</span><br><span class="line">        <span class="keyword">if</span> (!a[i])</span><br><span class="line">        &#123;</span><br><span class="line">        p.<span class="built_in">push_back</span>(i);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = i+i; j &lt;= N; j += i)</span><br><span class="line">                a[j] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure><h3 id="线性筛">线性筛</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">get_primes</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">2</span>;i&lt;=n;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(!st[i])primes[++cnt]=i;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">1</span>;primes[j]&lt;=n/i;j++)<span class="comment">//保证每个数只会被最小质因子筛掉</span></span><br><span class="line">        &#123;</span><br><span class="line">            st[primes[j]*i]=<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span>(i%primes[j]==<span class="number">0</span>)<span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>而为什么线性筛的复杂度是O(n)，埃氏筛是O(nloglogn)，是因为线性筛中每个数只可能被筛掉一次。<br>因为一个数是被其最小质因子筛掉，那么就算一个数存在两个及以上的质因子，只要最小的把这个数筛过，那么就不会用其他的质因子筛掉这个数。<br>如 ：21<br>埃氏筛会被3和7分别筛掉，想当于21被筛了两次<br>而线性筛只会被筛掉一次，因为质数是从小到大开始枚举，一旦出现i%primes[j]就会退出循环，根本枚举不到更大的质因子。</p><h2 id="分解质因数">分解质因数</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">divide</span><span class="params">(<span class="type">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">2</span>;i&lt;=x/i;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(x%i==<span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="type">int</span> s=<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">while</span>(x%i==<span class="number">0</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                x/=i;</span><br><span class="line">                s++;</span><br><span class="line">            &#125;</span><br><span class="line">            cout&lt;&lt;i&lt;&lt;<span class="string">&quot; &quot;</span>&lt;&lt;s&lt;&lt;<span class="string">&quot;\n&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(x&gt;<span class="number">1</span>) cout&lt;&lt;x&lt;&lt;<span class="string">&quot; &quot;</span>&lt;&lt;<span class="number">1</span>&lt;&lt;<span class="string">&quot;\n&quot;</span>;</span><br><span class="line">    cout&lt;&lt;<span class="string">&quot;\n&quot;</span>;</span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="快速幂">快速幂</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1001</span>;</span><br><span class="line"><span class="type">int</span> a, b, p;</span><br><span class="line"><span class="type">int</span> n, m, ans;</span><br><span class="line"><span class="type">int</span> t;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">qmi</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> res = <span class="number">1</span> % p;</span><br><span class="line">    <span class="keyword">while</span> (b)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (b &amp; <span class="number">1</span>)</span><br><span class="line">            res = res * a % p;</span><br><span class="line">        a = a * a % p;</span><br><span class="line">        b /= <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; res &lt;&lt; <span class="string">&quot;\n&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    <span class="keyword">while</span> (t--)</span><br><span class="line">    &#123;</span><br><span class="line">        cin &gt;&gt; a &gt;&gt; b &gt;&gt; p;</span><br><span class="line">        <span class="built_in">qmi</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="为什么需要用到逆元？">为什么需要用到逆元？</h3><p>{<br>因为要求$(a/b)\quad mod\quad p$ ，由于涉及到了除法，就需要把除法转化为乘法，那么$a \times b^{-1} \quad mod \quad p$ ，但是这里的$b^{-1}$ 并不是指倒数，只要满足 $b \times x \equiv 1 (mod\quad p)$ 即可，那么 $x$ 就是 $b$ 的逆元即 $x\equiv b^{-1}(mod \quad p)$ ，有费马小定理可得，$b$ 的逆元为 $b^{p-2}$ 。<br>}<br>求逆元：$x=m/gcd(m,b)$<br>费马定理：$b^{p-1}=1(mod\quad p)$</p><h2 id="组合数学">组合数学</h2><h2 id="朴素法求组合数：-O-n-2">朴素法求组合数：$O(n^2)$</h2><p>适用范围：<br>1 \leq n \leq 10000 ,<br>1 \leq a,b \leq 20000</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">2010</span>,mod=<span class="number">1e9</span><span class="number">+7</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> c[N][N];<span class="comment">//将所有的组合方式都预处理出来</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;=<span class="number">2000</span>;i++)</span><br><span class="line">     <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j&lt;=i;j++)</span><br><span class="line">      <span class="keyword">if</span>(!j) c[i][j]=<span class="number">1</span>;</span><br><span class="line">      <span class="keyword">else</span> c[i][j]=(c[i<span class="number">-1</span>][j]+c[i<span class="number">-1</span>][j<span class="number">-1</span>])%mod;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>,&amp;n);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">init</span>();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(n--)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="type">int</span> a,b;</span><br><span class="line">        <span class="built_in">scanf</span>(<span class="string">&quot;%d%d&quot;</span>,&amp;a,&amp;b);</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;%d\n&quot;</span>,c[a][b]);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="快速幂求组合数-O-nlogn">快速幂求组合数: $O(nlogn)$</h2><p>适用范围：<br>$$<br>1 \leq n \leq 10000 ,<br>1 \leq a,b \leq 10^5<br>$$</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">101001</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> LL;</span><br><span class="line"><span class="type">int</span> n, m, ans;</span><br><span class="line"><span class="type">int</span> fact[N], infact[N];</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> mod = <span class="number">1e9</span> + <span class="number">7</span>;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">qmi</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> res = <span class="number">1</span> % mod;</span><br><span class="line">    <span class="keyword">while</span> (b)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (b &amp; <span class="number">1</span>)</span><br><span class="line">            res = (LL)res * a % mod;</span><br><span class="line">        a = (LL)a * a % mod;</span><br><span class="line">        b /= <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    fact[<span class="number">0</span>] = infact[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; N; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        fact[i] = (LL)fact[i - <span class="number">1</span>] * i % mod;<span class="comment">//分子的阶乘</span></span><br><span class="line">        infact[i] = (LL)infact[i - <span class="number">1</span>] * <span class="built_in">qmi</span>(i, mod - <span class="number">2</span>) % mod;<span class="comment">//逆元的阶乘</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*求逆元优化成线性</span></span><br><span class="line"><span class="comment">    infact[N - 1] = qmi(fact[N - 1], mod - 2);</span></span><br><span class="line"><span class="comment">    for (int i = N - 2; i &gt;= 1; i--)</span></span><br><span class="line"><span class="comment">    &#123;</span></span><br><span class="line"><span class="comment">        infact[i] = (LL)infact[i + 1] * (i + 1) % mod; // 分母的阶乘</span></span><br><span class="line"><span class="comment">    &#125;*/</span></span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="keyword">while</span> (n--)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="type">int</span> a, b;</span><br><span class="line">        cin &gt;&gt; a &gt;&gt; b;</span><br><span class="line">        cout &lt;&lt; (LL)fact[a] * infact[b] % mod * infact[a - b] % mod &lt;&lt; <span class="string">&quot;\n&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>6.1 并查集</h1><h2 id="1-概述">1. <strong>概述</strong></h2><p>并查集（Union-Find），也称为不相交集（Disjoint Set Union，DSU），是一种数据结构，主要用于处理集合的合并（union）与查询（find）操作。它支持高效地处理某些动态连通性问题，例如判断两个元素是否在同一集合中，或者将两个元素合并到一个集合中。</p><p>并查集常用于处理图论中的连通性问题、网络中元素的关系查询等问题。它通常用于图的最小生成树（MST）算法（如 Kruskal 算法），网络连接问题等。</p><h2 id="2-基本操作">2. <strong>基本操作</strong></h2><p>并查集支持以下基本操作：</p><ul><li><strong>Find</strong>：查找某个元素所在的集合。通常通过查找元素的“父节点”来实现。</li><li><strong>Union</strong>：将两个元素所在的集合合并为一个集合。</li></ul><p>这些操作通常都要求在尽可能短的时间内完成。</p><h2 id="3-数据结构">3. <strong>数据结构</strong></h2><p>并查集的核心思想是每个元素在集合中都有一个父节点。最初每个元素自成一个集合，父节点指向自己（即每个集合的代表元素是自己）。合并集合时，会将其中一个集合的根节点指向另一个集合的根节点。</p><p>为了提高效率，通常使用两个技术来优化并查集的操作：</p><ol><li><strong>路径压缩（Path Compression）</strong>：在查找操作时，使得路径上的每个节点都直接指向根节点，从而加快后续查找的速度。</li><li><strong>统计联通块数量</strong>：在合并操作时，将不同的两个集合合并到一起，并统计这个集合有多少数目</li></ol><h2 id="4-并查集的实现">4. <strong>并查集的实现</strong></h2><p>以下是并查集的常见实现：<br>c++</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">find</span><span class="params">(<span class="type">int</span> x)</span><span class="comment">//</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (f[x] == x)</span><br><span class="line"><span class="keyword">return</span> x;</span><br><span class="line"><span class="keyword">return</span> f[x] = <span class="built_in">find</span>(f[x]); <span class="comment">// 找祖宗的祖宗，递归到最深层返回</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="模版">模版</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">101001</span>;</span><br><span class="line"><span class="type">int</span> f[N];</span><br><span class="line"><span class="type">int</span> n, m, ans;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">find</span><span class="params">(<span class="type">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (f[x] == x)</span><br><span class="line"><span class="keyword">return</span> x;</span><br><span class="line"><span class="keyword">return</span> f[x] = <span class="built_in">find</span>(f[x]); <span class="comment">// 找祖宗的祖宗，递归到最深层返回</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">f[i] = i;</span><br><span class="line"><span class="keyword">while</span> (m--)</span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> x, y;</span><br><span class="line"><span class="type">char</span> op;</span><br><span class="line">cin &gt;&gt; op &gt;&gt; x &gt;&gt; y;</span><br><span class="line"><span class="keyword">if</span> (op == <span class="string">&#x27;Q&#x27;</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> a = <span class="built_in">find</span>(x), b = <span class="built_in">find</span>(y);</span><br><span class="line"><span class="keyword">if</span> (a == b)</span><br><span class="line">cout &lt;&lt; <span class="string">&quot;Yes\n&quot;</span>;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">cout &lt;&lt; <span class="string">&quot;No\n&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> a = <span class="built_in">find</span>(x), b = <span class="built_in">find</span>(y);</span><br><span class="line">f[a]=b;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>6.2 贪心引入</h1><p>贪心算法（英语：greedy algorithm），是用计算机来模拟一个「贪心」的人做出决策的过程。这个人十分贪婪，每一步行动总是按某种指标选取最优的操作。而且他目光短浅，总是只看眼前，并不考虑以后可能造成的影响。</p><p>可想而知，并不是所有的时候贪心法都能获得最优解，所以一般使用贪心法的时候，都要确保自己能证明其正确性。</p><h2 id="解释">解释</h2><p>贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是问题能够分解成子问题来解决，子问题的最优解能递推到最终问题的最优解。</p><h2 id="证明">证明</h2><p>贪心算法有两种证明方法：反证法和归纳法。一般情况下，一道题只会用到其中的一种方法来证明。</p><ol><li>反证法：如果交换方案中任意两个元素/相邻的两个元素后，答案不会变得更好，那么可以推定目前的解已经是最优解了。</li><li>归纳法：先算得出边界情况（例如 <code>n==1</code>）的最优解，然后再证明：对于每个 <code>n</code> ,$f_{n+1}$ 都可以由 $f_{n}$ 推导出结果。</li></ol><h2 id="要点">要点</h2><p>在算法竞赛中，最常见的贪心有两种。</p><ul><li>我们将 XXX 按照某某顺序排序，然后按某种顺序（例如从小到大）选择。</li><li>我们每次都取 XXX 中最大/小的东西，并更新 XXX。」（有时「XXX 中最大/小的东西」可以优化，比如用优先队列维护）</li></ul><p>二者的区别在于一种是离线的，先处理后选择；一种是在线的，边处理边选择。</p><h2 id="排序解法">排序解法</h2><p>用排序法常见的情况是输入一个包含几个（一般一到两个）权值的数组，通过排序然后遍历模拟计算的方法求出最优值。</p><h2 id="后悔解法">后悔解法</h2><p>思路是无论当前的选项是否最优都接受，然后进行比较，如果选择之后不是最优了，则反悔，舍弃掉这个选项；否则，正式接受。如此往复。</p><h2 id="与动态规划区别">与动态规划区别</h2><p>贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择，不能回退。动态规划则会保存以前的运算结果，并根据以前的结果对当前进行选择，有回退功能。</p><h2 id="例题">例题</h2><p>恰逢 H 国国庆，国王邀请 n 位大臣来玩一个有奖游戏。首先，他让每个大臣在左、右手上面分别写下一个整数，国王自己也在左、右手上各写一个整数。然后，让这 n 位大臣排成一排，国王站在队伍的最前面。排好队后，所有的大臣都会获得国王奖赏的若干金币，每位大臣获得的金币数分别是：排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数，然后向下取整得到的结果。</p><p>国王不希望某一个大臣获得特别多的奖赏，所以他想请你帮他重新安排一下队伍的顺序，使得获得奖赏最多的大臣，所获奖赏尽可能的少。注意，国王的位置始终在队伍的最前面。</p><p><a href="https://www.luogu.com.cn/problem/P1080">P1080 [NOIP 2012 提高组] 国王游戏 - 洛谷</a></p><p>看到任意排列想到邻项交换贪心，发现交换两个相邻并不会造成其他影响，而对于相邻两人而言，肯定是他们两者的最大值越小越好。于是可以直接假设相邻两项 $(a_x, b_x)$ 和 $(a_y, b_y)$，前面的 $\prod a = k$。 那么 $x$ 排在 $y$ 前面的条件是： $$ \frac{k a_x}{b_y} &lt; \frac{k a_y}{b_x} $$ 把 $k$ 除掉并去分母可得： $$ a_x b_x &lt; a_y b_y $$ 直接按这个排序即可。</p><p>由于c/c++ 代码需要高精，阅读量较大，这里给出python代码解释</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 只用讨论左右手乘积最大的那个大臣在最后一位的情况</span></span><br><span class="line">N = <span class="built_in">int</span>(<span class="built_in">input</span>())</span><br><span class="line">left_king, right_king = <span class="built_in">map</span>(<span class="built_in">int</span>, <span class="built_in">input</span>().split())    <span class="comment"># 国王的左右手上分别的数字</span></span><br><span class="line">left_mul = left_king    <span class="comment"># left_mul来记录“已经确认不会是最后一个人”的左手边上的数字</span></span><br><span class="line"></span><br><span class="line">left, right = <span class="built_in">map</span>(<span class="built_in">int</span>, <span class="built_in">input</span>().split())    <span class="comment"># 第一个大臣的</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(N - <span class="number">1</span>):</span><br><span class="line">    left_new, right_new = <span class="built_in">map</span>(<span class="built_in">int</span>, <span class="built_in">input</span>().split())</span><br><span class="line">    <span class="keyword">if</span> left_new * right_new &gt; left * right:   <span class="comment"># 来确认是否是左右手乘积最大的那个大臣</span></span><br><span class="line">        left_mul *= left</span><br><span class="line">        left, right = left_new, right_new</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        left_mul *= left_new</span><br><span class="line">    <span class="built_in">print</span>(left_mul//right)</span><br></pre></td></tr></table></figure><p>同样的，贪心算法是不能进行回推的，所以往往它会需要一个局部最优解，这里常常会结合到优先队列。</p><p>这里给大家介绍一下优先队列，</p><h2 id="优先队列">优先队列</h2><p>优先队列（Priority Queue）是一种特殊的队列数据结构，其中每个元素都有一个与之相关的优先级。与普通队列不同，优先队列并不是按照插入顺序处理元素的，而是根据元素的优先级来决定处理的顺序。具有更高优先级的元素会被优先处理。</p><h3 id="优先队列的特点：">优先队列的特点：</h3><ol><li><strong>元素的优先级</strong>：每个元素在插入时都会分配一个优先级，通常是一个数字。优先级较高的元素会比优先级较低的元素先被处理。</li><li><strong>访问顺序</strong>：在普通队列中，元素按插入顺序处理（FIFO: 先进先出）。而在优先队列中，元素会根据其优先级的高低进行排序，优先级高的元素会先被取出。</li><li><strong>操作</strong>：<ul><li><strong>插入（Push）</strong>：将一个新元素及其优先级添加到队列中。</li><li><strong>删除（Pop）</strong>：从队列中删除并返回优先级最高的元素（优先级数值最小或者最大，取决于实现方式）。</li></ul></li></ol><p>优先队列的内部实现方式是通过堆来实现的，但是我们这里不手写堆，c++的话使用stl中的优先队列，python中使用heapq来调用就可也。</p><h3 id="复杂度分析：">复杂度分析：</h3><ul><li><strong>插入操作（Push）</strong>：对于堆实现的优先队列，插入操作的时间复杂度是O(log n)，因为在最坏的情况下，需要将新元素上浮到合适的位置。</li><li><strong>删除操作（Pop）</strong>：删除操作的时间复杂度为O(log n)，因为需要将堆顶元素删除，并通过下沉操作恢复堆的性质。</li><li><strong>访问最大/最小元素</strong>：对于堆实现，访问最大或最小元素的时间复杂度是O(1)，因为堆的根节点始终存储最优先的元素。</li></ul><p>C++代码示例</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;queue&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Compare</span> &#123; </span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">operator</span><span class="params">()</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> </span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> a &gt; b; <span class="comment">// 将优先队列变为最小堆 </span></span><br><span class="line">&#125; </span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建一个默认的最大堆优先队列</span></span><br><span class="line">    priority_queue&lt;<span class="type">int</span>&gt; pq;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 向队列中插入元素</span></span><br><span class="line">    pq.<span class="built_in">push</span>(<span class="number">10</span>);</span><br><span class="line">    pq.<span class="built_in">push</span>(<span class="number">20</span>);</span><br><span class="line">    pq.<span class="built_in">push</span>(<span class="number">15</span>);</span><br><span class="line">    pq.<span class="built_in">push</span>(<span class="number">30</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 输出并删除优先队列中的元素（按照优先级顺序）</span></span><br><span class="line">    <span class="keyword">while</span> (!pq.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        cout &lt;&lt; pq.<span class="built_in">top</span>() &lt;&lt; <span class="string">&quot; &quot;</span>;  <span class="comment">// 输出优先队列中的最高优先级元素</span></span><br><span class="line">        pq.<span class="built_in">pop</span>();  <span class="comment">// 删除该元素</span></span><br><span class="line">        pq.<span class="built_in">push</span>(<span class="number">156</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="例题-2">例题</h2><p>在一个果园里，多多已经将所有的果子打了下来，而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。</p><p>每一次合并，多多可以把两堆果子合并到一起，消耗的体力等于两堆果子的重量之和。可以看出，所有的果子经过 $n-1$ 次合并之后， 就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。</p><p>因为还要花大力气把这些果子搬回家，所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为 $1$ ，并且已知果子的种类 数和每种果子的数目，你的任务是设计出合并的次序方案，使多多耗费的体力最少，并输出这个最小的体力耗费值。</p><p>例如有 $3$ 种果子，数目依次为 $1$ ， $2$ ， $9$ 。可以先将 $1$ 、 $2$ 堆合并，新堆数目为 $3$ ，耗费体力为 $3$ 。接着，将新堆与原先的第三堆合并，又得到新的堆，数目为 $12$ ，耗费体力为 $12$ 。所以多多总共耗费体力 $=3+12=15$ 。可以证明 $15$ 为最小的体力耗费值。</p><h2 id="思路">思路</h2><p>显然是贪心+优先队列，每次合并的时候选择果子数目少的堆，再把合并的新堆放入优先队列中。</p><h1>7. 位运算</h1><p>{</p><h2 id="求某个数二进制的第i位：-x-1-i">求某个数二进制的第i位：$x&amp;(1&lt;&lt;i)$</h2><p>$(1&lt;&lt;i)$ 表示 $2^i$，$(n&lt;&lt;i)$ 表示 $n*2^i$，$(i&gt;&gt;k)&amp;1$  表示二进制数 $i$ 的从右往左数第 $k$ 位是否为 $1$</p><p>二进制中 -x=~x+1；<br>$lowbit(x)$ 表示返回 $x$ 最后一位为 $1$ 的数</p><ul><li>$k$ 个相同的数异或和，当$k$ 为奇数，结果为这个数本身，否则为 $0$ 。</li><li>任何数与 $0$ 异或是这个数本身。</li></ul><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">lowbit</span><span class="params">(<span class="type">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="keyword">return</span> x&amp;((~x)<span class="number">+1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>}</p><h2 id="X-进制：">X 进制：</h2><p>平时我们所说的10进制数是怎么得出来的呢？<br>比如10进制数 123: 它是由百位上的1 * 10 * 10 加上 十位上的 2 * 10 加上 个位上的 3 得出来的</p><p>关于x进制转10进制：<br>比如题目中给的：11进制（10）、5进制（4）、2进制（0）<br>对于i位上的数字 $num[i]$，转换为十进制就是 $num[i]$ *低于i位所有位的进制</p><pre><code>            就是10*5*2+4*2+0=108    再比如：11进制（1）、5进制（2）、2进制（0）                        就是1*5*2+2*2+0=14</code></pre><h2 id="进制转换">进制转换</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">101001</span>;</span><br><span class="line"></span><br><span class="line">string a, b;</span><br><span class="line">map&lt;<span class="type">char</span>, <span class="type">int</span>&gt; q;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">tra10</span><span class="params">(<span class="type">int</span> n, string s)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> ns = s.<span class="built_in">size</span>();</span><br><span class="line">    <span class="type">int</span> k = <span class="number">1</span>;</span><br><span class="line">    <span class="type">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = ns - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (s[i] &gt;= <span class="string">&#x27;A&#x27;</span> &amp;&amp; s[i] &lt;= <span class="string">&#x27;F&#x27;</span>)</span><br><span class="line">            res += (q[s[i]] * k);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            res += (s[i] - <span class="string">&#x27;0&#x27;</span>) * k;</span><br><span class="line">        k *= n;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">output</span><span class="params">(stack&lt;<span class="type">int</span>&gt; s)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (!s.<span class="built_in">empty</span>())</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (s.<span class="built_in">top</span>() &gt;= <span class="number">10</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            cout &lt;&lt; (<span class="type">char</span>)(s.<span class="built_in">top</span>() + <span class="string">&#x27;A&#x27;</span> - <span class="number">10</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            cout &lt;&lt; s.<span class="built_in">top</span>();</span><br><span class="line">        s.<span class="built_in">pop</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">work</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> r)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    stack&lt;<span class="type">int</span>&gt; s;</span><br><span class="line">    <span class="keyword">while</span> (n)</span><br><span class="line">    &#123;</span><br><span class="line">        s.<span class="built_in">push</span>(n % r);</span><br><span class="line">        n /= r;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">output</span>(s);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> n, m, ans;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; a &gt;&gt; m;</span><br><span class="line">    q[<span class="string">&#x27;A&#x27;</span>] = <span class="number">10</span>;</span><br><span class="line">    q[<span class="string">&#x27;B&#x27;</span>] = <span class="number">11</span>;</span><br><span class="line">    q[<span class="string">&#x27;C&#x27;</span>] = <span class="number">12</span>;</span><br><span class="line">    q[<span class="string">&#x27;D&#x27;</span>] = <span class="number">13</span>;</span><br><span class="line">    q[<span class="string">&#x27;E&#x27;</span>] = <span class="number">14</span>;</span><br><span class="line">    q[<span class="string">&#x27;F&#x27;</span>] = <span class="number">15</span>;</span><br><span class="line">    <span class="type">int</span> n_10 = <span class="built_in">tra10</span>(n, a);</span><br><span class="line">    <span class="comment">// cout &lt;&lt; n_10;</span></span><br><span class="line">    <span class="built_in">work</span>(n_10, m);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>8. 动态规划</h1><h2 id="一、动态规划四步法（万能套路）">一、动态规划四步法（万能套路）</h2><ol><li><p><strong>定义状态</strong><br>明确<code>dp[i]</code>或<code>dp[i][j]</code>表示什么含义</p></li><li><p><strong>确定转移方程</strong><br>找出<code>dp[i]</code>与之前状态的关系（最重要的一步）</p></li><li><p><strong>初始化</strong><br>给初始状态赋基准值（如<code>dp[0] = 0</code>）</p></li><li><p><strong>确定计算顺序</strong><br>保证计算当前状态时，所需的前驱状态都已计算过</p></li></ol><h2 id="二、线性DP-最长递增子序列（LIS）">二、线性DP - 最长递增子序列（LIS）</h2><h3 id="问题描述">问题描述</h3><p>给定数组<code>nums</code>，求最长严格递增子序列长度<br>示例：<code>[10,9,2,5,3,7,101,18]</code> → 最长<code>[2,3,7,101]</code>，长度为4</p><h3 id="解法1：O-n²-模板（必背）">解法1：O(n²)模板（必背）</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">lengthOfLIS</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n = nums.<span class="built_in">size</span>();</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">dp</span><span class="params">(n, <span class="number">1</span>)</span></span>; <span class="comment">// dp[i]表示以nums[i]结尾的LIS长度</span></span><br><span class="line">    <span class="type">int</span> res = <span class="number">1</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt; n; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">0</span>; j &lt; i; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[j] &lt; nums[i]) &#123;</span><br><span class="line">                dp[i] = <span class="built_in">max</span>(dp[i], dp[j] + <span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        res = <span class="built_in">max</span>(res, dp[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="解法2：O-nlogn-优化（进阶）">解法2：O(nlogn)优化（进阶）</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">lengthOfLIS</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; tails; <span class="comment">// tails[k]存储长度为k+1的子序列最小末尾</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> num : nums) &#123;</span><br><span class="line">        <span class="keyword">auto</span> it = <span class="built_in">lower_bound</span>(tails.<span class="built_in">begin</span>(), tails.<span class="built_in">end</span>(), num);</span><br><span class="line">        <span class="keyword">if</span>(it == tails.<span class="built_in">end</span>()) tails.<span class="built_in">push_back</span>(num);</span><br><span class="line">        <span class="keyword">else</span> *it = num;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> tails.<span class="built_in">size</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="三、背包DP-0-1背包">三、背包DP - 0/1背包</h2><h3 id="问题描述-2">问题描述</h3><p>给定物品重量<code>w[]</code>和价值<code>v[]</code>，背包容量<code>W</code>，每个物品只能选0或1次，求最大价值</p><h3 id="标准模板（空间优化版）">标准模板（空间优化版）</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">knapsack</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; w, vector&lt;<span class="type">int</span>&gt;&amp; v, <span class="type">int</span> W)</span> </span>&#123;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">dp</span><span class="params">(W + <span class="number">1</span>, <span class="number">0</span>)</span></span>; <span class="comment">// dp[j]表示容量j时的最大价值</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; w.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = W; j &gt;= w[i]; j--) &#123; <span class="comment">// 必须逆向枚举！</span></span><br><span class="line">            dp[j] = <span class="built_in">max</span>(dp[j], dp[j - w[i]] + v[i]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[W];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="四步法分析：">四步法分析：</h3><ol><li><strong>状态定义</strong>：<code>dp[j]</code>表示容量为j时的最大价值</li><li><strong>转移方程</strong>：<code>dp[j] = max(不选当前物品, 选当前物品)</code></li><li><strong>初始化</strong>：<code>dp[0]=0</code>，其他初始为0</li><li><strong>计算顺序</strong>：外层遍历物品，内层逆向遍历容量</li></ol><h2 id="四、背包DP-完全背包">四、背包DP - 完全背包</h2><h3 id="问题描述-3">问题描述</h3><p>与0/1背包相同，但物品可以选无限次</p><h3 id="模板（与0-1背包仅枚举顺序不同）">模板（与0/1背包仅枚举顺序不同）</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">knapsack</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; w, vector&lt;<span class="type">int</span>&gt;&amp; v, <span class="type">int</span> W)</span> </span>&#123;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">dp</span><span class="params">(W + <span class="number">1</span>, <span class="number">0</span>)</span></span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; w.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = w[i]; j &lt;= W; j++) &#123; <span class="comment">// 正向枚举！</span></span><br><span class="line">            dp[j] = <span class="built_in">max</span>(dp[j], dp[j - w[i]] + v[i]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[W];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="关键区别：">关键区别：</h3><ul><li>0/1背包：内层逆向枚举（防止重复选择）</li><li>完全背包：内层正向枚举（允许重复选择）</li></ul><h2 id="五、实战技巧">五、实战技巧</h2><ol><li><p><strong>Debug检查清单</strong>：</p><ul><li>是否正/逆向枚举搞错？</li><li>数组大小是否足够？</li><li>边界条件是否处理？</li></ul></li><li><p><strong>记忆口诀</strong>：</p><ul><li>“01背包倒着走，完全背包正着来”</li><li>“LIS两重循环，二分优化替换”</li></ul></li><li><p><strong>经典变形</strong>：</p><ul><li>背包问题求方案数 → 初始化<code>dp[0]=1</code>，转移用<code>+=</code></li><li>背包问题求具体方案 → 记录转移路径</li></ul></li></ol><p>掌握这两个模型，能解决80%的笔试DP题！建议先手敲模板10遍，再找3道相关题目练习。</p><h1>蓝桥杯专项总结</h1><h2 id="1-🧩-STL（优先级最高）">1. 🧩 <strong>STL（优先级最高）</strong></h2><h3 id="核心容器-函数">核心容器/函数</h3><ul><li><code>vector</code><br><code>push_back()</code> / <code>pop_back()</code> / <code>size()</code></li><li><code>string</code><br><code>substr(pos, len)</code> / <code>find(str)</code> / <code>+=</code></li><li><code>queue</code><br><code>push()</code> / <code>front()</code> / <code>pop()</code></li><li><code>priority_queue</code><br>默认大根堆，小根堆：<code>priority_queue&lt;int, vector&lt;int&gt;, greater&lt;int&gt;&gt;</code></li><li><code>sort(v.begin(), v.end())</code><br>自定义排序：<code>bool cmp(int a, int b) &#123; return a &gt; b; &#125;</code></li></ul><h3 id="⚡-应用场景">⚡ 应用场景</h3><ul><li>快速实现数组操作（vector）</li><li>字符串处理（substr截取子串）</li><li>堆优化（Dijkstra算法优先队列）</li></ul><hr><h2 id="2-🔢-排序（STL为主）">2. 🔢 <strong>排序（STL为主）</strong></h2><h3 id="关键模板">关键模板</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 自定义结构体排序</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span> &#123; <span class="type">int</span> x, y; &#125;;</span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(Node a, Node b)</span> </span>&#123; </span><br><span class="line">    <span class="keyword">if</span> (a.x == b.x) <span class="keyword">return</span> a.y &lt; b.y;</span><br><span class="line">    <span class="keyword">return</span> a.x &gt; b.x;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), cmp);</span><br></pre></td></tr></table></figure><h3 id="⚡-应用场景-2">⚡ 应用场景</h3><ul><li>贪心算法前的预处理</li><li>二分查找前的有序化</li></ul><hr><h2 id="3-🔍-二分（必背！）">3. 🔍 <strong>二分（必背！）</strong></h2><h3 id="整数二分模板">整数二分模板</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> l=<span class="number">1</span>;r=n;</span><br><span class="line"><span class="type">int</span> ans;<span class="comment">//ans表示当前答案满足时的最优解</span></span><br><span class="line"><span class="keyword">while</span>(l&lt;=r) </span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> mid=(l+r)&gt;&gt;<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">check</span>(mid))</span><br><span class="line">   l=mid<span class="number">+1</span>,ans=mid; </span><br><span class="line"><span class="keyword">else</span> r=mid<span class="number">-1</span>; </span><br><span class="line">&#125;</span><br><span class="line">cout &lt;&lt; ans;</span><br></pre></td></tr></table></figure><h3 id="实数二分模板">实数二分模板</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">double</span> l=<span class="number">0</span>, r=<span class="number">1e9</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i=<span class="number">0</span>; i&lt;<span class="number">100</span>; i++) &#123; <span class="comment">// 精度控制</span></span><br><span class="line">    <span class="type">double</span> mid = (l + r) / <span class="number">2</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">check</span>(mid)) r = mid;</span><br><span class="line">    <span class="keyword">else</span> l = mid;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="⚡-应用场景-3">⚡ 应用场景</h3><ul><li>有序数组查找</li><li>答案单调时的最优解问题（如：分绳子）</li></ul><hr><h2 id="4-➕-前缀和与差分">4. ➕ <strong>前缀和与差分</strong></h2><h3 id="一维核心公式">一维核心公式</h3><ul><li><strong>前缀和</strong>：<code>s[i] = s[i-1] + a[i]</code></li><li><strong>差分</strong>：<code>diff[l] += c</code>, <code>diff[r+1] -= c</code></li></ul><h3 id="二维差分操作">二维差分操作</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 矩阵区域加减</span></span><br><span class="line">diff[x1][y1] += c;</span><br><span class="line">diff[x2<span class="number">+1</span>][y1] -= c;</span><br><span class="line">diff[x1][y2<span class="number">+1</span>] -= c;</span><br><span class="line">diff[x2<span class="number">+1</span>][y2<span class="number">+1</span>] += c;</span><br></pre></td></tr></table></figure><h3 id="⚡-应用场景-4">⚡ 应用场景</h3><ul><li>区间求和（O(1)查询）</li><li>多次区间修改后求最终数组</li></ul><hr><h2 id="5-🧮-数学（背公式！）">5. 🧮 <strong>数学（背公式！）</strong></h2><h3 id="高频考点">高频考点</h3><ul><li><strong>质数判断</strong>：试除法（枚举到√n）</li><li>筛质数（线性筛，埃氏筛）</li><li><strong>快速幂</strong>（递归分治）：<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">qpow</span><span class="params">(<span class="type">long</span> <span class="type">long</span> a, <span class="type">long</span> <span class="type">long</span> b, <span class="type">long</span> <span class="type">long</span> p)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (b == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span> % p;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> res = <span class="built_in">qpow</span>(a, b/<span class="number">2</span>, p);</span><br><span class="line">    <span class="keyword">return</span> b % <span class="number">2</span> ? res * res % p * a % p : res * res % p;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><strong>最大公约数</strong>：<code>__gcd(a, b)</code>（STL自带）</li><li>组合数学问题</li><li>进制问题</li></ul><hr><h2 id="6-🤝-并查集-贪心">6. 🤝 <strong>并查集 + 贪心</strong></h2><h3 id="并查集模板">并查集模板</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> father[N];</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">find</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> father[x] == x ? x : father[x] = <span class="built_in">find</span>(father[x]);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">merge</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> </span>&#123;</span><br><span class="line">    father[<span class="built_in">find</span>(a)] = <span class="built_in">find</span>(b);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="贪心策略">贪心策略</h3><ul><li><strong>排序贪心</strong>：按权重排序后取最优</li><li><strong>区间调度</strong>：优先选结束早的</li></ul><hr><h2 id="7-💻-二进制与位运算">7. 💻 <strong>二进制与位运算</strong></h2><h3 id="常用操作">常用操作</h3><ul><li><code>n &amp; 1</code>：判断奇偶</li><li><code>n &gt;&gt; 1</code>：等价于 <code>/2</code></li><li><code>a ^ b ^ b = a</code>：交换变量 <code>a = a ^ b; b = a ^ b; a = a ^ b;</code></li></ul><h3 id="⚡-应用场景-5">⚡ 应用场景</h3><ul><li>状态压缩（用二进制表示集合）</li><li>快速计算乘除2的幂</li></ul><hr><h2 id="8-🐌-动态规划">8. 🐌 <strong>动态规划</strong></h2><h3 id="经典问题">经典问题</h3><ul><li><strong>背包问题</strong><br>状态转移：<code>dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]] + w[i])</code></li><li><strong>最长递增子序列</strong><br>状态转移：<code>dp[i] = max(dp[i], dp[j] + 1) (j &lt; i &amp;&amp; a[j] &lt; a[i])</code></li></ul><h3 id="⚡-技巧">⚡ 技巧</h3><ul><li>解决「01背包」「斐波那契」等基础模型</li></ul><p><strong>📌 策略</strong></p><ol><li><strong>优先掌握</strong>：STL &gt; 排序 &gt; 二分 &gt; 前缀和</li><li><strong>代码默写</strong>：每天手敲一次二分/快速幂模板</li><li><strong>动态规划</strong>：留到最后，只背经典题！</li></ol><div class="note default flat"><p>特别鸣谢！文章参考：[云顶数模]、[茶灵山艾府]、[菜鸟教程]</p></div>]]></content>
    
    
    <summary type="html">🪅专攻多数据结构结合💡与算法应用分析🧮的学习笔记📝与题解反思📋</summary>
    
    
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/categories/%E7%AE%97%E6%B3%95/"/>
    
    
    <category term="C++" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="程序设计" scheme="https://home.y1xuanyun.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
    
    <category term="数据结构" scheme="https://home.y1xuanyun.cn/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    
    <category term="语法" scheme="https://home.y1xuanyun.cn/tags/%E8%AF%AD%E6%B3%95/"/>
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/tags/%E7%AE%97%E6%B3%95/"/>
    
  </entry>
  
  <entry>
    <title>ASP.NET 程序设计 登入查询页面详解</title>
    <link href="https://home.y1xuanyun.cn/posts/25net01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25net01.html</id>
    <published>2025-04-02T03:00:00.000Z</published>
    <updated>2025-04-07T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="note default flat"><p>本文涉及刘老师清华大学出版社教材<code>167-183</code>页内容</p></div><h1>前置准备</h1><p>需要完成以下前置准备工作，方可进行下一节代码调试</p><h2 id="数据库设计">数据库设计</h2><p>如想要实现数据库连接，需要先使用SSMS（SQL Server Management Studio）创建数据库和数据表并手动修改添加数据。<br>以下为SQLServer数据库的创建教程和数据表的创建教程，请根据实际情况进行操作0。</p><div class="btns rounded grid5">            <a class="button" href='https://blog.csdn.net/m0_62688033/article/details/136138586' title='表的创建'><i class='fas fa-book-open'></i>表的创建</a><a class="button" href='https://blog.csdn.net/weixin_30877493/article/details/96261187' title='修改表数据'><i class='fas fa-book-open'></i>修改表数据</a>          </div><ol><li>SSMS连接<br>服务器类型：<code>数据库引擎</code><br>服务器名称：<code>(local)</code><br>身份验证：<code>Windows身份验证</code></li><li>创建数据库<br>数据库名称为<code>Studentdata</code>，以下“database=该数据库名称”</li><li>创建数据表</li></ol><div class="note success no-icon flat"><p>tbl_Userinfo （登入信息表）</p></div><table><thead><tr><th style="text-align:center">字段</th><th style="text-align:center">用途</th><th style="text-align:center">字段类型</th></tr></thead><tbody><tr><td style="text-align:center"><code>user_name</code></td><td style="text-align:center">用户名</td><td style="text-align:center">nchar(10)</td></tr><tr><td style="text-align:center"><code>pwd</code></td><td style="text-align:center">密码</td><td style="text-align:center">nchar(10)</td></tr></tbody></table><div class="note success no-icon flat"><p>tbl_Studentinfo （学生信息表）</p></div><table><thead><tr><th style="text-align:center">字段</th><th style="text-align:center">用途</th><th style="text-align:center">字段类型</th></tr></thead><tbody><tr><td style="text-align:center"><code>userid</code></td><td style="text-align:center">学号</td><td style="text-align:center">nchar(10)</td></tr><tr><td style="text-align:center"><code>name</code></td><td style="text-align:center">姓名</td><td style="text-align:center">nchar(10)</td></tr><tr><td style="text-align:center"><code>gender</code></td><td style="text-align:center">性别</td><td style="text-align:center">nchar(10)</td></tr><tr><td style="text-align:center"><code>birthday</code></td><td style="text-align:center">出生日期</td><td style="text-align:center"><code>datetime</code></td></tr><tr><td style="text-align:center"><code>telephone</code></td><td style="text-align:center">电话</td><td style="text-align:center"><code>nchar(11)</code></td></tr></tbody></table><h2 id="页面设计">页面设计</h2><ol><li>Login.aspx.cs 登入页面</li></ol><table><thead><tr><th style="text-align:center">名称</th><th style="text-align:center">用途</th><th style="text-align:center">组件类型及ID</th></tr></thead><tbody><tr><td style="text-align:center"><code>登入</code>📨</td><td style="text-align:center">验证跳转</td><td style="text-align:center"><code>Button1_Click</code></td></tr><tr><td style="text-align:center"><code>重置</code>💿</td><td style="text-align:center">清空文本框</td><td style="text-align:center"><code>Button2_Click</code></td></tr><tr><td style="text-align:center"><code>账号</code>📝</td><td style="text-align:center">录入账号</td><td style="text-align:center"><code>TextBox1</code></td></tr><tr><td style="text-align:center"><code>密码</code>📝</td><td style="text-align:center">录入密码</td><td style="text-align:center"><code>TextBox2</code></td></tr></tbody></table><ol start="2"><li>Search.aspx.cs 查询页面</li></ol><table><thead><tr><th style="text-align:center">名称</th><th style="text-align:center">用途</th><th style="text-align:center">组件类型及ID</th></tr></thead><tbody><tr><td style="text-align:center"><code>学号</code>🔍</td><td style="text-align:center">查询依据</td><td style="text-align:center"><code>TextBox0</code></td></tr><tr><td style="text-align:center"><code>提交</code>📨</td><td style="text-align:center">查询数据库</td><td style="text-align:center"><code>Button1_Click</code></td></tr><tr><td style="text-align:center"><code>学号</code>📃</td><td style="text-align:center">结果显示</td><td style="text-align:center"><code>TextBox1</code></td></tr><tr><td style="text-align:center"><code>姓名</code>📃</td><td style="text-align:center">结果显示</td><td style="text-align:center"><code>TextBox2</code></td></tr><tr><td style="text-align:center"><code>性别</code>📃</td><td style="text-align:center">结果显示</td><td style="text-align:center"><code>TextBox3</code></td></tr><tr><td style="text-align:center"><code>出生</code>📃</td><td style="text-align:center">结果显示</td><td style="text-align:center"><code>TextBox4</code></td></tr><tr><td style="text-align:center"><code>电话</code>📃</td><td style="text-align:center">结果显示</td><td style="text-align:center"><code>TextBox5</code></td></tr></tbody></table><h3 id="页面布局">页面布局</h3><p><img src="https://file.y1xuanyun.cn/posts/25net01/WebF01.jpg" alt=""></p><div class="note warning flat"><p>受有限带宽影响图片加载较慢请耐心等待</p></div><h1><a href="http://ASP.NET">ASP.NET</a> Web 登录与查询功能代码</h1><p>以下为基于C#<a href="http://xn--ASP-2w2h.NET">的ASP.NET</a> Web 登录功能代码实现，完成以上准备工作后，请将代码复制到对应的文件中，并确保代码中的数据库连接字符串正确。</p><div class="note warning flat"><p>参考代码前后请双击按钮组件以确保被正确定位到C#代码</p></div><h2 id="Login-aspx-cs-登入页面">Login.aspx.cs 登入页面</h2><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"><span class="keyword">using</span> System.Data.SqlClient;</span><br><span class="line"><span class="keyword">using</span> System.Data;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">partial</span> <span class="keyword">class</span> <span class="title">Login</span> : <span class="title">System.Web.UI.Page</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">Page_Load</span>(<span class="params"><span class="built_in">object</span> sender, EventArgs e</span>)</span>&#123;&#125;<span class="comment">//页面加载时执行</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">Button2_Click</span>(<span class="params"><span class="built_in">object</span> sender, EventArgs e</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        TextBox1.Text = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        TextBox2.Text = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        TextBox1.Focus(); <span class="comment">//焦点设置</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">Button1_Click</span>(<span class="params"><span class="built_in">object</span> sender, EventArgs e</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        SqlConnection con = <span class="keyword">new</span> SqlConnection();</span><br><span class="line">        con.ConnectionString = <span class="string">&quot;server=(local);database=Studentdata;trusted_connection=true&quot;</span>;</span><br><span class="line">        <span class="keyword">try</span></span><br><span class="line">        &#123;</span><br><span class="line">            con.Open();</span><br><span class="line">            SqlCommand cmd = <span class="keyword">new</span> SqlCommand();</span><br><span class="line">            cmd.Connection = con;</span><br><span class="line">            cmd.CommandType = CommandType.Text;</span><br><span class="line">            cmd.CommandText = <span class="string">&quot;select count(*) from tbl_Userinfo where user_name=&#x27;&quot;</span> + TextBox1.Text + <span class="string">&quot;&#x27; and pwd=&#x27;&quot;</span> + TextBox2.Text + <span class="string">&quot;&#x27;&quot;</span>;</span><br><span class="line">            <span class="built_in">int</span> i = Convert.ToInt16(cmd.ExecuteScalar());</span><br><span class="line">            <span class="keyword">if</span> (i == <span class="number">1</span>)</span><br><span class="line">            &#123; </span><br><span class="line">                Response.Redirect(<span class="string">&quot;Search.aspx&quot;</span>); </span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                Response.Write(<span class="string">&quot;用户名密码错误，请重新输入！&quot;</span>);</span><br><span class="line">                TextBox1.Text = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                TextBox2.Text = <span class="string">&quot;&quot;</span>;</span><br><span class="line">                TextBox1.Focus(); <span class="comment">//焦点设置</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      <span class="keyword">catch</span> </span><br><span class="line">        &#123;</span><br><span class="line">            Response.Write(<span class="string">&quot;数据库连接失败！&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="Search-aspx-cs-查询页面">Search.aspx.cs 查询页面</h2><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"><span class="keyword">using</span> System.Data.SqlClient;</span><br><span class="line"><span class="keyword">using</span> System.Data;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">partial</span> <span class="keyword">class</span> <span class="title">Search</span> : <span class="title">System.Web.UI.Page</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">Page_Load</span>(<span class="params"><span class="built_in">object</span> sender, EventArgs e</span>)</span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">Button1_Click</span>(<span class="params"><span class="built_in">object</span> sender, EventArgs e</span>)</span></span><br><span class="line">    &#123;</span><br><span class="line">        SqlConnection con = <span class="keyword">new</span> SqlConnection();</span><br><span class="line">        con.ConnectionString = <span class="string">&quot;server=(local);database=Studentdata;trusted_connection=true&quot;</span> ;</span><br><span class="line">        <span class="keyword">try</span></span><br><span class="line">        &#123;</span><br><span class="line">            con.Open();</span><br><span class="line">            SqlCommand cmd = <span class="keyword">new</span> SqlCommand();</span><br><span class="line">            cmd.Connection = con;</span><br><span class="line">            cmd.CommandType = CommandType.Text;</span><br><span class="line">            cmd.CommandText = <span class="string">&quot;select count(*) from tbl_Studentinfo where userid=&#x27;&quot;</span> + TextBox0.Text + <span class="string">&quot;&#x27;&quot;</span>;</span><br><span class="line">            <span class="built_in">int</span> i = Convert.ToInt16(cmd.ExecuteScalar()); </span><br><span class="line">            <span class="keyword">if</span> (i == <span class="number">1</span>) <span class="comment">//判断学号是否存在</span></span><br><span class="line">            &#123;</span><br><span class="line"></span><br><span class="line">                SqlCommand cmd2 = <span class="keyword">new</span> SqlCommand();</span><br><span class="line">                cmd2.Connection = con;</span><br><span class="line">                cmd2.CommandType = CommandType.Text;</span><br><span class="line">                cmd2.CommandText = <span class="string">&quot;select * from tbl_Studentinfo where userid=&#x27;&quot;</span> + TextBox0.Text + <span class="string">&quot;&#x27;&quot;</span>;</span><br><span class="line">                SqlDataReader dr = cmd2.ExecuteReader();</span><br><span class="line">                <span class="keyword">while</span> (dr.Read())</span><br><span class="line">                    &#123;</span><br><span class="line">                    TextBox1.Text = dr.GetString(<span class="number">0</span>);<span class="comment">//学号</span></span><br><span class="line">                    TextBox2.Text = dr.GetString(<span class="number">1</span>);<span class="comment">//姓名</span></span><br><span class="line">                    TextBox3.Text = dr.GetString(<span class="number">2</span>);<span class="comment">//性别</span></span><br><span class="line">                    TextBox4.Text = Convert.ToString(dr.GetValue(<span class="number">3</span>));<span class="comment">//出生//若为nchar类型，则使用GetString方法</span></span><br><span class="line">                    TextBox5.Text = dr.GetString(<span class="number">4</span>);<span class="comment">//电话</span></span><br><span class="line">                &#125;</span><br><span class="line">                dr.Close(); <span class="comment">//关闭数据读取器</span></span><br><span class="line">                con.Close(); <span class="comment">//关闭数据库连接</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">                Response.Write(<span class="string">&quot;记录不存在&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span> &#123;</span><br><span class="line">            Response.Write(<span class="string">&quot;数据库连接失败！&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>特别鸣谢</h1><div class="note default flat"><p>参考：<a href="https://www.nepu.edu.cn/">ASP.NET程序设计及应用[刘苗苗]</a></p></div>]]></content>
    
    
    <summary type="html">SQLServer数据库连接、C# 登录与查询功能代码实现</summary>
    
    
    
    <category term="Web" scheme="https://home.y1xuanyun.cn/categories/Web/"/>
    
    
    <category term="环境配置" scheme="https://home.y1xuanyun.cn/tags/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/"/>
    
    <category term="指南" scheme="https://home.y1xuanyun.cn/tags/%E6%8C%87%E5%8D%97/"/>
    
    <category term="ASP.NET" scheme="https://home.y1xuanyun.cn/tags/ASP-NET/"/>
    
    <category term="SQLServer" scheme="https://home.y1xuanyun.cn/tags/SQLServer/"/>
    
    <category term="SQL" scheme="https://home.y1xuanyun.cn/tags/SQL/"/>
    
    <category term="C#" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>使用批处理脚本自动化安装与配置 MySQL 数据库</title>
    <link href="https://home.y1xuanyun.cn/posts/25sql01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25sql01.html</id>
    <published>2025-04-02T03:00:00.000Z</published>
    <updated>2025-04-07T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>在 Windows 环境下，手动安装和配置 MySQL 数据库往往涉及多个繁琐的步骤。通过编写批处理脚本（<code>.bat</code>），我们可以实现 MySQL 的自动化安装、配置甚至数据导入，大大提高效率并减少人为错误。本文将介绍一个实用的 MySQL 自动化安装脚本，并对其实现原理和优化建议进行解析。</p><hr><h1>📜 脚本概览</h1><p>以下批处理脚本实现了 MySQL 的自动化安装、服务配置、Root 密码设置以及可选的 SQL 文件导入功能：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">@echo off</span><br><span class="line">setlocal</span><br><span class="line">REM ===== 配置参数 =====</span><br><span class="line">set &quot;MYSQL_DIR=盘符目录\mysql-9.0.1-winx64&quot;</span><br><span class="line">set &quot;ROOT_PASS=123456&quot;</span><br><span class="line">set &quot;SQL_FILE=%MYSQL_DIR%\数据库文件名.sql&quot;  REM 要导入的SQL文件路径</span><br><span class="line">REM ===== 停止现有MySQL服务 =====</span><br><span class="line">net stop MySQL 2&gt;nul</span><br><span class="line">if %errorlevel% neq 0 (</span><br><span class="line">echo MySQL服务未运行或停止失败</span><br><span class="line">)</span><br><span class="line">REM ===== 终止占用3306端口的进程 =====</span><br><span class="line">for /f &quot;tokens=5&quot; %%a in (&#x27;netstat -ano ^| findstr &quot;:3306 &quot;&#x27;) do (</span><br><span class="line">taskkill /f /pid %%a 2&gt;nul</span><br><span class="line">echo 已终止进程ID: %%a</span><br><span class="line">)</span><br><span class="line">REM ===== 管理员权限安装 =====</span><br><span class="line">cd /d &quot;%MYSQL_DIR%\bin&quot;</span><br><span class="line">REM 初始化+安装服务+启动服务</span><br><span class="line">mysqld --initialize-insecure --console</span><br><span class="line">mysqld --install MySQL</span><br><span class="line">net start MySQL</span><br><span class="line">REM ===== 等待MySQL服务完全启动 =====</span><br><span class="line">timeout /t 5 /nobreak &gt;nul</span><br><span class="line">REM ===== 自动设置密码 =====</span><br><span class="line">mysql -u root -e &quot;ALTER USER &#x27;root&#x27;@&#x27;localhost&#x27; IDENTIFIED BY &#x27;%ROOT_PASS%&#x27;; FLUSH PRIVILEGES;&quot;</span><br><span class="line">REM ===== 检查SQL文件是否存在并导入 =====</span><br><span class="line">if exist &quot;%SQL_FILE%&quot; (</span><br><span class="line">echo 开始导入SQL文件: %SQL_FILE%</span><br><span class="line">mysql -u root -p%ROOT_PASS% &lt; &quot;%SQL_FILE%&quot;</span><br><span class="line">if !errorlevel! equ 0 (</span><br><span class="line">echo ✅ SQL文件导入成功</span><br><span class="line">) else (</span><br><span class="line">echo ❌ SQL文件导入失败，错误代码: !errorlevel!</span><br><span class="line">)</span><br><span class="line">) else (</span><br><span class="line">echo ❌ 未找到SQL文件: %SQL_FILE%</span><br><span class="line">echo 请确保文件存在且路径正确</span><br><span class="line">)</span><br><span class="line">echo --</span><br><span class="line">echo ✅ MySQL 安装完成</span><br><span class="line">echo ✅ Root 密码已设置为: %ROOT_PASS%</span><br><span class="line">pause</span><br></pre></td></tr></table></figure><hr><h1>🧠 脚本解析与批处理知识补充</h1><h2 id="1-批处理脚本基础">1. 批处理脚本基础</h2><ul><li><code>@echo off</code>：关闭命令回显，使输出更整洁。</li><li><code>setlocal</code>：确保环境变量变化仅在脚本内有效。</li><li><code>REM</code>：注释语句，不影响脚本执行。</li></ul><h2 id="2-错误处理与输出重定向">2. 错误处理与输出重定向</h2><ul><li><code>2&gt;nul</code>：隐藏错误信息。</li><li><code>netstat -ano ^| findstr &quot;:3306 &quot;</code>：查找占用 3306 端口的进程。</li><li><code>taskkill /f /pid %%a</code>：强制终止指定进程。</li></ul><h2 id="3-MySQL-安装与配置">3. MySQL 安装与配置</h2><ul><li><code>--initialize-insecure</code>：初始化数据目录，不使用随机密码。</li><li><code>--install [服务名]</code>：将 MySQL 安装为 Windows 服务。</li><li><code>net start/stop</code>：启动或停止服务。</li></ul><h2 id="4-条件判断与流程控制">4. 条件判断与流程控制</h2><ul><li><code>if exist</code>：判断文件是否存在。</li><li><code>if %errorlevel%</code> 和 <code>if !errorlevel!</code>：检查上一条命令的执行结果。</li></ul><hr><h1>🛠 推广到一般情况的建议</h1><h2 id="1-参数化与配置分离">1. 参数化与配置分离</h2><p>建议将配置参数（如路径、密码）提取到外部配置文件（如 <code>config.ini</code>），增强脚本的灵活性：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">for /f &quot;delims=&quot; %%i in (&#x27;type config.ini&#x27;) do set &quot;%%i&quot;</span><br></pre></td></tr></table></figure><h2 id="2-增强错误处理">2. 增强错误处理</h2><p>添加更详细的错误日志记录，便于排查问题：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">net start MySQL || (</span><br><span class="line">echo [!] 服务启动失败，正在查询日志...</span><br><span class="line">findstr /i &quot;error&quot; &quot;%MYSQL_DIR%\data*.err&quot;</span><br><span class="line">exit /b 1</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h2 id="3-权限检查与请求">3. 权限检查与请求</h2><p>在脚本开头检查管理员权限，若非管理员则自动请求提升：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">net session &gt;nul 2&gt;&amp;1 || (</span><br><span class="line">echo 请求管理员权限...</span><br><span class="line">powershell -Command &quot;Start-Process cmd -ArgumentList &#x27;/c %~0&#x27; -Verb RunAs&quot;</span><br><span class="line">exit /b</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h2 id="4-日志记录">4. 日志记录</h2><p>重定向关键操作输出到日志文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">call :log &gt;&gt; &quot;%MYSQL_DIR%\install.log&quot; 2&gt;&amp;1</span><br><span class="line">exit /b</span><br><span class="line">:log</span><br><span class="line">:: 脚本主体放在此处</span><br></pre></td></tr></table></figure><h2 id="5-支持自定义选项">5. 支持自定义选项</h2><p>通过命令行参数指定配置，如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">f &quot;%~1&quot; neq &quot;&quot; set &quot;MYSQL_DIR=%~1&quot;</span><br><span class="line">if &quot;%~2&quot; neq &quot;&quot; set &quot;ROOT_PASS=%~2&quot;</span><br><span class="line">:: 脚本主体放在此处</span><br></pre></td></tr></table></figure><hr><h1>✅ 总结</h1><p>通过批处理脚本实现 MySQL 的自动化安装与配置，可以显著提升在 Windows 系统上的部署效率。本脚本提供了一个基础框架，适用于开发、测试环境的快速搭建。你可以根据实际需求扩展更多功能，如备份恢复、多实例支持等。</p><p>如果你有更复杂的需求（例如多版本管理、集群部署），建议结合 PowerShell 或专业配置管理工具（如 Ansible）实现。</p><hr><p><strong>版权声明</strong>：本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来源！</p>]]></content>
    
    
    <summary type="html">通过编写批处理脚本（`.bat`）大大提高效率并减少人为错误</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="脚本" scheme="https://home.y1xuanyun.cn/tags/%E8%84%9A%E6%9C%AC/"/>
    
    <category term="SQL" scheme="https://home.y1xuanyun.cn/tags/SQL/"/>
    
    <category term="MySQL" scheme="https://home.y1xuanyun.cn/tags/MySQL/"/>
    
    <category term="自动化" scheme="https://home.y1xuanyun.cn/tags/%E8%87%AA%E5%8A%A8%E5%8C%96/"/>
    
  </entry>
  
  <entry>
    <title>东油秦“代码织锦，智启星河”编程竞逐赛</title>
    <link href="https://home.y1xuanyun.cn/posts/25cpp01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25cpp01.html</id>
    <published>2025-03-30T10:00:00.000Z</published>
    <updated>2025-04-06T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="note info flat"><p>该比赛圆满结束，比赛页面详见 <a href="https://www.luogu.com.cn/contest/238293">东油秦“代码织锦，智启星河”编程竞逐赛</a> 比赛邀请码：yxal</p></div><h1>活动背景</h1><p>在数字浪潮奔涌的时代，代码是编织未来的丝线，算法是叩击真理的密钥。为激发本校学子探索计算机科学的热情，提升逻辑思维与实践能力，东北石油大学秦皇岛校区大数据与计算机科学系特此举办编程竞赛，以赛促学、以技会友，于代码的方寸之间，窥见浩瀚星河。</p><h1>主办单位</h1><p>东北石油大学秦皇岛校区大数据与计算机科学系系学生会</p><h1>比赛内容</h1><p>赛制：采用IOI赛制，即赛时反馈，按测试点或子任务得分。<br>评分规则：比赛结束后按总得分及总用时进行排名（罚时制）。<br>题目详情：8道编程题，难度梯度递增，覆盖基础语法、简单算法与递归搜索，整体难度介于课后习题与力扣周赛之间。</p><h1>赛后总结</h1><p>本次比赛圆满结束，在此向所有获奖选手致以最热烈的祝贺。你们用代码编织逻辑之美，以算法突破思维边界，这份荣誉既是天赋与热爱的馈赠，更是无数深夜调试代码、反复优化方案的汗水结晶，让智慧的火花得以璀璨绽放。<br>期待未来见证更多同学&quot;以创新精神书写数字时代的新篇章&quot;！代码永无止境，少年未来可期！</p><h2 id="封榜时刻">封榜时刻</h2><p><img src="https://file.y1xuanyun.cn/img/active/NEPU_QHD_codeP1.png" alt=""></p><div class="note info flat"><p>因带宽限制，图片加载较慢，请耐心等待。</p></div><h1>题目列表及解题思路</h1><h1>1. P1425 小鱼的游泳时间</h1><h2 id="题目描述">题目描述</h2><p>伦敦奥运会要到了，小鱼在拼命练习游泳准备参加游泳比赛，可怜的小鱼并不知道鱼类是不能参加人类的奥运会的。</p><p>这一天，小鱼给自己的游泳时间做了精确的计时（本题中的计时都按 $24$ 小时制计算），它发现自己从 $a$ 时 $b$ 分一直游泳到当天的 $c$ 时 $d$ 分，请你帮小鱼计算一下，它这天一共游了多少时间呢？</p><p>小鱼游的好辛苦呀，你可不要算错了哦。</p><h2 id="输入格式">输入格式</h2><p>一行内输入四个整数，以空格隔开，分别表示题目中的 $a, b, c, d$。</p><h2 id="输出格式">输出格式</h2><p>一行内输出两个整数 $e$ 和 $f$，用空格间隔，依次表示小鱼这天一共游了多少小时多少分钟。其中表示分钟的整数 $f$ 应该小于 $60$。</p><h2 id="输入输出样例-1">输入输出样例 #1</h2><h3 id="输入-1">输入 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">12 </span><span class="number">50</span> <span class="number">19</span> <span class="number">10</span></span><br></pre></td></tr></table></figure><h3 id="输出-1">输出 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">6 </span><span class="number">20</span></span><br></pre></td></tr></table></figure><h2 id="说明-提示">说明/提示</h2><p>对于全部测试数据，$0\le a,c \le 24$，$0\le b,d \le 60$，且结束时间一定晚于开始时间。</p><h2 id="解题思路">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> a, b, c, d, s;</span><br><span class="line">    cin &gt;&gt; a &gt;&gt; b &gt;&gt; c &gt;&gt; d;</span><br><span class="line">    s = c * <span class="number">60</span> + d - (a * <span class="number">60</span> + b);</span><br><span class="line">    cout &lt;&lt; s / <span class="number">60</span> &lt;&lt; <span class="string">&quot; &quot;</span> &lt;&lt; s % <span class="number">60</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>2. B2028 反向输出一个三位数</h1><h2 id="题目描述-2">题目描述</h2><p>将一个三位数反向输出，例如输入 $358$，反向输出 $853$。</p><h2 id="输入格式-2">输入格式</h2><p>一个三位数 $n$。</p><h2 id="输出格式-2">输出格式</h2><p>反向输出 $n$。</p><h2 id="输入输出样例-1-2">输入输出样例 #1</h2><h3 id="输入-1-2">输入 #1</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">100</span><br></pre></td></tr></table></figure><h3 id="输出-1-2">输出 #1</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">001</span><br></pre></td></tr></table></figure><h2 id="输入输出样例-2">输入输出样例 #2</h2><h3 id="输入-2">输入 #2</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">001</span><br></pre></td></tr></table></figure><h3 id="输出-2">输出 #2</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">100</span><br></pre></td></tr></table></figure><h2 id="输入输出样例-3">输入输出样例 #3</h2><h3 id="输入-3">输入 #3</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">678</span><br></pre></td></tr></table></figure><h3 id="输出-3">输出 #3</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">876</span><br></pre></td></tr></table></figure><h2 id="解题思路-2">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    cout &lt;&lt; n % <span class="number">10</span> &lt;&lt; n % <span class="number">100</span> / <span class="number">10</span> &lt;&lt; n / <span class="number">100</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>3. B3735 [信息与未来 2018] 圣诞树</h1><h2 id="题目描述-3">题目描述</h2><p>圣诞树共有 $n$ 层，从上向下数第 $1$ 层有 $1$ 个星星、第 $2$ 层有 $2$ 个星星、以此类推，排列成下图所示的形状。</p><p><img src="https://cdn.luogu.com.cn/upload/image_hosting/gnp9d7er.png" alt=""></p><p>星星和星星之间用绳子连接。第 $1,2,\cdots, n - 1$ 层的每个星星都向下一层最近的两个星星连一段绳子，最后一层的相邻星星之间连一段绳子。</p><p>你能算出如果要布置一棵很大（$n$ 层）的圣诞树，需要买多少段绳子吗？</p><h2 id="输入格式-3">输入格式</h2><p>输入一行一个整数 $n$，圣诞树的层数。</p><h2 id="输出格式-3">输出格式</h2><p>输出一行一个整数，代表圣诞树中绳子的段数。</p><h2 id="输入输出样例-1-3">输入输出样例 #1</h2><h3 id="输入-1-3">输入 #1</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2</span><br></pre></td></tr></table></figure><h3 id="输出-1-3">输出 #1</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3</span><br></pre></td></tr></table></figure><h2 id="输入输出样例-2-2">输入输出样例 #2</h2><h3 id="输入-2-2">输入 #2</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">4</span><br></pre></td></tr></table></figure><h3 id="输出-2-2">输出 #2</h3><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">15</span><br></pre></td></tr></table></figure><h2 id="说明-提示-2">说明/提示</h2><h3 id="样例解释">样例解释</h3><h4 id="样例-1">样例 $1$</h4><p>$2$ 层的圣诞树只需 $3$ 段绳⼦。</p><h4 id="样例-2">样例 $2$</h4><p>参考题图。</p><h3 id="数据规模">数据规模</h3><p>所有数据满足 $1 ≤ n ≤ 10^3$。</p><blockquote><p>本题原始满分为 $15\text{pts}$。</p></blockquote><h2 id="解题思路-3">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    cout &lt;&lt; n * n - <span class="number">1</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>4. P5726 【深基4.习9】打分</h1><h2 id="题目描述-4">题目描述</h2><p>现在有 $n(n \le 1000)$ 位评委给选手打分，分值从 $0$ 到 $10$。需要去掉一个最高分，去掉一个最低分（如果有多个最高或者最低分，也只需要去掉一个），剩下的评分的平均数就是这位选手的得分。现在输入评委人数和他们的打分，请输出选手的最后得分，精确到 $2$ 位小数。</p><h2 id="输入格式-4">输入格式</h2><p>第一行输入一个正整数 $n$，表示有 $n$ 个评委。</p><p>第二行输入 $n$ 个正整数，第 $i$ 个正整数表示第 $i$ 个评委打出的分值。</p><h2 id="输出格式-4">输出格式</h2><p>输出一行一个两位小数，表示选手的最后得分。</p><h2 id="输入输出样例-1-4">输入输出样例 #1</h2><h3 id="输入-1-4">输入 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">5</span></span><br><span class="line"><span class="symbol">9 </span><span class="number">5</span> <span class="number">6</span> <span class="number">8</span> <span class="number">9</span></span><br></pre></td></tr></table></figure><h3 id="输出-1-4">输出 #1</h3><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">7</span>.<span class="number">67</span></span><br></pre></td></tr></table></figure><h2 id="说明-提示-3">说明/提示</h2><p>数据保证，$3 \leq n \leq 1000$，每个评委打出的分值为为 $0$ 到 $10$（含 $0$ 与 $10$）之间的整数。</p><h2 id="解题思路-4">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">double</span>&gt; <span class="title">s</span><span class="params">(n)</span></span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span>&amp; i : s) cin &gt;&gt; i;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">sort</span>(s.<span class="built_in">begin</span>(), s.<span class="built_in">end</span>());</span><br><span class="line">    <span class="type">double</span> sum = <span class="built_in">accumulate</span>(s.<span class="built_in">begin</span>() + <span class="number">1</span>, s.<span class="built_in">end</span>() - <span class="number">1</span>, <span class="number">0.0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%.2f&quot;</span>, sum / (n - <span class="number">2</span>));</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1>5. B2124 判断字符串是否为回文</h1><h2 id="题目描述-5">题目描述</h2><p>输入一个字符串，输出该字符串是否回文。回文是指顺读和倒读都一样的字符串。</p><h2 id="输入格式-5">输入格式</h2><p>输入一行字符串，长度小于 $100$。</p><h2 id="输出格式-5">输出格式</h2><p>如果字符串是回文，输出 <code>yes</code>；否则，输出 <code>no</code>。</p><h2 id="输入输出样例-1-5">输入输出样例 #1</h2><h3 id="输入-1-5">输入 #1</h3><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">abcdedcba</span></span><br></pre></td></tr></table></figure><h3 id="输出-1-5">输出 #1</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">yes</span></span><br></pre></td></tr></table></figure><h2 id="解题思路-5">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">isHuiwen</span><span class="params">(string s)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n = s.<span class="built_in">length</span>();</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n / <span class="number">2</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (s[i] != s[n - <span class="number">1</span> - i]) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    string s;</span><br><span class="line">    cin &gt;&gt; s;</span><br><span class="line">    cout &lt;&lt; (<span class="built_in">isHuiwen</span>(s) ? <span class="string">&quot;yes&quot;</span> : <span class="string">&quot;no&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>6. P4414 [COCI 2006/2007 #2] ABC</h1><h2 id="题目描述-6">题目描述</h2><p>三个整数分别为 $A,B,C$。这三个数字不会按照这样的顺序给你，但它们始终满足条件：$A &lt; B &lt; C$。为了看起来更加简洁明了，我们希望你可以按照给定的顺序重新排列它们。</p><h2 id="输入格式-6">输入格式</h2><p>第一行包含三个正整数 $A,B,C$，不一定是按这个顺序。这三个数字都小于或等于 $100$。第二行包含三个大写字母 $A$、$B$ 和 $C$（它们之间<strong>没有</strong>空格）表示所需的顺序。</p><h2 id="输出格式-6">输出格式</h2><p>在一行中输出 $A$，$B$ 和 $C$，用一个 <code> </code>（空格）隔开。</p><p>感谢 @smartzzh 提供的翻译</p><h2 id="输入输出样例-1-6">输入输出样例 #1</h2><h3 id="输入-1-6">输入 #1</h3><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">1</span> <span class="number">5</span> <span class="number">3</span></span><br><span class="line"><span class="attribute">ABC</span></span><br></pre></td></tr></table></figure><h3 id="输出-1-6">输出 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">1 </span><span class="number">3</span> <span class="number">5</span></span><br></pre></td></tr></table></figure><h2 id="输入输出样例-2-3">输入输出样例 #2</h2><h3 id="输入-2-3">输入 #2</h3><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">6</span> <span class="number">4</span> <span class="number">2</span></span><br><span class="line"><span class="attribute">CAB</span></span><br></pre></td></tr></table></figure><h3 id="输出-2-3">输出 #2</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">6 </span><span class="number">2</span> <span class="number">4</span></span><br></pre></td></tr></table></figure><h2 id="解题思路-6">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> a[<span class="number">3</span>];</span><br><span class="line"><span class="type">char</span> X, Y, Z;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; a[<span class="number">0</span>] &gt;&gt; a[<span class="number">1</span>] &gt;&gt; a[<span class="number">2</span>];</span><br><span class="line">    cin &gt;&gt; X &gt;&gt; Y &gt;&gt; Z;</span><br><span class="line">    <span class="built_in">sort</span>(a, a + <span class="number">3</span>);</span><br><span class="line">    cout &lt;&lt; a[X - <span class="string">&#x27;A&#x27;</span>] &lt;&lt; <span class="string">&quot; &quot;</span> &lt;&lt; a[Y - <span class="string">&#x27;A&#x27;</span>] &lt;&lt; <span class="string">&quot; &quot;</span> &lt;&lt; a[Z - <span class="string">&#x27;A&#x27;</span>];</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>7. P1012 [NOIP 1998 提高组] 拼数</h1><h2 id="题目描述-7">题目描述</h2><p>设有 $n$ 个正整数 $a_1 \dots a_n$，将它们联接成一排，相邻数字首尾相接，组成一个最大的整数。</p><h2 id="输入格式-7">输入格式</h2><p>第一行有一个整数，表示数字个数 $n$。</p><p>第二行有 $n$ 个整数，表示给出的 $n$ 个整数 $a_i$。</p><h2 id="输出格式-7">输出格式</h2><p>一个正整数，表示最大的整数</p><h2 id="输入输出样例-1-7">输入输出样例 #1</h2><h3 id="输入-1-7">输入 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">3</span></span><br><span class="line"><span class="symbol">13 </span><span class="number">312</span> <span class="number">343</span></span><br></pre></td></tr></table></figure><h3 id="输出-1-7">输出 #1</h3><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">34331213</span></span><br></pre></td></tr></table></figure><h2 id="输入输出样例-2-4">输入输出样例 #2</h2><h3 id="输入-2-4">输入 #2</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">4</span></span><br><span class="line"><span class="symbol">7 </span><span class="number">13</span> <span class="number">4</span> <span class="number">246</span></span><br></pre></td></tr></table></figure><h3 id="输出-2-4">输出 #2</h3><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">7424613</span></span><br></pre></td></tr></table></figure><h2 id="说明-提示-4">说明/提示</h2><p>对于全部的测试点，保证 $1 \leq n \leq 20$，$1 \leq a_i \leq 10^9$。</p><p>NOIP1998 提高组 第二题</p><h2 id="解题思路-7">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="function">vector&lt;string&gt; <span class="title">nums</span><span class="params">(n)</span></span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span>&amp; i : nums) cin &gt;&gt; i;</span><br><span class="line">    <span class="built_in">sort</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">end</span>(), [](<span class="type">const</span> string&amp; a, <span class="type">const</span> string&amp; b) &#123;</span><br><span class="line">        <span class="keyword">return</span> a + b &gt; b + a;</span><br><span class="line">        &#125;);</span><br><span class="line">    string res = <span class="built_in">accumulate</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">end</span>(), <span class="built_in">string</span>());</span><br><span class="line">    cout &lt;&lt; (res.<span class="built_in">empty</span>() || res[<span class="number">0</span>] == <span class="string">&#x27;0&#x27;</span> ? <span class="string">&quot;0&quot;</span> : res) &lt;&lt; endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>8. B2143 进制转换</h1><h2 id="题目描述-8">题目描述</h2><p>用递归算法将一个十进制整数 $X$（$1 \le X \le 10^9$）转换成任意进制数 $M$（$2\le M\le16$，$M$ 为整数）。</p><h2 id="输入格式-8">输入格式</h2><p>一行两个数，第一个十进制整数 $X$，第二个为进制 $M$。</p><h2 id="输出格式-8">输出格式</h2><p>输出结果。</p><h2 id="输入输出样例-1-8">输入输出样例 #1</h2><h3 id="输入-1-8">输入 #1</h3><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">31 </span><span class="number">16</span></span><br></pre></td></tr></table></figure><h3 id="输出-1-8">输出 #1</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span><span class="built_in">F</span></span><br></pre></td></tr></table></figure><h2 id="说明-提示-5">说明/提示</h2><p><strong>样例解释</strong>。</p><p>将十进制 $31$ 转化为十六进制数。</p><h2 id="解题思路-8">解题思路</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (n == <span class="number">0</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="built_in">dfs</span>(n / m, m);</span><br><span class="line">    <span class="type">int</span> r = n % m;</span><br><span class="line">    <span class="type">char</span> c;</span><br><span class="line">    <span class="keyword">if</span> (r &lt; <span class="number">10</span>) &#123;</span><br><span class="line">        c = <span class="string">&#x27;0&#x27;</span> + r;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        c = <span class="string">&#x27;A&#x27;</span> + (r - <span class="number">10</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; c;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> X, M;</span><br><span class="line">    cin &gt;&gt; X &gt;&gt; M;</span><br><span class="line">    <span class="keyword">if</span> (X == <span class="number">0</span>) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;0&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(X, M);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1>致谢</h1><div class="note default flat"><p>感谢活动平台支持：<a href="https://www.luogu.com.cn/">洛谷</a></p></div>]]></content>
    
    
    <summary type="html">编程竞逐赛活动说明及赛后题解</summary>
    
    
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/categories/%E7%AE%97%E6%B3%95/"/>
    
    
    <category term="C++" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="程序设计" scheme="https://home.y1xuanyun.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
    
    <category term="数据结构" scheme="https://home.y1xuanyun.cn/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    
    <category term="语法" scheme="https://home.y1xuanyun.cn/tags/%E8%AF%AD%E6%B3%95/"/>
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="笔记" scheme="https://home.y1xuanyun.cn/tags/%E7%AC%94%E8%AE%B0/"/>
    
    <category term="题解" scheme="https://home.y1xuanyun.cn/tags/%E9%A2%98%E8%A7%A3/"/>
    
    <category term="校赛" scheme="https://home.y1xuanyun.cn/tags/%E6%A0%A1%E8%B5%9B/"/>
    
  </entry>
  
  <entry>
    <title>从快速启动机制到系统修复指南</title>
    <link href="https://home.y1xuanyun.cn/posts/25pc01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25pc01.html</id>
    <published>2025-03-06T03:00:00.000Z</published>
    <updated>2025-04-15T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>前置知识</h1><p>在深入探讨特定问题之前，我们有必要先了解一些核心概念。当按下电脑的开机键后，到屏幕上出现Windows徽标，这期间发生的过程远比想象中复杂。</p><h2 id="什么是BIOS-UEFI？">什么是BIOS/UEFI？</h2><p><strong>BIOS</strong>（Basic Input/Output System，基本输入输出系统）和其现代继任者 <strong>UEFI</strong>（Unified Extensible Firmware Interface，统一可扩展固件接口）是固化在主板芯片上的一套核心程序。您可以将其理解为计算机的“潜意识”或“本能”——它在操作系统醒来之前全权负责管理硬件。</p><ul><li><strong>核心职责</strong>：<ol><li><strong>开机自检（POST）</strong>：启动时检查CPU、内存、硬盘、显卡等关键硬件是否正常工作。</li><li><strong>硬件初始化与驱动</strong>：激活基础硬件，为加载操作系统做好准备。</li><li><strong>引导加载</strong>：按照预设的启动顺序（Boot Order）从硬盘、U盘或网络等设备上寻找并加载操作系统的引导程序。</li><li><strong>系统设置</strong>：提供一个设置界面（就是我们常说的“进BIOS”），允许用户配置硬件参数、开关虚拟化技术、调整启动顺序等。</li></ol></li></ul><p>当您遇到开机自动进入BIOS界面，且大部分选项呈<strong>灰色不可编辑状态</strong>时，这通常是BIOS/UEFI的一种保护机制。它通常在检测到严重的不确定性或硬件问题时启动，锁定高级设置以防止用户在不稳定的环境下进行错误配置，从而避免进一步的问题。</p><h2 id="Windows的启动之旅与“安全模式”">Windows的启动之旅与“安全模式”</h2><p>操作系统启动是一个层层递进的过程，我们遇到的问题就发生在这个链条的早期。</p><ol><li><strong>固件阶段</strong>：BIOS/UEFI初始化硬件并找到<strong>引导程序</strong>。</li><li><strong>引导阶段</strong>：引导程序（如Windows Boot Manager）读取<strong>BCD（启动配置数据）</strong> 存储，并准备加载操作系统内核。</li><li><strong>内核加载</strong>：加载操作系统核心文件（如<code>ntoskrnl.exe</code>）和必需的驱动程序。</li><li><strong>用户登录</strong>：加载用户界面，等待登录。</li></ol><p>在这个过程中，如果系统文件损坏、驱动程序冲突或软件不兼容，就可能导致启动失败（蓝屏、卡死等）。此时，就需要我们的救星——<strong>安全模式</strong>。</p><ul><li><p><strong>安全模式（Safe Mode）是什么？</strong><br>它是Windows的一个<strong>最小化故障诊断启动状态</strong>。在此模式下，系统仅加载最核心的驱动和系统服务，屏蔽所有第三方软件和大部分驱动。这就像给系统做了一次“肠胃清理”，如果一个问题在安全模式下不再出现，那么基本可以断定是第三方软件或驱动造成的。</p></li><li><p><strong>如何进入安全模式？</strong><br>在Windows 10/11中，有多种方法，最常用的是：</p><ol><li>在系统设置 -&gt; 恢复 -&gt; 高级启动中，选择“立即重新启动”。</li><li>在开机过程中（看到旋转的圆点前）强制关机2-3次，系统会自动进入恢复环境（WinRE）。</li><li>在恢复环境中，选择 <strong>“疑难解答” -&gt; “高级选项” -&gt; “启动设置” -&gt; “重启”</strong>，然后按 <code>F4</code> 或 <code>4</code> 键即可进入安全模式。</li></ol></li></ul><p>了解这些背景后，我们再回来看您遇到的具体问题，就会豁然开朗。</p><hr><h1>问题深度解析</h1><p><strong>问题的现象</strong>：<br>笔记本电脑开机后自动进入BIOS设置界面，且界面内大部分配置选项呈灰色不可编辑状态。该问题的触发极具规律性：</p><ul><li><strong>强制关机（如长按电源键关机）后，下次开机必现。</strong></li><li><strong>正常关机或重启后，下次开机一切正常。</strong></li></ul><p><img src="%5B%E5%9B%BE%E7%89%87%E9%93%BE%E6%8E%A5%5D" alt="BIOS启动界面截图"><br><em>图：AMI Aptio BIOS 启动设置界面，注意<code>Fast Boot</code>为启用状态。若出现问题，该界面选项会大量灰化。</em></p><h2 id="根本原因：两种“快速启动”的机制冲突">根本原因：两种“快速启动”的机制冲突</h2><p>此问题并非由硬件物理损坏引起，而是与 <strong>Windows操作系统</strong> 和 <strong>BIOS/UEFI固件</strong> 的两种“快速启动”功能之间的交互机制冲突有关。</p><ol><li><p><strong>Windows快速启动（Fast Startup）</strong>: 为提升用户体验，Windows默认启用了“快速启动”功能。在用户执行“关机”操作时，Windows并非完全关闭系统，而是将系统内核和驱动程序的状态保存到硬盘的休眠文件（<code>hiberfil.sys</code>）中，然后切断电源。下次开机时，系统会从休眠状态快速加载，跳过多项硬件自检和系统引导步骤，从而实现“秒开”。</p></li><li><p><strong>BIOS快速启动（Fast Boot）</strong>: 在现代计算机的BIOS/UEFI设置中，通常也提供一个 <code>Fast Boot</code> 选项。其作用是让BIOS跳过部分详细的硬件自检（POST）过程，进一步加快启动速度。此功能依赖于硬件在上次关机时处于一个稳定且可预测的状态。</p></li><li><p><strong>冲突链条的形成</strong>:</p><ul><li><strong>触发点</strong>：当用户执行 <strong>强制关机</strong>（或“按住Shift键关机”）时，此操作会<strong>绕过Windows的快速启动机制</strong>，执行一次彻底的、完全的关机。这会清空之前的休眠状态，并使硬件（特别是NVMe固态硬盘）恢复到完全的“冷启动”状态。</li><li><strong>问题产生</strong>：在彻底关机后，硬盘需要完整的初始化时间。然而，下次开机时，BIOS的 <code>Fast Boot</code> 功能已被启用，它期望硬件能极快地响应就绪。</li><li><strong>判断超时</strong>：如果硬盘的冷启动初始化时间<strong>略微超过了BIOS <code>Fast Boot</code> 模式下的等待时限</strong>，BIOS便无法在预期时间内检测到启动设备（硬盘）。</li><li><strong>保护性措施</strong>：一旦BIOS判定启动设备丢失，作为一种保护性措施，它会<strong>自动启动并进入设置界面</strong>，同时将大部分可能影响硬件稳定性的选项<strong>灰化</strong>，以防止用户在不确定的硬件状态下进行错误配置。</li></ul></li></ol><p><strong>简而言之</strong>：<strong>强制完全关机 → 硬件状态重置 + BIOS快速启动 → 硬盘初始化超时 → BIOS启动失败并进入保护模式（界面灰化）。</strong></p><p>而正常关机或重启利用了Windows的快速启动，硬盘始终处于“热”状态，响应迅速，故不会触发此问题。这完美解释了问题出现的规律性。</p><hr><h1>解决方案与扩展排查</h1><p>以下是针对此问题的两种核心解决方案，推荐从方案一开始尝试。</p><h2 id="方案一：禁用Windows的“快速启动”（推荐）">方案一：禁用Windows的“快速启动”（推荐）</h2><p>此方案一劳永逸，通过让Windows每次都执行完全关机，确保硬件状态的一致性，从根本上避免冲突。</p><ol><li>正常启动进入Windows操作系统。</li><li>打开 <strong>控制面板</strong> &gt; <strong>电源选项</strong>。</li><li>点击左侧的 <strong>“选择电源按钮的功能”</strong>。</li><li>点击页面上方的 <strong>“更改当前不可用的设置”</strong>。</li><li>在下方的“关机设置”区域中，<strong>取消勾选 “启用快速启动（推荐）”</strong>。</li><li>点击 <strong>“保存修改”</strong>。</li></ol><p><strong>完成此设置后</strong>，无论以何种方式关机，下次启动时系统都会进行完整的硬件初始化，BIOS有充足的时间检测到所有设备，从而避免该问题。</p><h2 id="方案二：禁用BIOS中的“Fast-Boot”选项">方案二：禁用BIOS中的“Fast Boot”选项</h2><p>此方案允许保留Windows的快速启动，但让BIOS进行更全面的自检，给予硬件更长的等待时间。</p><ol><li>开机并进入BIOS设置界面（方法通常为在开机Logo出现时按 <code>Del</code>, <code>F2</code>, <code>F10</code> 等特定键）。</li><li>使用键盘方向键切换到 <strong><code>Boot</code></strong> 选项卡。</li><li>找到 <strong><code>Fast Boot</code></strong> 配置项。</li><li>按下 <strong><code>Enter</code></strong> 键或 <strong><code>+/-</code></strong> 键将其设置从 <strong><code>Enabled</code></strong> 更改为 <strong><code>Disabled</code></strong>。</li><li>按下 <strong><code>F10</code></strong> 键（或根据屏幕底部提示的保存键），选择“Yes”保存设置并退出。</li></ol><h1>扩展思考</h1><p>如果按照上述方案操作后问题仍然出现，则需将排查范围扩大，考虑硬件本身的可能性。</p><ol><li><strong>检查硬盘连接</strong>：打开笔记本后盖，重新插拔NVMe SSD或SATA硬盘，清理金手指，确保连接稳固。</li><li><strong>更新固件</strong>：<ul><li><strong>更新BIOS/UEFI</strong>：前往笔记本制造商官网，下载并安装最新版本的BIOS，这可能修复了与特定硬盘的兼容性问题。</li><li><strong>更新硬盘固件</strong>：访问硬盘制造商（如三星、西数、铠侠）官网，查看是否有针对您硬盘型号的固件更新。</li></ul></li><li><strong>运行硬件诊断</strong>：大多数品牌笔记本（如Dell, HP, Lenovo）都内置了硬件诊断工具（开机时按特定功能键进入），可以运行对硬盘的全面检测。</li><li><strong>进入安全模式或PE系统</strong>：如果能进入<strong>安全模式</strong>或通过U盘启动进入<strong>Windows PE</strong>系统，则说明主板和硬盘基本正常，问题可能出在系统引导或驱动层面，可以进行系统修复或重置。</li></ol><h1>总结</h1><p>开机自动进入BIOS且选项灰化的问题，是一个典型的由软件（操作系统）与固件（BIOS/UEFI）电源管理机制冲突导致的“软”故障。其规律性的触发条件（强制关机触发，正常启动无事）是判断的关键依据。</p><ul><li><strong>核心原因</strong>：强制关机与BIOS快速启动模式结合，导致硬盘初始化超时。</li><li><strong>首选解决方案</strong>：禁用Windows的“快速启动”功能，从根本上确保每次关机的彻底性。</li><li><strong>知识延伸</strong>：理解BIOS/UEFI的作用、Windows启动流程以及安全模式等概念，有助于我们形成网状的知识体系，在面对各种启动类故障时都能保持清晰的排查思路。</li></ul><h1>补充 命令提示符进入BIOS</h1><p>在Windows操作系统中按下<kbd>win</kbd>+<kbd>R</kbd>即可调出运行<br>键入<code>shutdown</code>，具体参数如下：<br><strong>/r</strong>：重启<br><strong>/fw</strong>：下次启动转到固件页面<br><strong>/t 0</strong>：0秒后执行</p><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">shutdown</span> <span class="string">/r</span> <span class="string">/fw</span> <span class="string">/t</span> 0</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">开机自动进入BIOS且选项灰化的深度解析</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="Windows" scheme="https://home.y1xuanyun.cn/tags/Windows/"/>
    
    <category term="操作系统" scheme="https://home.y1xuanyun.cn/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    
    <category term="BIOS" scheme="https://home.y1xuanyun.cn/tags/BIOS/"/>
    
    <category term="快速启动" scheme="https://home.y1xuanyun.cn/tags/%E5%BF%AB%E9%80%9F%E5%90%AF%E5%8A%A8/"/>
    
    <category term="安全模式" scheme="https://home.y1xuanyun.cn/tags/%E5%AE%89%E5%85%A8%E6%A8%A1%E5%BC%8F/"/>
    
  </entry>
  
  <entry>
    <title>那些Unity中名不见经传的包</title>
    <link href="https://home.y1xuanyun.cn/posts/25u3d01.html"/>
    <id>https://home.y1xuanyun.cn/posts/25u3d01.html</id>
    <published>2025-02-01T03:00:00.000Z</published>
    <updated>2025-09-01T09:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-blue"  style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><p>该文章长期更新</p></div></div><p>在使用 Unity 进行项目开发时，除了软件自带的标准包，我们常常需要借助一些更专业的第三方包来提升开发效率、实现特定功能或优化工作流。Unity 的 Package Manager 虽然强大，但有些官方验证（Verified）或第三方（Third-party）的包并不会直接显示在列表中，需要我们知道正确的名称或 URL 才能导入。</p><p>本文将介绍几个在开发中极其常用，但需要一些&quot;特殊技巧&quot;才能导入的包，并详细说明它们的作用、解决的问题以及导入方法。</p><hr><h1>1. Newtonsoft.Json (<a href="http://Json.NET">Json.NET</a>)</h1><p>Newtonsoft.Json，也被称为 <a href="http://Json.NET">Json.NET</a>，是 .NET 生态中事实上的 JSON 标准库。它比 Unity 自带的 <code>JsonUtility</code> 功能更强大、更灵活。</p><h2 id="应用与解决的问题">应用与解决的问题</h2><ul><li><strong>功能强大</strong>：支持序列化和反序列化复杂对象（如字典、多态类、私有字段等），而 <code>JsonUtility</code> 在这方面限制很多。</li><li><strong>高度可定制</strong>：提供了大量的属性（如 <code>[JsonProperty]</code>） 和设置来精确控制 JSON 的输入和输出格式。</li><li><strong>性能优异</strong>：在大多数场景下，其性能都优于 Unity 内置的解决方案。</li></ul><p><strong>它能解决什么问题？</strong><br>当你需要与 Web API 交互、读取复杂的配置文件、保存包含丰富数据结构的游戏存档时，<code>JsonUtility</code> 往往会力不从心，而 <a href="http://Json.NET">Json.NET</a> 则是你的不二之选。</p><h2 id="如何导入">如何导入</h2><p>这个包需要通过 <strong>Git URL</strong> 的方式导入。</p><ol><li>打开 Unity，导航到 <code>Window &gt; Package Manager</code>。</li><li>点击左上角的 <strong>“+”</strong> 按钮，选择 <strong>“Add package from git URL…”</strong>。</li><li>在弹出的输入框中，填入以下 URL：<br><code>https://github.com/jilleJr/Newtonsoft.Json-for-Unity.git#upm</code></li><li>点击 <strong>“Add”</strong>。Unity 便会开始从该 Git 仓库下载并安装包。</li></ol><blockquote><p><strong>注意</strong>：请务必使用上述专门的 <code>Newtonsoft.Json-for-Unity</code> 仓库，而不是官方源。这个版本解决了 Unity 与 .NET Standard / .NET Framework 的兼容性问题。</p></blockquote><hr><h1>2. Cinemachine</h1><p>Cinemachine 是一套基于组件的相机系统，堪称 <strong>“智能相机工具包”</strong>。它现在虽然是官方包，但在旧版或某些项目设置中可能需要手动添加。</p><h2 id="应用与解决的问题-2">应用与解决的问题</h2><ul><li><strong>无需编码</strong>：通过组合各种虚拟相机（Virtual Camera）和扩展组件，可以创造出复杂、影院级的相机运动效果，而无需编写复杂的相机控制代码。</li><li><strong>智能切换</strong>：可以在多个虚拟相机之间实现平滑、无感的过渡（例如，从跟随相机切换到过场动画相机）。</li><li><strong>高级功能</strong>：内置噪声模拟、镜头抖动、作曲规则（Rule-based Composing）等功能。</li></ul><p><strong>它能解决什么问题？</strong><br>手动编写相机逻辑非常繁琐且难以维护。Cinemachine 完美解决了相机跟踪、视角切换、镜头抖动等常见需求，让开发者能专注于游戏设计本身。</p><h2 id="如何导入-2">如何导入</h2><p>Cinemachine 是官方验证包，可以直接在 Package Manager 中找到。</p><ol><li>打开 <code>Window &gt; Package Manager</code>。</li><li>点击左上角的 <strong>“+”</strong> 按钮，选择 <strong>“Add package by name…”</strong>。</li><li>在输入框中输入 <code>com.unity.cinemachine</code>，然后点击 <strong>“Add”</strong>。</li><li>或者，在包管理器窗口顶部，将 <strong>“Packages: Unity Registry”</strong> 切换到 <strong>“Packages: Unity Registry”</strong>，然后在列表中找到 <strong>Cinemachine</strong> 并点击安装。</li></ol><hr><h1>3. GLTFast</h1><p><code>com.unity.cloud.gltfast</code> 是一个用于在 Unity 中<strong>高速导入和导出 glTF 3D 模型</strong>的包。glTF 是一种日益流行的开放标准3D模型格式（被称为&quot;3D 界的 JPEG&quot;）。</p><h2 id="应用与解决的问题-3">应用与解决的问题</h2><ul><li><strong>极速加载</strong>：相较于 Unity 传统的 <code>.fbx</code> 导入方式，GLTFast 专注于运行时和编辑器下的高效 glTF 文件加载，速度更快。</li><li><strong>格式开放</strong>：完美支持 <code>.gltf</code> 和 <code>.glb</code> 文件，适合需要动态下载和显示3D模型的在线应用、AR/VR 项目。</li><li><strong>功能完整</strong>：支持基于 Draco 压缩的模型、材质、动画等。</li></ul><p><strong>它能解决什么问题？</strong><br>当你需要从网络动态加载 3D 模型，或者你的美术流水线主要使用 glTF 格式时，使用这个包可以避免繁琐的格式转换，并实现更高效的运行时加载。</p><h2 id="如何导入-3">如何导入</h2><p>这是一个官方发布的包，可以通过名称导入。</p><ol><li>打开 <code>Window &gt; Package Manager</code>。</li><li>点击左上角的 <strong>“+”</strong> 按钮，选择 <strong>“Add package by name…”</strong>。</li><li>在输入框中输入 <code>com.unity.cloud.gltfast</code>，然后点击 <strong>“Add”</strong>。</li></ol><hr><h1>4. (Bonus) ParrelSync</h1><p>虽然不完全是&quot;包&quot;，但它是一个必须通过 Git URL 安装的神器。<strong>ParrelSync</strong> 是一个用于实现<strong>同一项目多开</strong>的工具，主要用于模拟多人联机测试。</p><h2 id="应用与解决的问题-4">应用与解决的问题</h2><ul><li><strong>本地多人测试</strong>：无需构建项目，即可在编辑器中同时打开多个项目副本，模拟客户端-服务器或多玩家环境。</li><li><strong>提升测试效率</strong>：极大简化了需要网络同步功能的游戏的测试流程。</li></ul><h2 id="如何导入-4">如何导入</h2><p>同样通过 Git URL 安装。</p><ol><li>打开 <code>Window &gt; Package Manager</code>。</li><li>点击左上角的 <strong>“+”</strong> 按钮，选择 <strong>“Add package from git URL…”</strong>。</li><li>输入以下 URL：<br><code>https://github.com/VeriorPies/ParrelSync.git#upm</code></li><li>点击 <strong>“Add”</strong>。安装成功后，你可以在菜单栏 <code>Tools &gt; ParrelSync</code> 中找到它。</li></ol><hr><h1>总结</h1><p>熟练掌握 Package Manager 的多种导入方式是成为一名高效 Unity 开发者的必备技能。</p><table><thead><tr><th style="text-align:left">包名</th><th style="text-align:left">用途</th><th style="text-align:left">导入方式</th></tr></thead><tbody><tr><td style="text-align:left"><strong>Newtonsoft.Json</strong></td><td style="text-align:left">强大的 JSON 序列化/反序列化</td><td style="text-align:left">Git URL</td></tr><tr><td style="text-align:left"><strong>Cinemachine</strong></td><td style="text-align:left">智能相机系统</td><td style="text-align:left">按名称添加 (<code>com.unity.cinemachine</code>)</td></tr><tr><td style="text-align:left"><strong>GLTFast</strong></td><td style="text-align:left">高速导入/导出 glTF 模型</td><td style="text-align:left">按名称添加 (<code>com.unity.cloud.gltfast</code>)</td></tr><tr><td style="text-align:left"><strong>ParrelSync</strong></td><td style="text-align:left">项目多开以进行本地联机测试</td><td style="text-align:left">Git URL</td></tr></tbody></table><p>希望这些工具能帮助你更高效地开发下一个 Unity 项目！</p>]]></content>
    
    
    <summary type="html">收集汇总了unity中必装但需要手动配置的强大工具</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="Unity" scheme="https://home.y1xuanyun.cn/tags/Unity/"/>
    
    <category term="3D" scheme="https://home.y1xuanyun.cn/tags/3D/"/>
    
    <category term="模型" scheme="https://home.y1xuanyun.cn/tags/%E6%A8%A1%E5%9E%8B/"/>
    
    <category term="导包" scheme="https://home.y1xuanyun.cn/tags/%E5%AF%BC%E5%8C%85/"/>
    
    <category term="汇总" scheme="https://home.y1xuanyun.cn/tags/%E6%B1%87%E6%80%BB/"/>
    
  </entry>
  
  <entry>
    <title>Java环境配置与基础题解分析</title>
    <link href="https://home.y1xuanyun.cn/posts/24java01.html"/>
    <id>https://home.y1xuanyun.cn/posts/24java01.html</id>
    <published>2024-09-10T10:00:00.000Z</published>
    <updated>2024-09-24T02:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>前言</h1><div class="note info flat"><p>本篇适用于东油秦《面向对象程序设计》课程学习，教材已有知识点将不再过多解释</p></div><h1>开发环境</h1><p>对应教材第一章内容，部分定义已在教材中详细说明，不做详细解释说明。</p><h2 id="JDK-与-JRE">JDK 与 JRE</h2><p>对应教材 P30 习题 3✨</p><ul><li>JRE 是 Java 的运行环境。面向 Java 程序的使用者，而不是开发者。JRE 是运行 Java 程序所必须环境的集合，包含 JVM 标准实现及 Java 核心类库。它包括 Java 虚拟机、Java 平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。</li><li>JDK 是 Java 开发工具包，它提供了 Java 的开发环境(提供了编译器 等工具，用于将 java 文件编译为 class 文件)和运行环境(提 供了 JVM 和 Runtime 辅助包，用于解析 class 文件使其得到运行)。JDK 是整个 Java 的核心，包括了 Java 运行环境(JRE)，一堆 Java 工具 和 Java 标准类库。</li></ul><h2 id="官网下载安装-JDK">官网下载安装 JDK</h2><h3 id="甲骨文-Oracle-官网">甲骨文 Oracle 官网</h3><p>首先我们需要下载 java 开发工具包 JDK，在下载页面中根据自己的系统选择对应的版本，本文以<code> Windows 11 64位系统 JDK版本8</code>为例，其他版本如 JDK 21/17/11/8 的<code>长期支持版本</code>均可。</p><div class="note warning flat"><p>甲骨文官网下载会要求注册账号并登入，且部分路由节点对外网访问有限制，推荐移至文章尾部下载链接</p></div><div class="tag link"><a class="link-card" title="JDK官网下载页面" href="https://www.oracle.com/cn/java/technologies/downloads/"><div class="left"><img src="https://www.oracle.com/a/tech/img/rc10-java-badge-3.png"/></div><div class="right"><p class="text">JDK官网下载页面</p><p class="url">https://www.oracle.com/cn/java/technologies/downloads/</p></div></a></div><p>选择 JDK 版本并进行如下操作下载<br>选择 windows 系统 ➡️ 从上到下依次是<code>压缩包</code>、<code>.exe</code>、<code>.msi</code>格式的安装包 ➡️ 推荐后两者</p><div class="note info flat"><p>JDK 8 版本安装包无需考虑此问题</p></div><h3 id="msi-和-exe-安装包区别">.msi 和.exe 安装包区别</h3><ol><li>.msi 文件 适用于需要可靠的安装、维护和卸载功能的企业级应用，特别是在需要大规模部署的场景中。它提供了丰富的安装选项和维护功能，使得软件管理更加高效和可靠。</li><li>.exe 文件 则适用于自定义需求较多的安装过程，或者当需要捆绑多个安装程序时。它的灵活性和自定义能力使得它在某些特定场景下非常有用。<div class="img-wrap"><div class="img-bg"><img class="img" src="https://www.runoob.com/wp-content/uploads/2013/12/jdk-download.png"/></div></div></li></ol><h3 id="正式安装-JDK">正式安装 JDK</h3><ul><li>安装 JDK 过程中无特殊要求，点击下一步即可，可以自定义安装目录等信息，例如我们选择安装目录为 C:\Program Files (x86)\Java\jdk1.8.0_91 该路径需要保存以便后续写入环境变量</li></ul><h2 id="变量配置">变量配置</h2><h3 id="打开变量管理界面">打开变量管理界面</h3><p>右键<code>此电脑</code>➡️<code>属性</code>➡️<code>高级系统设置</code>➡️<code>环境变量</code></p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/1.png"/></div></div><h3 id="新建系统变量">新建系统变量</h3><p>1.<code>新建</code>➡️ 2.<code>变量名</code>➡️3.<code>变量值</code>➡️4.<code>确定</code></p><figure class="highlight delphi"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">变量名  JAVA_HOME</span><br><span class="line"><span class="comment">// 变量名需为JDK安装路径，以下为默认安装路径示例</span></span><br><span class="line">变量值  C:\<span class="keyword">Program</span> Files (x86)\Java\jdk1.<span class="number">8.0_91</span></span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/2.png"/></div></div><h3 id="新建环境变量">新建环境变量</h3><p>1.双击系统变量<code>Path</code>,或选中并点击下方<code>编辑</code></p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/3.png"/></div></div> 1.`新建`➡️ 2.填入以下固定格式 ➡️3.`确定`<figure class="highlight gcode"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">%</span>JAVA_HOME<span class="meta">%</span>\bi<span class="symbol">n</span></span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/4.png"/></div></div><h3 id="返回新建系统变量">返回新建系统变量</h3><p>1.<code>新建</code>➡️ 2.<code>变量名</code>、<code>变量值</code>均填写以下固定格式 ➡️3.<code>确定</code></p><figure class="highlight gcode"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">变量名  CLASSPATH</span><br><span class="line">变量值  .;<span class="meta">%</span>JAVA_HOME<span class="meta">%</span>\lib;</span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/5.png"/></div></div><h3 id="配置完成检验">配置完成检验</h3><kbd>win</kbd>+<kbd>R</kbd>调出运行<p>输入<code>cmd</code>➡️<code>确定</code>➡️ 进入命令提示符 ➡️ 输入以下指令回车验证版本</p><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -<span class="built_in">version</span></span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/6.png"/></div></div><div class="note success flat"><p>显示 JDK 安装版本即环境变量配置成功</p></div><h1>关于 IDE</h1><h2 id="IDE-的作用和特性">IDE 的作用和特性</h2><p>IDE（Integrated Development Environment）是一个集成开发环境，为开发者提供了包括代码编辑、编译、调试、测试在内的一站式服务。IntelliJ IDEA 作为一款流行的 Java IDE，具备智能代码补全、版本控制工具集成、代码重构等高级功能。<br>使用 IDE 可以大大提高开发效率，减少手动配置和环境搭建的时间，同时提供更为友好的用户界面和错误提示，帮助开发者更快地定位和解决问题。</p><h2 id="JDK-与-IDE-的依赖关系">JDK 与 IDE 的依赖关系</h2><p>虽然 IDE 提供了许多便捷的开发工具，但它本身并不包含 JDK。因此，在使用 IDE 如 IntelliJ IDEA 进行 Java 开发前，需要先安装并配置 JDK。在 IDE 中，可以通过设置来指定使用的 JDK 版本，确保项目能够在正确的环境中编译和运行。</p><h2 id="配置和使用">配置和使用</h2><p>安装 JDK 后，通常需要配置环境变量，如 JAVA_HOME，以便系统能够识别 JDK 的安装路径。<br>在 IDE 中，通过“Settings”或“Preferences”菜单，可以配置项目的 JDK 路径，选择已安装的 JDK 版本作为项目的编译和运行环境</p><h1>安装常用 IDE</h1><p>Eclipse 和 IntelliJ IDEA（简称 IDEA）是两种广泛使用的集成开发环境（IDE），它们在界面设计、代码编辑以及重构工具等方面存在区别。</p><h2 id="Eclipse">Eclipse</h2><p>Eclipse 的代码编辑器支持多种语言，如 Java、C++、Python 等，但其代码提示和自动补全功能略显不足，可能需要手动输入更多的代码。Eclipse 提供了一些基本的重构功能，但相对较少，可能无法满足一些高级重构需求。</p><h2 id="IDEA">IDEA</h2><p>IDEA 具有现代化和直观的用户界面设计，提供清晰的组织结构和菜单选项，使用户能够快速找到所需的功能。这种设计对于追求高效率的开发者来说是一个加分项。同时提供了丰富的重构工具，使代码重构变得更加方便和安全。这些工具包括重命名、提取方法、改变方法签名等常见操作，大大提高了开发效率。<br>IDEA 旗舰版为收费制软件，联系站长可获取破解工具（仅对 2023 版本及之前有效，推荐 2023.2），或前往官网获取社区版免费使用。</p><div class="note warning flat"><p>注意：破解仅用于学习交流，严禁商业用途</p></div><div class="btns wide rounded">            <a class="button" href='https://www.eclipse.org/downloads/packages/' title='Eclipse官网下载页面'><img src='https://www.eclipse.org/downloads/images/committers.png'>Eclipse官网下载页面</a><a class="button" href='https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2024-09/R/eclipse-java-2024-09-R-win32-x86_64.zip' title='Eclipse 2024.9 下载链接'><img src='https://www.eclipse.org/downloads/images/java.png'>Eclipse 2024.9 下载链接</a><a class="button" href='https://www.jetbrains.com/idea/download/?section=windows' title='IDEA 官网下载页面'><img src='https://tse4-mm.cn.bing.net/th/id/OIP-C.Xw8ijKwHW8yIYIU6GL3c_QAAAA?w=161&h=180&c=7&r=0&o=5&dpr=2&pid=1.7'>IDEA 官网下载页面</a><a class="button" href='https://download.jetbrains.com/idea/ideaIU-2023.2.exe?_gl=1*11ub9gj*_gcl_au*MTQ4NDM0NTUwMy4xNzI2MTQ1MjM1*_ga*NDM3NTY1OTQxLjE3MDA3ODgxODE.*_ga_9J976DJZ68*MTcyNjE0NTIzNy44LjEuMTcyNjE0NTQwMy4yMy4wLjA.' title='IDEA 2023.2 下载链接'><img src='https://pic60.mac89.com/mac69/ico/202208/19103723_00a36122bc.png'>IDEA 2023.2 下载链接</a>          </div><div class="note info flat"><p>Eclipse 和 IDEA 官网及其版本安装包下载链接如上，访问受限可移至文末进群下载。🎈🎈🎈</p></div><h1>项目创建与编译运行</h1><p>对应教材 P30 习题 4 和 5✨<br>需完成前置条件，即 JDK 安装与环境变量配置</p><h2 id="方式一：通过控制台命令程序">方式一：通过控制台命令程序</h2><p>1.<code>新建</code>.txt 文本文件 📄➡️ 2.<code>打开</code>输入以下代码 ➡️3.<code>保存</code>并关闭 ➡️4.修改后缀为<code>.java</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;  <span class="comment">//注意！文件名应与此处类名一致</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Hello World&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>1.<code>右键</code>所在文件夹 📄➡️ 2.<code>在终端中打开</code>➡️3.输入以下代码</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">javac Project.java  // 回车</span><br><span class="line">// 该命令用于将 java 源文件编译为 <span class="class"><span class="keyword">class</span> 字节码文件</span></span><br><span class="line"><span class="class"><span class="title">java</span> <span class="title">Project</span>   // 回车</span></span><br><span class="line"><span class="class">// <span class="title">java</span> 后面跟着的是<span class="title">java</span>文件中的类名,例如 <span class="title">Project</span> 就是类名</span></span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/c.png"/></div></div><div class="note success flat"><p>输出“ Hello World ”表示编译运行成功</p></div><h2 id="方式二：通过-Eclipse">方式二：通过 Eclipse</h2><p>见教材详解，不多做解释</p><div class="note info flat"><p>若未找到创建<code>Java project</code>选项，在<code>project</code>选项中选择<code>Java</code>即可。</p></div><h2 id="方式三：通过-IDEA">方式三：通过 IDEA</h2><p>1.选择<code>新建项目</code>📄➡️ 2.选择<code>空项目</code>➡️3.点击<code>创建</code></p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/i1.png"/></div></div> 1.右键`项目文件夹`📄➡️ 2.选择`新建`➡️3.点击`Java类`➡️4.输入类名确定，或连包带类创建<div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/i2.png"/></div></div> 1.输入`上文代码`📄➡️ 2.点击顶部`运行`➡️3.查看控制台输出<div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24xue01/i3.png"/></div></div><div class="note success flat"><p>输出“ Hello World ”表示编译运行成功</p></div><h1>程序获取</h1><div class="note info flat"><p>因多数官网服务器位于海外，下载受限可移步站长资源 QQ 群，不定时上传其他实用工具，欢迎学习交流。<a href="https://qm.qq.com/q/y3HWkaDGhi">点击前往</a></p></div><h1>课后习题题解分析</h1><div class="note warning flat"><p>代码推荐学习参考，本文已开放复制权限，但请弄懂每一行代码</p></div><h2 id="第二章-1-求圆球体积">第二章 1. 求圆球体积</h2><h3 id="题目">题目</h3><p>已知圆球体积公式为 V=4/3πr3，编写程序，设计一个求圆球体积的方法，并在主程序中调用它，求出当 r=3 时圆球的体积值。</p><h3 id="思路">思路</h3><blockquote><p>题目中涉及<code>π</code>和<code>4/3</code>，所以我们选择<code>double</code>浮点型处理带有小数的运算，并在<code>Math</code>类中调用相关数学方法，<code>Math.PI</code>表示<code>π</code>，<code>Math.pow(a, b)</code>用于处理幂函数<code>a的b次方</code>，再将计算返回值输出即可。</p></blockquote><h3 id="代码">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">double</span> <span class="variable">r</span> <span class="operator">=</span> <span class="number">3</span>;</span><br><span class="line">        <span class="type">double</span> <span class="variable">v</span> <span class="operator">=</span> fun_v(r);</span><br><span class="line">        System.out.println(<span class="string">&quot;当r=&quot;</span> + r + <span class="string">&quot;时，圆球的体积为：&quot;</span> + v);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">double</span> <span class="title function_">fun_v</span><span class="params">(<span class="type">double</span> r)</span> &#123;<span class="comment">//形参变量名可与实参变量名重复</span></span><br><span class="line">        <span class="keyword">return</span> (<span class="number">4.0</span> / <span class="number">3.0</span>) * Math.PI * Math.pow(r, <span class="number">3</span>);<span class="comment">//调用Math中的方法</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意">注意</h3><div class="note warning flat"><p>函数<code>fun_v</code>的返回值类型为浮点型，三分之四必须书写为<code>4.0/3.0</code></p></div><h2 id="第二章-2-棋盘麦粒问题">第二章 2. 棋盘麦粒问题</h2><h3 id="题目-2">题目</h3><p>曾有一位印度国王要奖赏他聪明能干的宰相达依尔。达依尔只要求在国际象棋的 64 个棋盘格上放置小麦粒，第一格放 1 粒，第二格放 2 粒，第三格放 4 粒，第四格放 8 粒……问最后一格需要放多少粒小麦粒呢？</p><h3 id="思路-2">思路</h3><blockquote><p>简洁的指数递增问题，可借助<code>Math.pow(a, b)</code>快速实现，不再多说，以下则利用<code>for循环</code>不断对当前格数的麦粒数目作自乘运算即可做出解答。</p></blockquote><h3 id="代码-2">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">double</span> <span class="variable">last</span> <span class="operator">=</span> <span class="number">1</span>; <span class="comment">//其他数据类型可能会产生溢出问题</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">63</span>; i++) &#123;<span class="comment">//第一格为1粒，相当于2的0次方</span></span><br><span class="line">            last *= <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;最后一格需要麦粒数量为：&quot;</span> + last);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意-2">注意</h3><div class="note warning flat"><p>虽然结果为整数，但不可选用长整型<code>long</code>,其范围为<code>-2^63~2^63-1</code>会产生溢出问题。</p></div><h2 id="第二章-3-水仙花数">第二章 3. 水仙花数</h2><h3 id="题目-3">题目</h3><p>打印出所有的&quot;水仙花数&quot;。“水仙花数&quot;是指一个 3 位数，其各位数字的立方和等干该数本身。例如，153 是一个&quot;水仙花数”，因为 153=1^3+5^3+3^3。</p><h3 id="思路-3">思路</h3><p>该题可先<code>遍历</code>100-1000 内的数，并将三位数分别提取，作 if 判断<code>枚举</code>输出匹配答案。</p><h3 id="代码-3">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">100</span>; i &lt; <span class="number">1000</span>; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> i / <span class="number">100</span>;        <span class="comment">//提取百分位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> (i % <span class="number">100</span>) / <span class="number">10</span>; <span class="comment">//提取十分位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">c</span> <span class="operator">=</span> i % <span class="number">10</span>;         <span class="comment">//提取个位数</span></span><br><span class="line">            <span class="keyword">if</span> (i == (Math.pow(a, <span class="number">3</span>) + Math.pow(b, <span class="number">3</span>) + Math.pow(c, <span class="number">3</span>))) &#123;</span><br><span class="line">                System.out.println(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意-3">注意</h3><div class="note warning flat"><p>弄清<code>%</code>取余符号的用法，不可与<code>/</code>作除符号弄混。</p></div><h2 id="第二章-4-分数序列之和">第二章 4. 分数序列之和</h2><h3 id="题目-4">题目</h3><p>有一分数序列：2/1,3/2,5/3,8/5,13/8,21/13,…，求出这个数列的前 20 项之和。</p><h3 id="思路-4">思路</h3><p>分析数学问题，找到规律是关键，序列以 2/1 开始，下一分子为前一分子与分母和，下一分母为前一分子，最后转换成编程语言即可。</p><h3 id="代码-4">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">double</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//总和</span></span><br><span class="line">        <span class="type">double</span> <span class="variable">s</span> <span class="operator">=</span> <span class="number">2</span>;   <span class="comment">//分子</span></span><br><span class="line">        <span class="type">double</span> <span class="variable">x</span> <span class="operator">=</span> <span class="number">1</span>;   <span class="comment">//分母</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">20</span>; i++) &#123;</span><br><span class="line">            sum += s / x;</span><br><span class="line">            s += x;</span><br><span class="line">            x = s - x;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;数列前20项和为：&quot;</span> + sum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意-4">注意</h3><div class="note warning flat"><p>循环中变量<code>x</code>引用的变量<code>s</code>已经完成累加，原数据已<code>被覆盖</code>，所以作<code>s-x</code>运算。</p></div><h2 id="第二章-5-打印菱形图案。">第二章 5. 打印菱形图案。</h2><h3 id="题目-5">题目</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">   *</span><br><span class="line">  ***</span><br><span class="line"> *****</span><br><span class="line">*******</span><br><span class="line"> *****</span><br><span class="line">  ***</span><br><span class="line">   *</span><br></pre></td></tr></table></figure><h3 id="思路-5">思路</h3><p>不考虑用 7 个<code>print</code>的方法输出，将菱形拆分为两个三角形状嵌套循环输出，外循环控制行数，内循环处理内容。</p><h3 id="代码-5">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">4</span>; <span class="comment">// 上半三角形行数</span></span><br><span class="line">        <span class="comment">// 上半三角形输出</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= n - i; j++) &#123;<span class="comment">//中轴线无空格</span></span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">1</span>; k &lt;= <span class="number">2</span> * i - <span class="number">1</span>; k++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();<span class="comment">//单行输出完成换行</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 下半三角形输出</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n - <span class="number">1</span>; i &gt;= <span class="number">1</span>; i--) &#123;<span class="comment">//反向循环，加变减</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= n - i; j++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">1</span>; k &lt;= <span class="number">2</span> * i - <span class="number">1</span>; k++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意-5">注意</h3><div class="note warning flat"><p>该题需分析清楚如何使用嵌套 for 循环。</p></div><h2 id="第二章-6-素数之和">第二章 6. 素数之和</h2><h3 id="题目-6">题目</h3><p>求出 100~200 之间的所有素数。</p><h3 id="思路-6">思路</h3><p>素数————在大于 1 的自然数中，除了 1 和它本身以外不再有其他因数的自然数。且范围 100~200，所以特殊情况<code>1</code>不考虑，站长在这道题采用的是循环<code>枚举</code>，调用<code>布尔类型方法</code>进行判断，输出符合条件结果。</p><h3 id="代码-6">代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Project</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">100</span>; i &lt;= <span class="number">200</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (fun_if(i)) &#123;<span class="comment">//调用方法作判断条件</span></span><br><span class="line">                System.out.println(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">fun_if</span><span class="params">(<span class="type">int</span> i)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">2</span>; j &lt;= Math.sqrt(i); j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i % j == <span class="number">0</span>) &#123;<span class="comment">//找到能被其他数整除</span></span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="注意-6">注意</h3><div class="note warning flat"><p>判断方法中<code>Math.sqrt(i)</code>为计算平方根，因为当被除数大于其平方根后，不肯能出现被整除情况，节省运算时间。</p></div><h1>实验课题解</h1><div class="note warning flat"><p>本篇只包含上节课02题目，复制需粘贴在类中，上机课03代码用记事本打开即可</p></div><h2 id="判断闰年">判断闰年</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//判断是否闰年方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isLeapYear</span><span class="params">(<span class="type">int</span> year)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>((year%<span class="number">4</span>==<span class="number">0</span>)&amp;&amp;(year%<span class="number">100</span>!=<span class="number">0</span>) || (year%<span class="number">400</span>==<span class="number">0</span>))&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//main 方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String []args)</span>&#123;</span><br><span class="line">    <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">    System.out.println(<span class="string">&quot;请输入年份：&quot;</span>);</span><br><span class="line">    <span class="type">int</span> year=sc.nextInt();</span><br><span class="line">    <span class="keyword">if</span>(isLeapYear(year))&#123;</span><br><span class="line">        System.out.println(year+<span class="string">&quot;年是闰年&quot;</span>);</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        System.out.println(year+<span class="string">&quot;年不是闰年&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="判断某年某月多少天">判断某年某月多少天</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isLeapYear</span><span class="params">(<span class="type">int</span> year)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>((year%<span class="number">4</span>==<span class="number">0</span>)&amp;&amp;(year%<span class="number">100</span>!=<span class="number">0</span>) || (year%<span class="number">400</span>==<span class="number">0</span>))&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">daysInMonth</span><span class="params">(<span class="type">int</span> year, <span class="type">int</span> month)</span>&#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">days</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">switch</span>(month)&#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">5</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">7</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">8</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">10</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">12</span>:</span><br><span class="line">            days = <span class="number">31</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">4</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">6</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">9</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="number">11</span>:</span><br><span class="line">            days = <span class="number">30</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">2</span>:<span class="comment">//特殊月份需调用方法判断是否为闰年</span></span><br><span class="line">            <span class="keyword">if</span>(isLeapYear(year))&#123;</span><br><span class="line">                days= <span class="number">29</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                days=<span class="number">28</span>;</span><br><span class="line">            &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> days;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//main方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String [] args)</span>&#123;</span><br><span class="line">    <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">    System.out.println(<span class="string">&quot;请输入年份：&quot;</span>);</span><br><span class="line">    <span class="type">int</span> <span class="variable">year</span> <span class="operator">=</span>sc.nextInt();</span><br><span class="line">    System.out.println(<span class="string">&quot;请输入月份：&quot;</span>);</span><br><span class="line">    <span class="type">int</span> <span class="variable">month</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">    <span class="type">int</span> <span class="variable">days</span> <span class="operator">=</span> daysInMonth(year,month);</span><br><span class="line">    System.out.println(year+<span class="string">&quot;年&quot;</span>+month+<span class="string">&quot;月&quot;</span>+<span class="string">&quot;有&quot;</span>+days+<span class="string">&quot;天&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1>程序获取</h1><div class="note info flat"><p>因多数官网服务器位于海外，下载受限可移步站长资源 QQ 群，不定时上传其他实用工具，欢迎学习交流。<a href="https://qm.qq.com/q/y3HWkaDGhi">点击前往</a></p></div><h1>特别鸣谢</h1><div class="note default flat"><p>参考：<a href="https://www.nepu.edu.cn/">Java 程序设计[王茱]</a> ; <a href="https://www.icourse163.org/course/NEU-1205915818">Java 程序设计[MOOC][东北大学]</a></p></div>]]></content>
    
    
    <summary type="html">针对《面向对象程序设计》课程解读文档与习题讲解</summary>
    
    
    
    <category term="演示" scheme="https://home.y1xuanyun.cn/categories/%E6%BC%94%E7%A4%BA/"/>
    
    
    <category term="题解" scheme="https://home.y1xuanyun.cn/tags/%E9%A2%98%E8%A7%A3/"/>
    
    <category term="Java" scheme="https://home.y1xuanyun.cn/tags/Java/"/>
    
    <category term="课程" scheme="https://home.y1xuanyun.cn/tags/%E8%AF%BE%E7%A8%8B/"/>
    
    <category term="环境配置" scheme="https://home.y1xuanyun.cn/tags/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/"/>
    
  </entry>
  
  <entry>
    <title>Markdown语法与外挂标签写法汇总</title>
    <link href="https://home.y1xuanyun.cn/posts/24ppt01.html"/>
    <id>https://home.y1xuanyun.cn/posts/24ppt01.html</id>
    <published>2024-08-09T10:00:00.000Z</published>
    <updated>2024-09-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>1.Markdown 语法自带格式</h1><div class="note warning flat"><p>注意：此页面偶尔会存在 CSS 冲突问题!</p></div><h2 id="1-1-代码块">1.1 代码块</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><p>font<br>```shell</p><h1>VSCode 终端</h1><p>hexo clean; hexo s<br>hexo clean; hexo g; hexo d<br>git add .; git commit -m “npm publish”; npm version patch;<br>git push</p><h1>Cmder 终端</h1><p>hexo clean &amp;&amp; hexo s<br>hexo clean &amp;&amp; hexo g &amp;&amp; hexo d<br>git add . &amp;&amp; git commit -m “npm publish” &amp;&amp; npm version patch<br>git push<br>```</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- endtab --&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- tab 渲染演示 --&gt;</span></span><br><span class="line">```shell</span><br><span class="line"># VSCode终端</span><br><span class="line">hexo clean; hexo s</span><br><span class="line">hexo clean; hexo g; hexo d</span><br><span class="line">git add .; git commit -m &quot;npm publish&quot;; npm version patch;</span><br><span class="line">git push</span><br><span class="line"></span><br><span class="line"># Cmder终端</span><br><span class="line">hexo clean &amp;&amp; hexo s</span><br><span class="line">hexo clean &amp;&amp; hexo g &amp;&amp; hexo d</span><br><span class="line">git add . &amp;&amp; git commit -m &quot;npm publish&quot; &amp;&amp; npm version patch</span><br><span class="line">git push</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-2-多级标题">1.2 多级标题</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># H1</span></span><br><span class="line"><span class="section">## H2</span></span><br><span class="line"><span class="section">### H3</span></span><br><span class="line"><span class="section">#### H4</span></span><br><span class="line"><span class="section">##### H5</span></span><br><span class="line"><span class="section">###### H6</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><p>见本文章标题!</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-3-文字样式">1.3 文字样式</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">u</span>&gt;</span></span>下划线演示<span class="language-xml"><span class="tag">&lt;/<span class="name">u</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line">文字<span class="strong">**加粗**</span>演示</span><br><span class="line"></span><br><span class="line">文字<span class="emphasis">*斜体*</span>演示</span><br><span class="line"></span><br><span class="line">文本<span class="code">`高亮`</span>演示</span><br><span class="line"></span><br><span class="line">文本~~删除~~线演示</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">font</span> <span class="attr">size</span> = <span class="string">5</span>&gt;</span></span>5号字<span class="language-xml"><span class="tag">&lt;/<span class="name">font</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">font</span> <span class="attr">face</span>=<span class="string">&quot;黑体&quot;</span>&gt;</span></span>黑体<span class="language-xml"><span class="tag">&lt;/<span class="name">font</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">font</span> <span class="attr">color</span>=<span class="string">blue</span>&gt;</span></span>蓝色<span class="language-xml"><span class="tag">&lt;/<span class="name">font</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">table</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;<span class="name">tr</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;<span class="name">td</span> <span class="attr">bgcolor</span>=<span class="string">MistyRose</span>&gt;</span></span>这里的背景色是：MistyRosen，此处输入任意想输入的内容<span class="language-xml"><span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">table</span>&gt;</span></span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><p><u>下划线演示</u></p><p>文字<strong>加粗</strong>演示</p><p>文字<em>斜体</em>演示</p><p>文本<code>高亮</code>演示</p><p>文本<s>删除</s>线演示</p><p><font size = 5>5 号字</font><br><font face="黑体">黑体</font><br><font color=blue>蓝色</font></p><table><tr><td bgcolor=MistyRose>这里的背景色是：MistyRosen，此处输入任意想输入的内容</td></tr></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-4-引用">1.4 引用</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="quote">&gt;  Java</span></span><br><span class="line"><span class="quote">&gt; 二级引用演示</span></span><br><span class="line"><span class="quote">&gt; MySQL</span></span><br><span class="line"><span class="quote">&gt; &gt;外键</span></span><br><span class="line"><span class="quote">&gt; &gt;</span></span><br><span class="line"><span class="quote">&gt; &gt;事务</span></span><br><span class="line"><span class="quote">&gt; &gt;</span></span><br><span class="line"><span class="quote">&gt; &gt;<span class="strong">**行级锁**</span>(引用内部一样可以用格式)</span></span><br><span class="line"><span class="quote">&gt;</span></span><br><span class="line"><span class="quote">&gt; ....</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><blockquote><p>Java<br>二级引用演示<br>MySQL</p><blockquote><p>外键</p><p>事务</p><p><strong>行级锁</strong>(引用内部一样可以用格式)</p></blockquote><p>…</p></blockquote><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-5-分割线">1.5 分割线</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line"><span class="strong">**<span class="emphasis">*</span></span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><hr><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-6-列表-跟空格都可以">1.6 列表(*,+,-跟空格都可以)</h2><h3 id="1-6-1-无序列表">1.6.1 无序列表</h3><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">*</span> Java</span><br><span class="line"><span class="bullet">*</span> Python</span><br><span class="line"><span class="bullet">*</span> ...</span><br><span class="line"></span><br><span class="line"><span class="bullet">+</span> Java</span><br><span class="line"><span class="bullet">+</span> Python</span><br><span class="line"><span class="bullet">+</span> ...</span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> Java</span><br><span class="line"><span class="bullet">-</span> Python</span><br><span class="line"><span class="bullet">-</span> ...</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ul><li>Java</li><li>Python</li><li>…</li></ul><ul><li>Java</li><li>Python</li><li>…</li></ul><ul><li>Java</li><li>Python</li><li>…</li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h3 id="1-6-2-有序列表">1.6.2 有序列表</h3><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 注意后面有空格</span></span><br><span class="line"><span class="bullet">1.</span></span><br><span class="line"><span class="bullet">2.</span></span><br><span class="line"><span class="bullet">3.</span></span><br><span class="line">4.</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li></li><li></li><li></li><li></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-7-图片">1.7 图片</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 本地图片</span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&quot;/assets/pusheencode.webp&quot;</span> <span class="attr">alt</span>=<span class="string">&quot;示例图片&quot;</span> <span class="attr">style</span>=<span class="string">&quot;zoom:50%;&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="section"># 在线图片</span></span><br><span class="line">![<span class="string">code</span>](<span class="link">https://cdn.jsdelivr.net/gh/fomalhaut1998/markdown_pic/img/code.png</span>)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><p>本地图片:<br><img src="/assets/pusheencode.webp" alt="示例图片" style="zoom:50%;" /><br>在线图片:<br><img src="https://cdn.jsdelivr.net/gh/fomalhaut1998/markdown_pic/img/code.png" alt="code"></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-8-表格">1.8 表格</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">| 项目标号 | 资金     | 备注 |</span><br><span class="line">| -------- | -------- | ---- |</span><br><span class="line">| 1        | 100，000 | 无   |</span><br><span class="line">| 2        | 200，000 | 无   |</span><br><span class="line">| 3        | 300,600  | 重要 |</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><table><thead><tr><th>项目标号</th><th>资金</th><th>备注</th></tr></thead><tbody><tr><td>1</td><td>100，000</td><td>无</td></tr><tr><td>2</td><td>200，000</td><td>无</td></tr><tr><td>3</td><td>300,600</td><td>重要</td></tr></tbody></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="1-9-公式">1.9 公式</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$$</span><br><span class="line">\Gamma(z)=\int<span class="emphasis">_0^\infty t^&#123;z-1&#125;e^&#123;-t&#125;dt.</span></span><br><span class="line"><span class="emphasis">$$</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><p>$$<br>\Gamma(z)=\int_0^\infty t^{z-1}e^{-t}dt.<br>$$</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h1>2.Butterfly 外挂标签</h1><div class="note info flat"><p>这部分参考安知鱼:<a href="https://anzhiy.cn/posts/7d58.html">基于 Butterfly 的外挂标签引入</a></p></div><h2 id="2-1-行内文本样式-text">2.1 行内文本样式 text</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;% u 文本内容 %&#125;</span><br><span class="line">&#123;% emp 文本内容 %&#125;</span><br><span class="line">&#123;% wavy 文本内容 %&#125;</span><br><span class="line">&#123;% del 文本内容 %&#125;</span><br><span class="line">&#123;% kbd 文本内容 %&#125;</span><br><span class="line">&#123;% psw 文本内容 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">1.</span> 带 &#123;% u 下划线 %&#125; 的文本</span><br><span class="line"><span class="bullet">2.</span> 带 &#123;% emp 着重号 %&#125; 的文本</span><br><span class="line"><span class="bullet">3.</span> 带 &#123;% wavy 波浪线 %&#125; 的文本</span><br><span class="line"><span class="bullet">4.</span> 带 &#123;% del 删除线 %&#125; 的文本</span><br><span class="line"><span class="bullet">5.</span> 键盘样式的文本 &#123;% kbd command %&#125; + &#123;% kbd D %&#125;</span><br><span class="line"><span class="bullet">6.</span> 密码样式的文本：&#123;% psw 这里没有验证码 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><ol><li>带 <u>下划线</u> 的文本</li><li>带 <emp>着重号</emp> 的文本</li><li>带 <wavy>波浪线</wavy> 的文本</li><li>带 <del>删除线</del> 的文本</li><li>键盘样式的文本 <kbd>command</kbd> + <kbd>D</kbd></li><li>密码样式的文本：<psw>这里没有验证码</psw></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-2-行内文本-span">2.2 行内文本 span</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% span 样式参数(参数以空格划分), 文本内容 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>字体</code>: logo, code</li><li><code>颜色</code>: red,yellow,green,cyan,blue,gray</li><li><code>大小</code>: small, h4, h3, h2, h1, large, huge, ultra</li><li><code>对齐方向</code>: left, center, right</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> 彩色文字</span><br><span class="line">在一段话中方便插入各种颜色的标签，包括：&#123;% span red, 红色 %&#125;、&#123;% span yellow, 黄色 %&#125;、&#123;% span green, 绿色 %&#125;、&#123;% span cyan, 青色 %&#125;、&#123;% span blue, 蓝色 %&#125;、&#123;% span gray, 灰色 %&#125;。</span><br><span class="line"><span class="bullet">-</span> 超大号文字</span><br><span class="line">文档「开始」页面中的标题部分就是超大号文字。</span><br><span class="line">&#123;% span center logo large, Volantis %&#125;</span><br><span class="line">&#123;% span center small, A Wonderful Theme for Hexo %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><ul><li>彩色文字<br>在一段话中方便插入各种颜色的标签，包括：<span class='p red'>红色</span>、<span class='p yellow'>黄色</span>、<span class='p green'>绿色</span>、<span class='p cyan'>青色</span>、<span class='p blue'>蓝色</span>、<span class='p gray'>灰色</span>。</li><li>超大号文字<br>文档「开始」页面中的标题部分就是超大号文字。<br><span class='p center logo large'>Volantis</span><br><span class='p center small'>A Wonderful Theme for Hexo</span></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-3-段落文本-p">2.3 段落文本 p</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% p 样式参数(参数以空格划分), 文本内容 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>字体</code>: logo, code</li><li><code>颜色</code>: red,yellow,green,cyan,blue,gray</li><li><code>大小</code>: small, h4, h3, h2, h1, large, huge, ultra</li><li><code>对齐方向</code>: left, center, right</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> 彩色文字</span><br><span class="line">在一段话中方便插入各种颜色的标签，包括：&#123;% p red, 红色 %&#125;、&#123;% p yellow, 黄色 %&#125;、&#123;% p green, 绿色 %&#125;、&#123;% p cyan, 青色 %&#125;、&#123;% p blue, 蓝色 %&#125;、&#123;% p gray, 灰色 %&#125;。</span><br><span class="line"><span class="bullet">-</span> 超大号文字</span><br><span class="line">文档「开始」页面中的标题部分就是超大号文字。</span><br><span class="line">&#123;% p center logo large, Volantis %&#125;</span><br><span class="line">&#123;% p center small, A Wonderful Theme for Hexo %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><ul><li>彩色文字<br>在一段话中方便插入各种颜色的标签，包括：<p class='p red'>红色</p>、<p class='p yellow'>黄色</p>、<p class='p green'>绿色</p>、<p class='p cyan'>青色</p>、<p class='p blue'>蓝色</p>、<p class='p gray'>灰色</p>。</li><li>超大号文字<br>文档「开始」页面中的标题部分就是超大号文字。</li></ul><p class='p center logo large'>Volantis</p><p class='p center small'>A Wonderful Theme for Hexo</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-4-引用-note">2.4 引用 note</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">通用配置</button></li><li class="tab"><button type="button" data-href="#分栏-2">语法格式</button></li><li class="tab"><button type="button" data-href="#分栏-3">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-4">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-5">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">note:</span><br><span class="line">  # Note tag style values:</span><br><span class="line">  #  - simple    bs-callout old alert style. Default.</span><br><span class="line">  #  - modern    bs-callout new (v2-v3) alert style.</span><br><span class="line">  #  - flat      flat callout style with background, like on Mozilla or StackOverflow.</span><br><span class="line">  #  - disabled  disable all CSS styles import of note tag.</span><br><span class="line">  style: simple</span><br><span class="line">  icons: false</span><br><span class="line">  border<span class="emphasis">_radius: 3</span></span><br><span class="line"><span class="emphasis">  # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6).</span></span><br><span class="line"><span class="emphasis">  # Offset also applied to label tag variables. This option can work with disabled note tag.</span></span><br><span class="line"><span class="emphasis">  light_</span>bg<span class="emphasis">_offset: 0</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 自带icon</span></span><br><span class="line">&#123;% note [class] [no-icon] [style] %&#125;</span><br><span class="line">Any content (support inline tags too.io).</span><br><span class="line">&#123;% endnote %&#125;</span><br><span class="line"><span class="section"># 外部icon</span></span><br><span class="line">&#123;% note [color] [icon] [style] %&#125;</span><br><span class="line">Any content (support inline tags too.io).</span><br><span class="line">&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.自带 icon</p><table><thead><tr><th>参数</th><th style="text-align:center">用法</th></tr></thead><tbody><tr><td>class</td><td style="text-align:center">【可选】标识，不同的标识有不同的配色 （ default / primary / success / info / warning / danger ）</td></tr><tr><td>no-icon</td><td style="text-align:center">【可选】不显示 icon</td></tr><tr><td>style</td><td style="text-align:center">【可选】可以覆盖配置中的 style （simple/modern/flat/disabled）</td></tr></tbody></table><p>2.外部 icon</p><table><thead><tr><th>参数</th><th style="text-align:center">用法</th></tr></thead><tbody><tr><td>class</td><td style="text-align:center">【可选】标识，不同的标识有不同的配色 （ default / blue / pink / red / purple / orange / green ）</td></tr><tr><td>no-icon</td><td style="text-align:center">【可选】可配置自定义 icon (只支持 fontawesome 图标, 也可以配置 no-icon )</td></tr><tr><td>style</td><td style="text-align:center">【可选】可以覆盖配置中的 style （simple/modern/flat/disabled）</td></tr></tbody></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><details class="folding-tag" blue><summary> 1.自带icon </summary>              <div class='content'>              <p>1.<code>simple</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note simple %&#125;默认 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note default simple %&#125;default 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note primary simple %&#125;primary 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note success simple %&#125;success 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note info simple %&#125;info 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note warning simple %&#125;warning 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note danger simple %&#125;danger 提示块标签&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>2.<code>modern</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note modern %&#125;默认 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note default modern %&#125;default 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note primary modern %&#125;primary 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note success modern %&#125;success 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note info modern %&#125;info 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note warning modern %&#125;warning 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note danger modern %&#125;danger 提示块标签&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>3.<code>flat</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note flat %&#125;默认 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note default flat %&#125;default 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note primary flat %&#125;primary 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note success flat %&#125;success 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note info flat %&#125;info 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note warning flat %&#125;warning 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note danger flat %&#125;danger 提示块标签&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>4.<code>disabled</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note disabled %&#125;默认 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note default disabled %&#125;default 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note primary disabled %&#125;primary 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note success disabled %&#125;success 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note info disabled %&#125;info 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note warning disabled %&#125;warning 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note danger disabled %&#125;danger 提示块标签&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>5.<code>no-icon</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note no-icon %&#125;默认 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note default no-icon %&#125;default 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note primary no-icon %&#125;primary 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note success no-icon %&#125;success 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note info no-icon %&#125;info 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note warning no-icon %&#125;warning 提示块标签&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note danger no-icon %&#125;danger 提示块标签&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure>              </div>            </details><details class="folding-tag" blue><summary> 2.外部icon </summary>              <div class='content'>              <p>1.<code>simple</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note &#x27;fab fa-cc-visa&#x27; simple %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note blue &#x27;fas fa-bullhorn&#x27; simple %&#125;2021 年快到了....&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note pink &#x27;fas fa-car-crash&#x27; simple %&#125;小心开车 安全至上&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note red &#x27;fas fa-fan&#x27; simple%&#125;这是三片呢？还是四片？&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note orange &#x27;fas fa-battery-half&#x27; simple %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note purple &#x27;far fa-hand-scissors&#x27; simple %&#125;剪刀石头布&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note green &#x27;fab fa-internet-explorer&#x27; simple %&#125;前端最讨厌的浏览器&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>2.<code>modern</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note &#x27;fab fa-cc-visa&#x27; modern %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note blue &#x27;fas fa-bullhorn&#x27; modern %&#125;2021 年快到了....&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note pink &#x27;fas fa-car-crash&#x27; modern %&#125;小心开车 安全至上&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note red &#x27;fas fa-fan&#x27; modern%&#125;这是三片呢？还是四片？&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note orange &#x27;fas fa-battery-half&#x27; modern %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note purple &#x27;far fa-hand-scissors&#x27; modern %&#125;剪刀石头布&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note green &#x27;fab fa-internet-explorer&#x27; modern %&#125;前端最讨厌的浏览器&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>3.<code>flat</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note &#x27;fab fa-cc-visa&#x27; flat %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note blue &#x27;fas fa-bullhorn&#x27; flat %&#125;2021 年快到了....&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note pink &#x27;fas fa-car-crash&#x27; flat %&#125;小心开车 安全至上&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note red &#x27;fas fa-fan&#x27; flat%&#125;这是三片呢？还是四片？&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note orange &#x27;fas fa-battery-half&#x27; flat %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note purple &#x27;far fa-hand-scissors&#x27; flat %&#125;剪刀石头布&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note green &#x27;fab fa-internet-explorer&#x27; flat %&#125;前端最讨厌的浏览器&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>4.<code>disabled</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note &#x27;fab fa-cc-visa&#x27; disabled %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note blue &#x27;fas fa-bullhorn&#x27; disabled %&#125;2021 年快到了....&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note pink &#x27;fas fa-car-crash&#x27; disabled %&#125;小心开车 安全至上&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note red &#x27;fas fa-fan&#x27; disabled %&#125;这是三片呢？还是四片？&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note orange &#x27;fas fa-battery-half&#x27; disabled %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note purple &#x27;far fa-hand-scissors&#x27; disabled %&#125;剪刀石头布&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note green &#x27;fab fa-internet-explorer&#x27; disabled %&#125;前端最讨厌的浏览器&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure><p>5.<code>no-icon</code>样式</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% note no-icon %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note blue no-icon %&#125;2021 年快到了....&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note pink no-icon %&#125;小心开车 安全至上&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note red no-icon %&#125;这是三片呢？还是四片？&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note orange no-icon %&#125;你是刷 Visa 还是 UnionPay&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note purple no-icon %&#125;剪刀石头布&#123;% endnote %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% note green no-icon %&#125;前端最讨厌的浏览器&#123;% endnote %&#125;</span><br></pre></td></tr></table></figure>              </div>            </details><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-5"><details class="folding-tag" blue><summary> 1.自带icon </summary>              <div class='content'>              <p>1.<code>simple</code>样式</p><div class="note simple"><p>默认 提示块标签</p></div><div class="note default simple"><p>default 提示块标签</p></div><div class="note primary simple"><p>primary 提示块标签</p></div><div class="note success simple"><p>success 提示块标签</p></div><div class="note info simple"><p>info 提示块标签</p></div><div class="note warning simple"><p>warning 提示块标签</p></div><div class="note danger simple"><p>danger 提示块标签</p></div> 2.`modern`样式<div class="note modern"><p>默认 提示块标签</p></div><div class="note default modern"><p>default 提示块标签</p></div><div class="note primary modern"><p>primary 提示块标签</p></div><div class="note success modern"><p>success 提示块标签</p></div><div class="note info modern"><p>info 提示块标签</p></div><div class="note warning modern"><p>warning 提示块标签</p></div><div class="note danger modern"><p>danger 提示块标签</p></div><p>3.<code>flat</code>样式</p><div class="note flat"><p>默认 提示块标签</p></div><div class="note default flat"><p>default 提示块标签</p></div><div class="note primary flat"><p>primary 提示块标签</p></div><div class="note success flat"><p>success 提示块标签</p></div><div class="note info flat"><p>info 提示块标签</p></div><div class="note warning flat"><p>warning 提示块标签</p></div><div class="note danger flat"><p>danger 提示块标签</p></div><p>4.<code>disabled</code>样式</p><div class="note disabled"><p>默认 提示块标签</p></div><div class="note default disabled"><p>default 提示块标签</p></div><div class="note primary disabled"><p>primary 提示块标签</p></div><div class="note success disabled"><p>success 提示块标签</p></div><div class="note info disabled"><p>info 提示块标签</p></div><div class="note warning disabled"><p>warning 提示块标签</p></div><div class="note danger disabled"><p>danger 提示块标签</p></div><p>5.<code>no-icon</code>样式</p><div class="note no-icon flat"><p>默认 提示块标签</p></div><div class="note default no-icon flat"><p>default 提示块标签</p></div><div class="note primary no-icon flat"><p>primary 提示块标签</p></div><div class="note success no-icon flat"><p>success 提示块标签</p></div><div class="note info no-icon flat"><p>info 提示块标签</p></div><div class="note warning no-icon flat"><p>warning 提示块标签</p></div><div class="note danger no-icon flat"><p>danger 提示块标签</p></div>              </div>            </details><details class="folding-tag" blue><summary> 2.外部icon </summary>              <div class='content'>              <p>1.<code>simple</code>样式</p><div class="note icon-padding simple"><i class="note-icon fab fa-cc-visa"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note blue icon-padding simple"><i class="note-icon fas fa-bullhorn"></i><p>2021 年快到了…</p></div><div class="note pink icon-padding simple"><i class="note-icon fas fa-car-crash"></i><p>小心开车 安全至上</p></div><div class="note red icon-padding simple"><i class="note-icon fas fa-fan"></i><p>这是三片呢？还是四片？</p></div><div class="note orange icon-padding simple"><i class="note-icon fas fa-battery-half"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note purple icon-padding simple"><i class="note-icon far fa-hand-scissors"></i><p>剪刀石头布</p></div><div class="note green icon-padding simple"><i class="note-icon fab fa-internet-explorer"></i><p>前端最讨厌的浏览器</p></div><p>2.<code>modern</code>样式</p><div class="note icon-padding modern"><i class="note-icon fab fa-cc-visa"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note blue icon-padding modern"><i class="note-icon fas fa-bullhorn"></i><p>2021 年快到了…</p></div><div class="note pink icon-padding modern"><i class="note-icon fas fa-car-crash"></i><p>小心开车 安全至上</p></div><div class="note red icon-padding modern"><i class="note-icon fas fa-fan"></i><p>这是三片呢？还是四片？</p></div><div class="note orange icon-padding modern"><i class="note-icon fas fa-battery-half"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note purple icon-padding modern"><i class="note-icon far fa-hand-scissors"></i><p>剪刀石头布</p></div><div class="note green icon-padding modern"><i class="note-icon fab fa-internet-explorer"></i><p>前端最讨厌的浏览器</p></div><p>3.<code>flat</code>样式</p><div class="note icon-padding flat"><i class="note-icon fab fa-cc-visa"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note blue icon-padding flat"><i class="note-icon fas fa-bullhorn"></i><p>2021 年快到了…</p></div><div class="note pink icon-padding flat"><i class="note-icon fas fa-car-crash"></i><p>小心开车 安全至上</p></div><div class="note red icon-padding flat"><i class="note-icon fas fa-fan"></i><p>这是三片呢？还是四片？</p></div><div class="note orange icon-padding flat"><i class="note-icon fas fa-battery-half"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note purple icon-padding flat"><i class="note-icon far fa-hand-scissors"></i><p>剪刀石头布</p></div><div class="note green icon-padding flat"><i class="note-icon fab fa-internet-explorer"></i><p>前端最讨厌的浏览器</p></div><p>4.<code>disabled</code>样式</p><div class="note icon-padding disabled"><i class="note-icon fab fa-cc-visa"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note blue icon-padding disabled"><i class="note-icon fas fa-bullhorn"></i><p>2021 年快到了…</p></div><div class="note pink icon-padding disabled"><i class="note-icon fas fa-car-crash"></i><p>小心开车 安全至上</p></div><div class="note red icon-padding disabled"><i class="note-icon fas fa-fan"></i><p>这是三片呢？还是四片？</p></div><div class="note orange icon-padding disabled"><i class="note-icon fas fa-battery-half"></i><p>你是刷 Visa 还是 UnionPay</p></div><div class="note purple icon-padding disabled"><i class="note-icon far fa-hand-scissors"></i><p>剪刀石头布</p></div><div class="note green icon-padding disabled"><i class="note-icon fab fa-internet-explorer"></i><p>前端最讨厌的浏览器</p></div><p>5.<code>no-icon</code>样式</p><div class="note no-icon flat"><p>你是刷 Visa 还是 UnionPay</p></div><div class="note blue no-icon flat"><p>2021 年快到了…</p></div><div class="note pink no-icon flat"><p>小心开车 安全至上</p></div><div class="note red no-icon flat"><p>这是三片呢？还是四片？</p></div><div class="note orange no-icon flat"><p>你是刷 Visa 还是 UnionPay</p></div><div class="note purple no-icon flat"><p>剪刀石头布</p></div><div class="note green no-icon flat"><p>前端最讨厌的浏览器</p></div>              </div>            </details><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-5-上标标签-tip">2.5 上标标签 tip</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip [参数，可选] %&#125;文本内容&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>样式</code>: success,error,warning,bolt,ban,home,sync,cogs,key,bell</li><li><code>自定义图标</code>: 支持 fontawesome。</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip %&#125;default&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip info %&#125;info&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip success %&#125;success&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip error %&#125;error&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip warning %&#125;warning&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip bolt %&#125;bolt&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip ban %&#125;ban&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip home %&#125;home&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip sync %&#125;sync&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip cogs %&#125;cogs&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip key %&#125;key&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip bell %&#125;bell&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip fa-atom %&#125;自定义font awesome图标&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class="tip "><p>default</p></div><div class="tip info"><p>info</p></div><div class="tip success"><p>success</p></div><div class="tip error"><p>error</p></div><div class="tip warning"><p>warning</p></div><div class="tip bolt"><p>bolt</p></div><div class="tip ban"><p>ban</p></div><div class="tip home"><p>home</p></div><div class="tip sync"><p>sync</p></div><div class="tip cogs"><p>cogs</p></div><div class="tip key"><p>key</p></div><div class="tip bell"><p>bell</p></div><div class="tip fa-atom"><p>自定义 font awesome 图标</p></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-6-动态标签-anima">2.6 动态标签 anima</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip [参数，可选] %&#125;文本内容&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><div class="note info flat"><ol><li>将所需的 CSS 类添加到图标（或 DOM 中的任何元素）。</li><li>对于父级悬停样式，需要给目标元素添加指定 CSS 类，同时还要给目标元素的父级元素添加 CSS 类<code>faa-parent animated-hover</code>。（详情见示例及示例源码）<br>You can regulate the speed of the animation by adding the CSS class or . faa-fastfaa-slow</li><li>可以通过给目标元素添加 CSS 类<code>faa-fast</code>或<code>faa-slow</code>来控制动画快慢。</li></ol></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.On DOM load（当页面加载时显示动画）</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip warning faa-horizontal animated %&#125;warning&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip ban faa-flash animated %&#125;ban&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><p>2.调整动画速度</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip warning faa-horizontal animated faa-fast %&#125;warning&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip ban faa-flash animated faa-slow %&#125;ban&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><p>3.On hover（当鼠标悬停时显示动画）</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip warning faa-horizontal animated-hover %&#125;warning&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip ban faa-flash animated-hover %&#125;ban&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><p>4.On parent hover（当鼠标悬停在父级元素时显示动画）</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tip warning faa-parent animated-hover %&#125;<span class="language-xml"><span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;faa-horizontal&quot;</span>&gt;</span></span>warning<span class="language-xml"><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span>&#123;% endtip %&#125;</span><br><span class="line">&#123;% tip ban faa-parent animated-hover %&#125;<span class="language-xml"><span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;faa-flash&quot;</span>&gt;</span></span>ban<span class="language-xml"><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span>&#123;% endtip %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.On DOM load（当页面加载时显示动画）</p><div class="tip warning faa-horizontal animated"><p>warning</p></div><div class="tip ban faa-flash animated"><p>ban</p></div> 2.调整动画速度<div class="tip warning faa-horizontal animated faa-fast"><p>warning</p></div><div class="tip ban faa-flash animated faa-slow"><p>ban</p></div>3.On hover（当鼠标悬停时显示动画）<div class="tip warning faa-horizontal animated-hover"><p>warning</p></div><div class="tip ban faa-flash animated-hover"><p>ban</p></div>4.On parent hover（当鼠标悬停在父级元素时显示动画）<div class="tip warning faa-parent animated-hover"><p class="faa-horizontal">warning</p></div><div class="tip ban faa-parent animated-hover"><p class="faa-flash">ban</p></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-7-复选列表-checkbox">2.7 复选列表 checkbox</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% checkbox 样式参数（可选）, 文本（支持简单md） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>样式</code>: plus, minus, times</li><li><code>颜色</code>: red,yellow,green,cyan,blue,gray</li><li><code>选中状态</code>: checked</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;% checkbox 纯文本测试 %&#125;</span><br><span class="line">&#123;% checkbox checked, 支持简单的 [<span class="string">markdown</span>](<span class="link">https://guides.github.com/features/mastering-markdown/</span>) 语法 %&#125;</span><br><span class="line">&#123;% checkbox red, 支持自定义颜色 %&#125;</span><br><span class="line">&#123;% checkbox green checked, 绿色 + 默认选中 %&#125;</span><br><span class="line">&#123;% checkbox yellow checked, 黄色 + 默认选中 %&#125;</span><br><span class="line">&#123;% checkbox cyan checked, 青色 + 默认选中 %&#125;</span><br><span class="line">&#123;% checkbox blue checked, 蓝色 + 默认选中 %&#125;</span><br><span class="line">&#123;% checkbox plus green checked, 增加 %&#125;</span><br><span class="line">&#123;% checkbox minus yellow checked, 减少 %&#125;</span><br><span class="line">&#123;% checkbox times red checked, 叉 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class='checkbox'><input type="checkbox" />            <p>纯文本测试</p>            </div><div class='checkbox checked'><input type="checkbox" checked="checked"/>            <p>支持简单的 <a href="https://guides.github.com/features/mastering-markdown/">markdown</a> 语法</p>            </div><div class='checkbox red'><input type="checkbox" />            <p>支持自定义颜色</p>            </div><div class='checkbox green checked'><input type="checkbox" checked="checked"/>            <p>绿色 + 默认选中</p>            </div><div class='checkbox yellow checked'><input type="checkbox" checked="checked"/>            <p>黄色 + 默认选中</p>            </div><div class='checkbox cyan checked'><input type="checkbox" checked="checked"/>            <p>青色 + 默认选中</p>            </div><div class='checkbox blue checked'><input type="checkbox" checked="checked"/>            <p>蓝色 + 默认选中</p>            </div><div class='checkbox plus green checked'><input type="checkbox" checked="checked"/>            <p>增加</p>            </div><div class='checkbox minus yellow checked'><input type="checkbox" checked="checked"/>            <p>减少</p>            </div><div class='checkbox times red checked'><input type="checkbox" checked="checked"/>            <p>叉</p>            </div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-8-单选列表-radio">2.8 单选列表 radio</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% radio 样式参数（可选）, 文本（支持简单md） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>颜色</code>: red,yellow,green,cyan,blue,gray</li><li><code>选中状态</code>: checked</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;% radio 纯文本测试 %&#125;</span><br><span class="line">&#123;% radio checked, 支持简单的 [<span class="string">markdown</span>](<span class="link">https://guides.github.com/features/mastering-markdown/</span>) 语法 %&#125;</span><br><span class="line">&#123;% radio red, 支持自定义颜色 %&#125;</span><br><span class="line">&#123;% radio green, 绿色 %&#125;</span><br><span class="line">&#123;% radio yellow, 黄色 %&#125;</span><br><span class="line">&#123;% radio cyan, 青色 %&#125;</span><br><span class="line">&#123;% radio blue, 蓝色 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class='checkbox'><input type="radio" />            <p>纯文本测试</p>            </div><div class='checkbox checked'><input type="radio" checked="checked"/>            <p>支持简单的 <a href="https://guides.github.com/features/mastering-markdown/">markdown</a> 语法</p>            </div><div class='checkbox red'><input type="radio" />            <p>支持自定义颜色</p>            </div><div class='checkbox green'><input type="radio" />            <p>绿色</p>            </div><div class='checkbox yellow'><input type="radio" />            <p>黄色</p>            </div><div class='checkbox cyan'><input type="radio" />            <p>青色</p>            </div><div class='checkbox blue'><input type="radio" />            <p>蓝色</p>            </div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-9-时间轴-timeline">2.9 时间轴 timeline</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&#123;% timeline 时间线标题（可选）[,color] %&#125;</span><br><span class="line">&lt;!-- timeline 时间节点（标题） --&gt;</span><br><span class="line">正文内容</span><br><span class="line">&lt;!-- endtimeline --&gt;</span><br><span class="line">&lt;!-- timeline 时间节点（标题） --&gt;</span><br><span class="line">正文内容</span><br><span class="line">&lt;!-- endtimeline --&gt;</span><br><span class="line">&#123;% endtimeline %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>title</code>:标题/时间线</li><li><code>color</code>:<code>timeline</code>颜色:default(留空) / blue / pink / red / purple / orange / green</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">&#123;% timeline 时间轴样式,blue %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- timeline 2020-07-24 [<span class="string">2.6.6 -&gt; 3.0</span>](<span class="link">https://github.com/volantis-x/hexo-theme-volantis/releases</span>) --&gt;</span><br><span class="line"></span><br><span class="line"><span class="bullet">1.</span> 如果有 <span class="code">`hexo-lazyload-image`</span> 插件，需要删除并重新安装最新版本，设置 <span class="code">`lazyload.isSPA: true`</span>。</span><br><span class="line"><span class="bullet">2.</span> 2.x 版本的 css 和 js 不适用于 3.x 版本，如果使用了 <span class="code">`use_cdn: true`</span> 则需要删除。</span><br><span class="line"><span class="bullet">3.</span> 2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。</span><br><span class="line"><span class="bullet">4.</span> 2.x 版本的置顶 <span class="code">`top: true`</span> 改为了 <span class="code">`pin: true`</span>，并且同样适用于 <span class="code">`layout: page`</span> 的页面。</span><br><span class="line"><span class="bullet">5.</span> 如果使用了 <span class="code">`hexo-offline`</span> 插件，建议卸载，3.0 版本默认开启了 pjax 服务。</span><br><span class="line"></span><br><span class="line">&lt;!-- endtimeline --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- timeline 2020-05-15 [<span class="string">2.6.3 -&gt; 2.6.6</span>](<span class="link">https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.6</span>) --&gt;</span><br><span class="line"></span><br><span class="line">不需要额外处理。</span><br><span class="line"></span><br><span class="line">&lt;!-- endtimeline --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- timeline 2020-04-20 [<span class="string">2.6.2 -&gt; 2.6.3</span>](<span class="link">https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.3</span>) --&gt;</span><br><span class="line"></span><br><span class="line"><span class="bullet">1.</span> 全局搜索 <span class="code">`seotitle`</span> 并替换为 <span class="code">`seo_title`</span>。</span><br><span class="line"><span class="bullet">2.</span> group 组件的索引规则有变，使用 group 组件的文章内，<span class="code">`group: group_name`</span> 对应的组件名必须是 <span class="code">`group_name`</span>。</span><br><span class="line"><span class="bullet">2.</span> group 组件的列表名优先显示文章的 <span class="code">`short_title`</span> 其次是 <span class="code">`title`</span>。</span><br><span class="line"></span><br><span class="line">&lt;!-- endtimeline --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtimeline %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class="timeline blue"><div class='timeline-item headline'><div class='timeline-item-title'><div class='item-circle'><p>时间轴样式</p></div></div></div><div class='timeline-item'><div class='timeline-item-title'><div class='item-circle'><p>2020-07-24 <a href="https://github.com/volantis-x/hexo-theme-volantis/releases">2.6.6 -&gt; 3.0</a></p></div></div><div class='timeline-item-content'><ol><li>如果有 <code>hexo-lazyload-image</code> 插件，需要删除并重新安装最新版本，设置 <code>lazyload.isSPA: true</code>。</li><li>2.x 版本的 css 和 js 不适用于 3.x 版本，如果使用了 <code>use_cdn: true</code> 则需要删除。</li><li>2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。</li><li>2.x 版本的置顶 <code>top: true</code> 改为了 <code>pin: true</code>，并且同样适用于 <code>layout: page</code> 的页面。</li><li>如果使用了 <code>hexo-offline</code> 插件，建议卸载，3.0 版本默认开启了 pjax 服务。</li></ol></div></div><div class='timeline-item'><div class='timeline-item-title'><div class='item-circle'><p>2020-05-15 <a href="https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.6">2.6.3 -&gt; 2.6.6</a></p></div></div><div class='timeline-item-content'><p>不需要额外处理。</p></div></div><div class='timeline-item'><div class='timeline-item-title'><div class='item-circle'><p>2020-04-20 <a href="https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.3">2.6.2 -&gt; 2.6.3</a></p></div></div><div class='timeline-item-content'><ol><li>全局搜索 <code>seotitle</code> 并替换为 <code>seo_title</code>。</li><li>group 组件的索引规则有变，使用 group 组件的文章内，<code>group: group_name</code> 对应的组件名必须是 <code>group_name</code>。</li><li>group 组件的列表名优先显示文章的 <code>short_title</code> 其次是 <code>title</code>。</li></ol></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-10-链接卡片-link">2.10 链接卡片 link</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% link 标题, 链接, 图片链接（可选） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% link 糖果屋教程贴, https://akilar.top/posts/615e2dec/, https://cdn.cbd.int/akilar-candyassets@1.0.36/image/siteicon/favicon.ico %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><div class="tag link"><a class="link-card" title="糖果屋教程贴" href="https://akilar.top/posts/615e2dec/"><div class="left"><img src="https://cdn.cbd.int/akilar-candyassets@1.0.36/image/siteicon/favicon.ico"/></div><div class="right"><p class="text">糖果屋教程贴</p><p class="url">https://akilar.top/posts/615e2dec/</p></div></a></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-11-按钮-btns">2.11 按钮 btns</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% btns 样式参数 %&#125;</span><br><span class="line">&#123;% cell 标题, 链接, 图片或者图标 %&#125;</span><br><span class="line">&#123;% cell 标题, 链接, 图片或者图标 %&#125;</span><br><span class="line">&#123;% endbtns %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li>圆角样式：rounded, circle</li><li>增加文字样式：可以在容器内增加 <code>&lt;b&gt;</code>标题<code>&lt;/b&gt;</code>和<code>&lt;p&gt;</code>描述文字<code>&lt;/p&gt;</code></li><li>布局方式：<br>默认为自动宽度，适合视野内只有一两个的情况。</li></ol><table><thead><tr><th>参数</th><th>含义</th></tr></thead><tbody><tr><td>wide</td><td>宽一点的按钮</td></tr><tr><td>fill</td><td>填充布局，自动铺满至少一行，多了会换行</td></tr><tr><td>center</td><td>居中，按钮之间是固定间距</td></tr><tr><td>around</td><td>居中分散</td></tr><tr><td>grid2</td><td>等宽最多 2 列，屏幕变窄会适当减少列数</td></tr><tr><td>grid3</td><td>等宽最多 3 列，屏幕变窄会适当减少列数</td></tr><tr><td>grid4</td><td>等宽最多 4 列，屏幕变窄会适当减少列数</td></tr><tr><td>grid5</td><td>等宽最多 5 列，屏幕变窄会适当减少列数</td></tr></tbody></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.如果需要显示类似「团队成员」之类的一组含有头像的链接</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;% btns circle grid5 %&#125;</span><br><span class="line">&#123;% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %&#125;</span><br><span class="line">&#123;% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %&#125;</span><br><span class="line">&#123;% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %&#125;</span><br><span class="line">&#123;% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %&#125;</span><br><span class="line">&#123;% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %&#125;</span><br><span class="line">&#123;% endbtns %&#125;</span><br></pre></td></tr></table></figure><p>2.或者含有图标的按钮</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% btns rounded grid5 %&#125;</span><br><span class="line">&#123;% cell 下载源码, /, fas fa-download %&#125;</span><br><span class="line">&#123;% cell 查看文档, /, fas fa-book-open %&#125;</span><br><span class="line">&#123;% endbtns %&#125;</span><br></pre></td></tr></table></figure><p>3.圆形图标 + 标题 + 描述 + 图片 + 网格 5 列 + 居中</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&#123;% btns circle center grid5 %&#125;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&#x27;https://apps.apple.com/cn/app/heart-mate-pro-hrm-utility/id1463348922?ls=1&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&#x27;fab fa-apple&#x27;</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">b</span>&gt;</span></span>心率管家<span class="language-xml"><span class="tag">&lt;/<span class="name">b</span>&gt;</span></span></span><br><span class="line">&#123;% p red, 专业版 %&#125;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&#x27;https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/qrcode/heartmate_pro.png&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&#x27;https://apps.apple.com/cn/app/heart-mate-lite-hrm-utility/id1475747930?ls=1&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&#x27;fab fa-apple&#x27;</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">b</span>&gt;</span></span>心率管家<span class="language-xml"><span class="tag">&lt;/<span class="name">b</span>&gt;</span></span></span><br><span class="line">&#123;% p green, 免费版 %&#125;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&#x27;https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/qrcode/heartmate_lite.png&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line">&#123;% endbtns %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.如果需要显示类似「团队成员」之类的一组含有头像的链接</p><div class="btns circle grid5">            <a class="button" href='https://xaoxuu.com' title='xaoxuu'><img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png'>xaoxuu</a><a class="button" href='https://xaoxuu.com' title='xaoxuu'><img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png'>xaoxuu</a><a class="button" href='https://xaoxuu.com' title='xaoxuu'><img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png'>xaoxuu</a><a class="button" href='https://xaoxuu.com' title='xaoxuu'><img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png'>xaoxuu</a><a class="button" href='https://xaoxuu.com' title='xaoxuu'><img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png'>xaoxuu</a>          </div> 2.或者含有图标的按钮<div class="btns rounded grid5">            <a class="button" href='/' title='下载源码'><i class='fas fa-download'></i>下载源码</a><a class="button" href='/' title='查看文档'><i class='fas fa-book-open'></i>查看文档</a>          </div> 3.圆形图标 + 标题 + 描述 + 图片 + 网格 5 列 + 居中<div class="btns circle center grid5">            <a href='https://apps.apple.com/cn/app/heart-mate-pro-hrm-utility/id1463348922?ls=1'><i class='fab fa-apple'></i><b>心率管家</b><p class='p red'>专业版</p><img src='https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/qrcode/heartmate_pro.png'></a><a href='https://apps.apple.com/cn/app/heart-mate-lite-hrm-utility/id1475747930?ls=1'><i class='fab fa-apple'></i><b>心率管家</b><p class='p green'>免费版</p><img src='https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/qrcode/heartmate_lite.png'></a>          </div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-12-github-卡片-ghcard">2.12 github 卡片 ghcard</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% ghcard 用户名, 其它参数（可选） %&#125;</span><br><span class="line">&#123;% ghcard 用户名/仓库, 其它参数（可选） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><p>使用<code>,</code>分割各个参数。写法为：<code>参数名=参数值</code><br>以下只写几个常用参数值。</p><table><thead><tr><th><strong>参数名</strong></th><th>取值</th><th>释义</th></tr></thead><tbody><tr><td>hide</td><td>stars,commits,prs,issues,contribs</td><td>隐藏指定统计</td></tr><tr><td>count_private</td><td>true</td><td>将私人项目贡献添加到总提交计数中</td></tr><tr><td>show_icons</td><td>true</td><td>显示图标</td></tr><tr><td>theme</td><td>查阅:<a href="https://github.com/anuraghazra/github-readme-stats/blob/master/themes/README.md">Available Themes</a></td><td>主题</td></tr></tbody></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.用户信息卡片</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">| &#123;% ghcard fomalhaut1998 %&#125; | &#123;% ghcard fomalhaut1998, theme=vue %&#125; |</span><br><span class="line">| -- | -- |</span><br><span class="line">| &#123;% ghcard fomalhaut1998, theme=buefy %&#125; | &#123;% ghcard fomalhaut1998, theme=solarized-light %&#125; |</span><br><span class="line">| &#123;% ghcard fomalhaut1998, theme=onedark %&#125; | &#123;% ghcard fomalhaut1998, theme=solarized-dark %&#125; |</span><br><span class="line">| &#123;% ghcard fomalhaut1998, theme=algolia %&#125; | &#123;% ghcard fomalhaut1998, theme=calm %&#125; |</span><br></pre></td></tr></table></figure><p>2.仓库信息卡片</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">| &#123;% ghcard volantis-x/hexo-theme-volantis %&#125;                | &#123;% ghcard volantis-x/hexo-theme-volantis, theme=vue %&#125;             |</span><br><span class="line">| ---------------------------------------------------------- | ------------------------------------------------------------------ |</span><br><span class="line">| &#123;% ghcard volantis-x/hexo-theme-volantis, theme=buefy %&#125;   | &#123;% ghcard volantis-x/hexo-theme-volantis, theme=solarized-light %&#125; |</span><br><span class="line">| &#123;% ghcard volantis-x/hexo-theme-volantis, theme=onedark %&#125; | &#123;% ghcard volantis-x/hexo-theme-volantis, theme=solarized-dark %&#125;  |</span><br><span class="line">| &#123;% ghcard volantis-x/hexo-theme-volantis, theme=algolia %&#125; | &#123;% ghcard volantis-x/hexo-theme-volantis, theme=calm %&#125;            |</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.用户信息卡片</p><table><thead><tr><th><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&show_owner=true"/></a></th><th><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=vue&show_owner=true"/></a></th></tr></thead><tbody><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=buefy&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=solarized-light&show_owner=true"/></a></td></tr><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=onedark&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=solarized-dark&show_owner=true"/></a></td></tr><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=algolia&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/fomalhaut1998"><img src="https://github-readme-stats.vercel.app/api/?username=fomalhaut1998&theme=calm&show_owner=true"/></a></td></tr></tbody></table><p>2.仓库信息卡片</p><table><thead><tr><th><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&show_owner=true"/></a></th><th><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=vue&show_owner=true"/></a></th></tr></thead><tbody><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=buefy&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=solarized-light&show_owner=true"/></a></td></tr><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=onedark&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=solarized-dark&show_owner=true"/></a></td></tr><tr><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=algolia&show_owner=true"/></a></td><td><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/volantis-x/hexo-theme-volantis"><img src="https://github-readme-stats.vercel.app/api/pin/?username=volantis-x&repo=hexo-theme-volantis&theme=calm&show_owner=true"/></a></td></tr></tbody></table><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-13-github-徽标-ghbdage">2.13 github 徽标 ghbdage</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% bdage [right],[left],[logo]||[color],[link],[title]||[option] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>left</code>：徽标左边的信息，必选参数。</li><li><code>right</code>: 徽标右边的信息，必选参数，</li><li><code>logo</code>：徽标图标，图标名称详见<a href="https://simpleicons.org/">simpleicons</a>，可选参数。</li><li><code>color</code>：徽标右边的颜色，可选参数。</li><li><code>link</code>：指向的链接，可选参数。</li><li><code>title</code>：徽标的额外信息，可选参数。主要用于优化 SEO，但<code>object</code>标签不会像<code>a</code>标签一样在鼠标悬停显示<code>title</code>信息。</li><li><code>option</code>：自定义参数，支持<a href="https://shields.io/">shields.io</a>的全部 API 参数支持，具体参数可以参看上文中的拓展写法示例。形式为<code>name1=value2&amp;name2=value2</code>。</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.基本参数,定义徽标左右文字和图标</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% bdage Theme,Butterfly %&#125;</span><br><span class="line">&#123;% bdage Frame,Hexo,hexo %&#125;</span><br></pre></td></tr></table></figure><p>2.信息参数，定义徽标右侧内容背景色，指向链接</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% bdage CDN,JsDelivr,jsDelivr||abcdef,https://metroui.org.ua/index.html,本站使用JsDelivr为静态资源提供CDN加速 %&#125;</span><br><span class="line">//如果是跨顺序省略可选参数，仍然需要写个逗号,用作分割</span><br><span class="line">&#123;% bdage Source,GitHub,GitHub||,https://github.com/ %&#125;</span><br></pre></td></tr></table></figure><p>3.拓展参数，支持 shields 的 API 的全部参数内容</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% bdage Hosted,Vercel,Vercel||brightgreen,https://vercel.com/,本站采用双线部署，默认线路托管于Vercel||style=social&amp;logoWidth=20 %&#125;</span><br><span class="line">//如果是跨顺序省略可选参数组，仍然需要写双竖线||用作分割</span><br><span class="line">&#123;% bdage Hosted,Vercel,Vercel||||style=social&amp;logoWidth=20&amp;logoColor=violet %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.基本参数,定义徽标左右文字和图标</p><p><object class="ghbdage" style="margin-inline:5px" title="" standby="loading..." data="https://img.shields.io/badge/Butterfly-Theme-orange?logo=&color=orange&link=&"></object><br><object class="ghbdage" style="margin-inline:5px" title="" standby="loading..." data="https://img.shields.io/badge/Hexo-Frame-orange?logo=hexo&color=orange&link=&"></object></p><p>2.信息参数，定义徽标右侧内容背景色，指向链接</p><p><object class="ghbdage" style="margin-inline:5px" title="本站使用JsDelivr为静态资源提供CDN加速" standby="loading..." data="https://img.shields.io/badge/JsDelivr-CDN-orange?logo=jsDelivr&color=abcdef&link=https://metroui.org.ua/index.html&"></object><br>//如果是跨顺序省略可选参数，仍然需要写个逗号,用作分割<br><object class="ghbdage" style="margin-inline:5px" title="" standby="loading..." data="https://img.shields.io/badge/GitHub-Source-orange?logo=GitHub&color=orange&link=https://github.com/&"></object></p><p>3.拓展参数，支持 shields 的 API 的全部参数内容</p><p><object class="ghbdage" style="margin-inline:5px" title="本站采用双线部署，默认线路托管于Vercel" standby="loading..." data="https://img.shields.io/badge/Vercel-Hosted-orange?logo=Vercel&color=brightgreen&link=https://vercel.com/&style=social&logoWidth=20"></object><br>//如果是跨顺序省略可选参数组，仍然需要写双竖线||用作分割<br><object class="ghbdage" style="margin-inline:5px" title="" standby="loading..." data="https://img.shields.io/badge/Vercel-Hosted-orange?logo=Vercel&color=orange&link=&style=social&logoWidth=20&logoColor=violet"></object></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-14-网站卡片-sites">2.14 网站卡片 sites</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% sitegroup %&#125;</span><br><span class="line">&#123;% site 标题, url=链接, screenshot=截图链接, avatar=头像链接（可选）, description=描述（可选） %&#125;</span><br><span class="line">&#123;% site 标题, url=链接, screenshot=截图链接, avatar=头像链接（可选）, description=描述（可选） %&#125;</span><br><span class="line">&#123;% endsitegroup %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;% sitegroup %&#125;</span><br><span class="line">&#123;% site xaoxuu, url=https://xaoxuu.com, screenshot=https://i.loli.net/2020/08/21/VuSwWZ1xAeUHEBC.jpg, avatar=https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/avatar/avatar.png, description=简约风格 %&#125;</span><br><span class="line">&#123;% site inkss, url=https://inkss.cn, screenshot=https://i.loli.net/2020/08/21/Vzbu3i8fXs6Nh5Y.jpg, avatar=https://cdn.jsdelivr.net/gh/inkss/common@master/static/web/avatar.jpg, description=这是一段关于这个网站的描述文字 %&#125;</span><br><span class="line">&#123;% site MHuiG, url=https://blog.mhuig.top, screenshot=https://i.loli.net/2020/08/22/d24zpPlhLYWX6D1.png, avatar=https://cdn.jsdelivr.net/gh/MHuiG/imgbed@master/data/p.png, description=这是一段关于这个网站的描述文字 %&#125;</span><br><span class="line">&#123;% site Colsrch, url=https://colsrch.top, screenshot=https://i.loli.net/2020/08/22/dFRWXm52OVu8qfK.png, avatar=https://cdn.jsdelivr.net/gh/Colsrch/images/Colsrch/avatar.jpg, description=这是一段关于这个网站的描述文字 %&#125;</span><br><span class="line">&#123;% site Linhk1606, url=https://linhk1606.github.io, screenshot=https://i.loli.net/2020/08/21/3PmGLCKicnfow1x.png, avatar=https://i.loli.net/2020/02/09/PN7I5RJfFtA93r2.png, description=这是一段关于这个网站的描述文字 %&#125;</span><br><span class="line">&#123;% endsitegroup %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><div class="site-card-group"><a class="site-card" href="https://fomalhaut1998.com"><div class="img"><img src="https://i.loli.net/2020/08/21/VuSwWZ1xAeUHEBC.jpg"/></div><div class="info"><img src="https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/avatar/avatar.png"/><span class="title">fomalhaut1998</span><span class="desc">简约风格</span></div></a><a class="site-card" href="https://inkss.cn"><div class="img"><img src="https://i.loli.net/2020/08/21/Vzbu3i8fXs6Nh5Y.jpg"/></div><div class="info"><img src="https://cdn.jsdelivr.net/gh/inkss/common@master/static/web/avatar.jpg"/><span class="title">inkss</span><span class="desc">这是一段关于这个网站的描述文字</span></div></a><a class="site-card" href="https://blog.mhuig.top"><div class="img"><img src="https://i.loli.net/2020/08/22/d24zpPlhLYWX6D1.png"/></div><div class="info"><img src="https://cdn.jsdelivr.net/gh/MHuiG/imgbed@master/data/p.png"/><span class="title">MHuiG</span><span class="desc">这是一段关于这个网站的描述文字</span></div></a><a class="site-card" href="https://colsrch.top"><div class="img"><img src="https://i.loli.net/2020/08/22/dFRWXm52OVu8qfK.png"/></div><div class="info"><img src="https://cdn.jsdelivr.net/gh/Colsrch/images/Colsrch/avatar.jpg"/><span class="title">Colsrch</span><span class="desc">这是一段关于这个网站的描述文字</span></div></a><a class="site-card" href="https://linhk1606.github.io"><div class="img"><img src="https://i.loli.net/2020/08/21/3PmGLCKicnfow1x.png"/></div><div class="info"><img src="https://i.loli.net/2020/02/09/PN7I5RJfFtA93r2.png"/><span class="title">Linhk1606</span><span class="desc">这是一段关于这个网站的描述文字</span></div></a></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-15-行内图片-inlineimage">2.15 行内图片 inlineimage</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% inlineimage 图片链接, height=高度（可选） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>高度</code>：height=20px</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">这是 &#123;% inlineimage https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/0000.gif %&#125; 一段话。</span><br><span class="line"></span><br><span class="line">这又是 &#123;% inlineimage https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/5150.gif, height=40px %&#125; 一段话。</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>这是 <img no-lazy class="inline" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/0000.gif" style="height:1.5em"/> 一段话。</p><p>这又是 <img no-lazy class="inline" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/5150.gif" style="height:40px;"/> 一段话。</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-16-单张图片-image">2.16 单张图片 image</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% image 链接, width=宽度（可选）, height=高度（可选）, alt=描述（可选）, bg=占位颜色（可选） %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li>图片宽度高度：width=300px, height=32px</li><li>图片描述：alt=图片描述（butterfly 需要在主题配置文件中开启图片描述）</li><li>占位背景色：bg=#f2f2f2</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.添加描述：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, alt=每天下课回宿舍的路，没有什么故事。 %&#125;</span><br></pre></td></tr></table></figure><p>2.指定宽度</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px %&#125;</span><br></pre></td></tr></table></figure><p>3.指定宽度并添加描述：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px, alt=每天下课回宿舍的路，没有什么故事。 %&#125;</span><br></pre></td></tr></table></figure><p>4.设置占位背景色：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px, bg=#1D0C04, alt=优化不同宽度浏览的观感 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.添加描述：</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg" alt="每天下课回宿舍的路，没有什么故事。"/></div><span class="image-caption">每天下课回宿舍的路，没有什么故事。</span></div>2..指定宽度<div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg" style="width:400px;"/></div></div> 3.指定宽度并添加描述：<div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg" alt="每天下课回宿舍的路，没有什么故事。" style="width:400px;"/></div><span class="image-caption">每天下课回宿舍的路，没有什么故事。</span></div> 4.设置占位背景色：<div class="img-wrap"><div class="img-bg" style="background:#1D0C04"><img class="img" src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg" alt="优化不同宽度浏览的观感" style="width:400px;"/></div><span class="image-caption">优化不同宽度浏览的观感</span></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-17-音频-audio">2.17 音频 audio</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% audio 音频链接 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% audio https://github.com/volantis-x/volantis-docs/releases/download/assets/Lumia1020.mp3 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><div class="audio"><audio controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/Lumia1020.mp3' type='audio/mp3'>Your browser does not support the audio tag.</audio></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-18-视频-video">2.18 视频 video</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% video 视频链接 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>对齐方向</code>：left, center, right</li><li><code>列数</code>：逗号后面直接写列数，支持 1 ～ 4 列。</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.100%宽度</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br></pre></td></tr></table></figure><p>2.50%宽度</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;% videos, 2 %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% endvideos %&#125;</span><br></pre></td></tr></table></figure><p>3.25%宽度</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;% videos, 4 %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG<span class="emphasis">_0341.mov %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_</span>0341.mov %&#125;</span><br><span class="line">&#123;% endvideos %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.100%宽度</p><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div>2.50%宽度<div class="videos" col='2'><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div></div>3.25%宽度<div class="videos" col='4'><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div><div class="video"><video controls preload><source src='https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov' type='video/mp4'>Your browser does not support the video tag.</video></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-19-相册-gallery">2.19 相册 gallery</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><p>1.gallerygroup 相册图库</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;gallery-group-main&quot;</span>&gt;</span></span></span><br><span class="line">&#123;% galleryGroup name description link img-url %&#125;</span><br><span class="line">&#123;% galleryGroup name description link img-url %&#125;</span><br><span class="line">&#123;% galleryGroup name description link img-url %&#125;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure><p>2.gallery 相册</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% gallery %&#125;</span><br><span class="line">markdown 圖片格式</span><br><span class="line">&#123;% endgallery %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ul><li>gallerygroup 相册图库</li></ul><table><thead><tr><th>参数名</th><th>释义</th></tr></thead><tbody><tr><td>name</td><td>图库名字</td></tr><tr><td>description</td><td>图库描述</td></tr><tr><td>link</td><td>链接到对应相册的地址</td></tr><tr><td>img-url</td><td>图库封面</td></tr></tbody></table><ul><li><p>gallery 相册</p><p>区别于旧版的 Gallery 相册,新的 Gallery 相册会自动根据图片长度进行排版，书写也更加方便，与 markdown 格式一样。可根据需要插入到相应的 md。无需再自己配置长宽。<strong>建议在粘贴时故意使用长短、大小、横竖不一的图片</strong>，会有更好的效果。（尺寸完全相同的图片只会平铺输出，效果很糟糕）</p></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.gallerygroup 相册图库</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;gallery-group-main&quot;</span>&gt;</span></span></span><br><span class="line">&#123;% galleryGroup MC 在Rikkaの六花服务器里留下的足迹 &#x27;/gallery/MC/&#x27; https://cdn.cbd.int/akilar-candyassets@1.0.36/image/1.jpg %&#125;</span><br><span class="line">&#123;% galleryGroup Gundam 哦咧哇gundam哒！ &#x27;/gallery/Gundam/&#x27; https://cdn.cbd.int/akilar-candyassets@1.0.36/image/20200907110508327.png %&#125;</span><br><span class="line">&#123;% galleryGroup I-am-Akilar 某种意义上也算自拍吧 &#x27;/gallery/I-am-Akilar/&#x27; https://cdn.cbd.int/akilar-candyassets@1.0.36/image/20200907113116651.png %&#125;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure><p>2.gallery 相册</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% gallery %&#125;</span><br><span class="line">![](<span class="link">https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg</span>)</span><br><span class="line">![](<span class="link">https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg</span>)</span><br><span class="line">&#123;% endgallery %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.gallerygroup 相册图库</p><div class="gallery-group-main">  <figure class="gallery-group">  <img class="gallery-group-img no-lightbox" src='https://cdn.cbd.int/akilar-candyassets@1.0.36/image/1.jpg' alt="Group Image Gallery">  <figcaption>  <div class="gallery-group-name">MC</div>  <p>在Rikkaの六花服务器里留下的足迹</p>  <a href='/gallery/MC/'></a>  </figcaption>  </figure>  <figure class="gallery-group">  <img class="gallery-group-img no-lightbox" src='https://cdn.cbd.int/akilar-candyassets@1.0.36/image/20200907110508327.png' alt="Group Image Gallery">  <figcaption>  <div class="gallery-group-name">Gundam</div>  <p>哦咧哇gundam哒！</p>  <a href='/gallery/Gundam/'></a>  </figcaption>  </figure>  <figure class="gallery-group">  <img class="gallery-group-img no-lightbox" src='https://cdn.cbd.int/akilar-candyassets@1.0.36/image/20200907113116651.png' alt="Group Image Gallery">  <figcaption>  <div class="gallery-group-name">I-am-Akilar</div>  <p>某种意义上也算自拍吧</p>  <a href='/gallery/I-am-Akilar/'></a>  </figcaption>  </figure></div>2.gallery 相册<div class="fj-gallery"><p><img src="https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg" alt=""><br><img src="https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg" alt=""></p>          </div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-20-折叠框-folding">2.20 折叠框 folding</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><p>1.gallerygroup 相册图库</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% folding 参数（可选）, 标题 %&#125;</span><br><span class="line">![](<span class="link">https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg</span>)</span><br><span class="line">&#123;% endfolding %&#125;</span><br></pre></td></tr></table></figure><!-- tab 参数配置 --><ol><li><p><code>颜色</code>：blue, cyan, green, yellow, red</p></li><li><p><code>状态</code>：状态填写 open 代表默认打开。</p></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">&#123;% folding 查看图片测试 %&#125;</span><br><span class="line"></span><br><span class="line">![](<span class="link">https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg</span>)</span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding cyan open, 查看默认打开的折叠框 %&#125;</span><br><span class="line"></span><br><span class="line">这是一个默认打开的折叠框。</span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding green, 查看代码测试 %&#125;</span><br><span class="line">假装这里有代码块（代码块没法嵌套代码块）</span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding yellow, 查看列表测试 %&#125;</span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> haha</span><br><span class="line"><span class="bullet">-</span> hehe</span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding red, 查看嵌套测试 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding blue, 查看嵌套测试2 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% folding 查看嵌套测试3 %&#125;</span><br><span class="line"></span><br><span class="line">hahaha <span class="language-xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&#x27;https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/tieba/%E6%BB%91%E7%A8%BD.png&#x27;</span> <span class="attr">style</span>=<span class="string">&#x27;height:24px&#x27;</span>&gt;</span></span><span class="language-xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% endfolding %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><details class="folding-tag" ><summary> 查看图片测试 </summary>              <div class='content'>              <p><img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg" alt=""></p>              </div>            </details><details class="folding-tag" cyan open><summary> 查看默认打开的折叠框 </summary>              <div class='content'>              <p>这是一个默认打开的折叠框。</p>              </div>            </details><details class="folding-tag" green><summary> 查看代码测试 </summary>              <div class='content'>              <p>假装这里有代码块（代码块没法嵌套代码块）</p>              </div>            </details><details class="folding-tag" yellow><summary> 查看列表测试 </summary>              <div class='content'>              <ul><li>haha</li><li>hehe</li></ul>              </div>            </details><details class="folding-tag" red><summary> 查看嵌套测试 </summary>              <div class='content'>              <details class="folding-tag" blue><summary> 查看嵌套测试2 </summary>              <div class='content'>              <details class="folding-tag" ><summary> 查看嵌套测试3 </summary>              <div class='content'>              <p>hahaha <span><img src='https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/tieba/%E6%BB%91%E7%A8%BD.png' style='height:24px'></span></p>              </div>            </details>              </div>            </details>              </div>            </details><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-21-分栏-tab">2.21 分栏 tab</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">配置参数</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tabs Unique name, [index] %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab [Tab caption] [@icon] --&gt;</span><br><span class="line"></span><br><span class="line">Any content (support inline tags too).</span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtabs %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><p>Unique name :</p><ul><li><p>选项卡块标签的唯一名称，不带逗号。</p></li><li><p>将在#id 中用作每个标签及其索引号的前缀。</p></li><li><p>如果名称中包含空格，则对于生成#id，所有空格将由破折号代替。</p></li><li><p>仅当前帖子/页面的 URL 必须是唯一的！</p></li></ul></li><li><p>[index]:</p><ul><li><p>活动选项卡的索引号。</p></li><li><p>如果未指定，将选择第一个标签（1）。</p></li><li><p>如果 index 为-1，则不会选择任何选项卡。</p></li><li><p>可选参数。</p></li></ul></li><li><p>[Tab caption]:</p><ul><li><p>当前选项卡的标题。</p></li><li><p>如果未指定标题，则带有制表符索引后缀的唯一名称将用作制表符的标题。</p></li><li><p>如果未指定标题，但指定了图标，则标题将为空。</p></li><li><p>可选参数。</p></li></ul></li><li><p>[@icon]:</p><ul><li><p>FontAwesome 图标名称（全名，看起来像“ fas fa-font”）</p></li><li><p>可以指定带空格或不带空格；</p></li><li><p>例如’Tab caption @icon’ 和 ‘Tab caption@icon’.</p></li><li><p>可选参数。</p></li></ul></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.Demo 1 - 预设选择第一个【默认】</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tabs test1 %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 1.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 2.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 3.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtabs %&#125;</span><br></pre></td></tr></table></figure><p>2.Demo 2 - 预设选择 tabs</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tabs test2, 3 %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 1.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 2.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 3.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtabs %&#125;</span><br></pre></td></tr></table></figure><p>3.Demo 3 - 没有预设值</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tabs test3, -1 %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 1.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 2.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**This is Tab 3.**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtabs %&#125;</span><br></pre></td></tr></table></figure><p>4.Demo 4 - 自定义 Tab 名 + 只有 icon + icon 和 Tab 名</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&#123;% tabs test4 %&#125;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab 第一个Tab --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**tab 名字为第一个 Tab**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab @fab fa-apple-pay --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**只有图标 没有 Tab 名字**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- tab 炸弹@fas fa-bomb --&gt;</span><br><span class="line"></span><br><span class="line"><span class="strong">**名字+icon**</span></span><br><span class="line"></span><br><span class="line">&lt;!-- endtab --&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endtabs %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.Demo 1 - 预设选择第一个【默认】</p><div class="tabs" id="test1"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#test1-1">test1 1</button></li><li class="tab"><button type="button" data-href="#test1-2">test1 2</button></li><li class="tab"><button type="button" data-href="#test1-3">test1 3</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="test1-1"><p><strong>This is Tab 1.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test1-2"><p><strong>This is Tab 2.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test1-3"><p><strong>This is Tab 3.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><p>2.Demo 2 - 预设选择 tabs</p><div class="tabs" id="test2"><ul class="nav-tabs"><li class="tab"><button type="button" data-href="#test2-1">test2 1</button></li><li class="tab"><button type="button" data-href="#test2-2">test2 2</button></li><li class="tab active"><button type="button" data-href="#test2-3">test2 3</button></li></ul><div class="tab-contents"><div class="tab-item-content" id="test2-1"><p><strong>This is Tab 1.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test2-2"><p><strong>This is Tab 2.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content active" id="test2-3"><p><strong>This is Tab 3.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><p>3.Demo 3 - 没有预设值</p><div class="tabs" id="test3"><ul class="nav-tabs"><li class="tab"><button type="button" data-href="#test3-1">test3 1</button></li><li class="tab"><button type="button" data-href="#test3-2">test3 2</button></li><li class="tab"><button type="button" data-href="#test3-3">test3 3</button></li></ul><div class="tab-contents"><div class="tab-item-content" id="test3-1"><p><strong>This is Tab 1.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test3-2"><p><strong>This is Tab 2.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test3-3"><p><strong>This is Tab 3.</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><p>4.Demo 4 - 自定义 Tab 名 + 只有 icon + icon 和 Tab 名</p><div class="tabs" id="test4"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#test4-1">第一个Tab</button></li><li class="tab"><button type="button" data-href="#test4-2"><i class="fab fa-apple-pay" style="text-align: center;"></i></button></li><li class="tab"><button type="button" data-href="#test4-3"><i class="fas fa-bomb"></i>炸弹</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="test4-1"><p><strong>tab 名字为第一个 Tab</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test4-2"><p><strong>只有图标 没有 Tab 名字</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="test4-3"><p><strong>名字+icon</strong></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-22-诗词标签-poem">2.22 诗词标签 poem</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-2">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-3">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><ol><li><code>title</code>：诗词标题</li><li><code>author</code>：作者，可以不写</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&#123;% poem 水调歌头,苏轼 %&#125;</span><br><span class="line">丙辰中秋，欢饮达旦，大醉，作此篇，兼怀子由。</span><br><span class="line">明月几时有？把酒问青天。</span><br><span class="line">不知天上宫阙，今夕是何年？</span><br><span class="line">我欲乘风归去，又恐琼楼玉宇，高处不胜寒。</span><br><span class="line">起舞弄清影，何似在人间？</span><br><span class="line"></span><br><span class="line">转朱阁，低绮户，照无眠。</span><br><span class="line">不应有恨，何事长向别时圆？</span><br><span class="line">人有悲欢离合，月有阴晴圆缺，此事古难全。</span><br><span class="line">但愿人长久，千里共婵娟。</span><br><span class="line">&#123;% endpoem %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><div class='poem'><div class='poem-title'>水调歌头</div><div class='poem-author'>苏轼</div><p>丙辰中秋，欢饮达旦，大醉，作此篇，兼怀子由。<br>明月几时有？把酒问青天。<br>不知天上宫阙，今夕是何年？<br>我欲乘风归去，又恐琼楼玉宇，高处不胜寒。<br>起舞弄清影，何似在人间？</p><p>转朱阁，低绮户，照无眠。<br>不应有恨，何事长向别时圆？<br>人有悲欢离合，月有阴晴圆缺，此事古难全。<br>但愿人长久，千里共婵娟。</p></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-23-阿里图标-icon">2.23 阿里图标 icon</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% icon [icon-xxxx],[font-size] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>icon-xxxx</code>：表示图标<code>font-class</code>,可以在自己的阿里矢量图标库项目的<code>font-class</code>引用方案内查询并复制。</li><li><code>font-size</code>：表示图标大小，直接填写数字即可，单位为<code>em</code>。图标大小默认值为<code>1em</code>。</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">&#123;% icon icon-rat<span class="emphasis">_zi %&#125;&#123;% icon icon-rat,2 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-ox_</span>chou,3 %&#125;&#123;% icon icon-ox,4 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% icon icon-tiger<span class="emphasis">_yin,5 %&#125;&#123;% icon icon-tiger,6 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-rabbit_</span>mao,1 %&#125;&#123;% icon icon-rabbit,2 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% icon icon-dragon<span class="emphasis">_chen,3 %&#125;&#123;% icon icon-dragon,4 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-snake_</span>si,5 %&#125;&#123;% icon icon-snake,6 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% icon icon-horse<span class="emphasis">_wu %&#125;&#123;% icon icon-horse,2 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-goat_</span>wei,3 %&#125;&#123;% icon icon-goat,4 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% icon icon-monkey<span class="emphasis">_shen,5 %&#125;&#123;% icon icon-monkey,6 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-rooster_</span>you %&#125;&#123;% icon icon-rooster,2 %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% icon icon-dog<span class="emphasis">_xu,3 %&#125;&#123;% icon icon-dog,4 %&#125;</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">&#123;% icon icon-boar_</span>hai,5 %&#125;&#123;% icon icon-boar,6 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p><svg class="icon" style="width:1em; height:1em" aria-hidden="true"><use xlink:href="#icon-rat_zi"></use></svg><svg class="icon" style="width:2em; height:2em" aria-hidden="true"><use xlink:href="#icon-rat"></use></svg></p><p><svg class="icon" style="width:3em; height:3em" aria-hidden="true"><use xlink:href="#icon-ox_chou"></use></svg><svg class="icon" style="width:4em; height:4em" aria-hidden="true"><use xlink:href="#icon-ox"></use></svg></p><p><svg class="icon" style="width:5em; height:5em" aria-hidden="true"><use xlink:href="#icon-tiger_yin"></use></svg><svg class="icon" style="width:6em; height:6em" aria-hidden="true"><use xlink:href="#icon-tiger"></use></svg></p><p><svg class="icon" style="width:1em; height:1em" aria-hidden="true"><use xlink:href="#icon-rabbit_mao"></use></svg><svg class="icon" style="width:2em; height:2em" aria-hidden="true"><use xlink:href="#icon-rabbit"></use></svg></p><p><svg class="icon" style="width:3em; height:3em" aria-hidden="true"><use xlink:href="#icon-dragon_chen"></use></svg><svg class="icon" style="width:4em; height:4em" aria-hidden="true"><use xlink:href="#icon-dragon"></use></svg></p><p><svg class="icon" style="width:5em; height:5em" aria-hidden="true"><use xlink:href="#icon-snake_si"></use></svg><svg class="icon" style="width:6em; height:6em" aria-hidden="true"><use xlink:href="#icon-snake"></use></svg></p><p><svg class="icon" style="width:1em; height:1em" aria-hidden="true"><use xlink:href="#icon-horse_wu"></use></svg><svg class="icon" style="width:2em; height:2em" aria-hidden="true"><use xlink:href="#icon-horse"></use></svg></p><p><svg class="icon" style="width:3em; height:3em" aria-hidden="true"><use xlink:href="#icon-goat_wei"></use></svg><svg class="icon" style="width:4em; height:4em" aria-hidden="true"><use xlink:href="#icon-goat"></use></svg></p><p><svg class="icon" style="width:5em; height:5em" aria-hidden="true"><use xlink:href="#icon-monkey_shen"></use></svg><svg class="icon" style="width:6em; height:6em" aria-hidden="true"><use xlink:href="#icon-monkey"></use></svg></p><p><svg class="icon" style="width:1em; height:1em" aria-hidden="true"><use xlink:href="#icon-rooster_you"></use></svg><svg class="icon" style="width:2em; height:2em" aria-hidden="true"><use xlink:href="#icon-rooster"></use></svg></p><p><svg class="icon" style="width:3em; height:3em" aria-hidden="true"><use xlink:href="#icon-dog_xu"></use></svg><svg class="icon" style="width:4em; height:4em" aria-hidden="true"><use xlink:href="#icon-dog"></use></svg></p><p><svg class="icon" style="width:5em; height:5em" aria-hidden="true"><use xlink:href="#icon-boar_hai"></use></svg><svg class="icon" style="width:6em; height:6em" aria-hidden="true"><use xlink:href="#icon-boar"></use></svg></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-24-特效标签-wow">2.24 特效标签 wow</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-2">渲染演示</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% wow [animete],[duration],[delay],[offset],[iteration] %&#125;</span><br><span class="line">内容</span><br><span class="line">&#123;% endwow %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>animate</code>: 动画样式，效果详见<a href="https://animate.style/">animate.css 参考文档</a></li><li><code>duration</code>: 选填项，动画持续时间，单位可以是<code>ms</code>也可以是<code>s</code>。例如<code>3s</code>，<code>700ms</code>。</li><li><code>delay</code>: 选填项，动画开始的延迟时间，单位可以是<code>ms</code>也可以是<code>s</code>。例如<code>3s</code>，<code>700ms</code>。</li><li><code>offset</code>: 选填项，开始动画的距离（相对浏览器底部）</li><li><code>iteration</code>: 选填项，动画重复的次数</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><p>1.flip 动画效果。</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;% wow animate<span class="strong">__zoomIn,5s,5s,100,10 %&#125;</span></span><br><span class="line"><span class="strong">&#123;% note blue &#x27;fas fa-bullhorn&#x27; modern%&#125;</span></span><br><span class="line"><span class="strong">`zoomIn`动画效果，持续`5s`，延时`5s`，离底部`100`距离时启动，重复`10`次</span></span><br><span class="line"><span class="strong">&#123;% endnote %&#125;</span></span><br><span class="line"><span class="strong">&#123;% endwow %&#125;</span></span><br></pre></td></tr></table></figure><p>2.zoomIn 动画效果，持续 5s，延时 5s，离底部 100 距离时启动，重复 10 次</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;% wow animate<span class="strong">__zoomIn,5s,5s,100,10 %&#125;</span></span><br><span class="line"><span class="strong">&#123;% note blue &#x27;fas fa-bullhorn&#x27; modern%&#125;</span></span><br><span class="line"><span class="strong">`zoomIn`动画效果，持续`5s`，延时`5s`，离底部`100`距离时启动，重复`10`次</span></span><br><span class="line"><span class="strong">&#123;% endnote %&#125;</span></span><br><span class="line"><span class="strong">&#123;% endwow %&#125;</span></span><br></pre></td></tr></table></figure><p>3.slideInRight 动画效果，持续 5s，延时 5s</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;% wow animate<span class="strong">__slideInRight,5s,5s %&#125;</span></span><br><span class="line"><span class="strong">&#123;% note orange &#x27;fas fa-car&#x27; modern%&#125;</span></span><br><span class="line"><span class="strong">`slideInRight`动画效果，持续`5s`，延时`5s`。</span></span><br><span class="line"><span class="strong">&#123;% endnote %&#125;</span></span><br><span class="line"><span class="strong">&#123;% endwow %&#125;</span></span><br></pre></td></tr></table></figure><p>4.heartBeat 动画效果，延时 5s，重复 10 次。此处注意不用的参数位置要留空，用逗号间隔。</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;% wow animate<span class="strong">__heartBeat,,5s,,10 %&#125;</span></span><br><span class="line"><span class="strong">&#123;% note red &#x27;fas fa-battery-half&#x27; modern%&#125;</span></span><br><span class="line"><span class="strong">`heartBeat`动画效果，延时`5s`，重复`10`次。</span></span><br><span class="line"><span class="strong">&#123;% endnote %&#125;</span></span><br><span class="line"><span class="strong">&#123;% endwow %&#125;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>1.flip 动画效果。</p><div class='wow animate__zoomIn' data-wow-duration='5s' data-wow-delay='5s' data-wow-offset='100'  data-wow-iteration='10' ><div class="note blue icon-padding modern"><i class="note-icon fas fa-bullhorn"></i><p><code>zoomIn</code>动画效果，持续<code>5s</code>，延时<code>5s</code>，离底部<code>100</code>距离时启动，重复<code>10</code>次</p></div></div><p>2.zoomIn 动画效果，持续 5s，延时 5s，离底部 100 距离时启动，重复 10 次</p><div class='wow animate__zoomIn' data-wow-duration='5s' data-wow-delay='5s' data-wow-offset='100'  data-wow-iteration='10' ><div class="note blue icon-padding modern"><i class="note-icon fas fa-bullhorn"></i><p><code>zoomIn</code>动画效果，持续<code>5s</code>，延时<code>5s</code>，离底部<code>100</code>距离时启动，重复<code>10</code>次</p></div></div><p>3.slideInRight 动画效果，持续 5s，延时 5s</p><div class='wow animate__slideInRight' data-wow-duration='5s' data-wow-delay='5s' data-wow-offset=''  data-wow-iteration='' ><div class="note orange icon-padding modern"><i class="note-icon fas fa-car"></i><p><code>slideInRight</code>动画效果，持续<code>5s</code>，延时<code>5s</code>。</p></div></div><p>4.heartBeat 动画效果，延时 5s，重复 10 次。此处注意不用的参数位置要留空，用逗号间隔。</p><div class='wow animate__heartBeat' data-wow-duration='' data-wow-delay='5s' data-wow-offset=''  data-wow-iteration='10' ><div class="note red icon-padding modern"><i class="note-icon fas fa-battery-half"></i><p><code>heartBeat</code>动画效果，延时<code>5s</code>，重复<code>10</code>次。</p></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-25-进度条-progress">2.25 进度条 progress</h2><div class="note info flat"><p>进度条标签参考<a href="https://rongbuqiu.com/jdt.html">沂佰孜猫-给 HEXO 文章添加彩色进度条</a>。<br>源样式提取自<a href="https://zwying0814.gitbook.io/cuteen/">Cuteen</a>主题。</p></div><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-2">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% progress [width] [color] [text] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>width</code>: 0 到 100 的阿拉伯数字</li><li><code>color</code>: 颜色，取值有 red,yellow,green,cyan,blue,gray</li><li><code>text</code>:进度条上的文字内容</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;% progress 10 red 进度条样式预览 %&#125;</span><br><span class="line">&#123;% progress 30 yellow 进度条样式预览 %&#125;</span><br><span class="line">&#123;% progress 50 green 进度条样式预览 %&#125;</span><br><span class="line">&#123;% progress 70 cyan 进度条样式预览 %&#125;</span><br><span class="line">&#123;% progress 90 blue 进度条样式预览 %&#125;</span><br><span class="line">&#123;% progress 100 gray 进度条样式预览 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-red"  style="width: 10%" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-yellow"  style="width: 30%" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-green"  style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-cyan"  style="width: 70%" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-blue"  style="width: 90%" aria-valuenow="90" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-gray"  style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><p>进度条样式预览</p></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-26-注释-notation">2.26 注释 notation</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% nota [label] , [text] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><p><code>label</code>: 注释词汇</p></li><li><p><code>text</code>: 悬停显示的注解内容</p></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% nota 把鼠标移动到我上面试试 ,可以看到注解内容出现在顶栏 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p><span class='nota' data-nota='可以看到注解内容出现在顶栏'>把鼠标移动到我上面试试</span></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-27-气泡注释-bubble">2.27 气泡注释 bubble</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% bubble [content] , [notation] ,[background-color] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>content</code>: 注释词汇</li><li><code>notation</code>: 悬停显示的注解内容</li><li><code>background-color</code>: 可选，气泡背景色。默认为“#71a4e3”</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">最近我学到了不少新玩意儿（虽然对很多大佬来说这些已经是旧技术了），比如CSS的&#123;% bubble 兄弟相邻选择器,&quot;例如 h1 + p &#123;margin-top:50px;&#125;&quot; %&#125;，&#123;% bubble flex布局,&quot;Flex 是 Flexible Box 的缩写，意为&quot;弹性布局&quot;，用来为盒状模型提供最大的灵活性&quot;,&quot;#ec5830&quot; %&#125;，&#123;% bubble transform变换,&quot;transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。&quot;,&quot;#1db675&quot; %&#125;，animation的&#123;% bubble 贝塞尔速度曲线,&quot;贝塞尔曲线(Bézier curve)，又称贝兹曲线或贝济埃曲线，是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线，贝兹曲线由线段与节点组成，节点是可拖动的支点，线段像可伸缩的皮筋&quot;,&quot;#de4489&quot; %&#125;写法，还有今天刚看到的&#123;% bubble clip-path,&quot;clip-path属性使用裁剪方式创建元素的可显示区域。区域内的部分显示，区域外的隐藏。&quot;,&quot;#868fd7&quot; %&#125;属性。这些对我来说很新颖的概念狠狠的冲击着我以前积累起来的设计思路。</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>最近我学到了不少新玩意儿（虽然对很多大佬来说这些已经是旧技术了），比如 CSS 的<span class="bubble-content">兄弟相邻选择器</span><span class="bubble-notation"><span class="bubble-item" style="background-color:#71a4e3;">例如 h1 + p {margin-top:50px;}</span></span>，<span class="bubble-content">flex布局</span><span class="bubble-notation"><span class="bubble-item" style="background-color:#ec5830;">Flex 是 Flexible Box 的缩写，意为弹性布局&quot;，用来为盒状模型提供最大的灵活性&quot;</span></span>，<span class="bubble-content">transform变换</span><span class="bubble-notation"><span class="bubble-item" style="background-color:#1db675;">transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。</span></span>，animation 的<span class="bubble-content">贝塞尔速度曲线</span><span class="bubble-notation"><span class="bubble-item" style="background-color:#de4489;">贝塞尔曲线(Bézier curve)，又称贝兹曲线或贝济埃曲线，是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线，贝兹曲线由线段与节点组成，节点是可拖动的支点，线段像可伸缩的皮筋</span></span>写法，还有今天刚看到的<span class="bubble-content">clip-path</span><span class="bubble-notation"><span class="bubble-item" style="background-color:#868fd7;">clip-path属性使用裁剪方式创建元素的可显示区域。区域内的部分显示，区域外的隐藏。</span></span>属性。这些对我来说很新颖的概念狠狠的冲击着我以前积累起来的设计思路。</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-28-引用文献-reference">2.28 引用文献 reference</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;% referto [id] , [literature] %&#125;</span><br><span class="line">&#123;% referfrom [id] , [literature] , [url] %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><p>referto 引用上标</p><ul><li><p><code>id</code>: 上标序号内容，需与 referfrom 标签的 id 对应才能实现跳转</p></li><li><p><code>literature</code>: 引用的参考文献名称</p></li></ul></li><li><p>referfrom 引用出处</p><ul><li><p><code>id</code>: 序号内容，需与 referto 标签的 id 对应才能实现 跳转</p></li><li><p><code>literature</code>: 引用的参考文献名称</p></li><li><p><code>url</code>: 引用的参考文献链接，可省略</p></li></ul></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">Akilarの糖果屋(akilar.top)是一个私人性质的博客&#123;% referto &#x27;[1]&#x27;,&#x27;Akilarの糖果屋群聊简介&#x27; %&#125;，从各类教程至生活点滴，无话不谈。建群的目的是提供一个闲聊的场所。博客采用Hexo框架&#123;% referto &#x27;[2]&#x27;,&#x27;Hexo中文文档&#x27; %&#125;，Butterfly主题&#123;% referto &#x27;[3]&#x27;,&#x27;Butterfly 安装文档(一) 快速开始&#x27; %&#125;</span><br><span class="line"></span><br><span class="line">本项目参考了Volantis&#123;% referto &#x27;[4]&#x27;,&#x27;hexo-theme-volantis 标签插件&#x27; %&#125;的标签样式。引入<span class="code">`[tag].js`</span>，并针对<span class="code">`butterfly`</span>主题修改了相应的<span class="code">`[tag].styl`</span>。在此鸣谢<span class="code">`Volantis`</span>主题众开发者。</span><br><span class="line">主要参考内容包括各个volantis的内置标签插件文档&#123;% referto &#x27;[5]&#x27;,&#x27;Volantis文档:内置标签插件&#x27; %&#125;</span><br><span class="line">Butterfly主题的各个衍生魔改&#123;% referto &#x27;[6]&#x27;,&#x27;Butterfly 安装文档:标签外挂（Tag Plugins&#x27; %&#125;&#123;% referto &#x27;[7]&#x27;,&#x27;小弋の生活馆全样式预览&#x27; %&#125;&#123;% referto &#x27;[8]&#x27;,&#x27;l-lin-font-awesome-animation&#x27; %&#125;&#123;% referto &#x27;[9]&#x27;,&#x27;小康的butterfly主题使用文档&#x27; %&#125;</span><br><span class="line"></span><br><span class="line">&#123;% referfrom &#x27;[1]&#x27;,&#x27;Akilarの糖果屋群聊简介&#x27;,&#x27;https://jq.qq.com/?<span class="emphasis">_wv=1027&amp;k=pGLB2C0N&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[2]&#x27;,&#x27;Hexo中文文档&#x27;,&#x27;https://hexo.io/zh-cn/docs/&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[3]&#x27;,&#x27;Butterfly 安装文档(一) 快速开始&#x27;,&#x27;https://butterfly.js.org/posts/21cfbf15/&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[4]&#x27;,&#x27;hexo-theme-volantis 标签插件&#x27;,&#x27;https://volantis.js.org/v5/tag-plugins/&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[5]&#x27;,&#x27;Volantis文档:内置标签插件&#x27;,&#x27;https://volantis.js.org/tag-plugins/&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[6]&#x27;,&#x27;Butterfly 安装文档:标签外挂（Tag Plugins&#x27;,&#x27;https://butterfly.js.org/posts/4aa8abbe/#%E6%A8%99%E7%B1%A4%E5%A4%96%E6%8E%9B%EF%BC%88Tag-Plugins%EF%BC%89&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[7]&#x27;,&#x27;小弋の生活馆全样式预览&#x27;,&#x27;https://lovelijunyi.gitee.io/posts/c898.html&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[8]&#x27;,&#x27;l-lin-font-awesome-animation&#x27;,&#x27;https://github.com/l-lin/font-awesome-animation&#x27; %&#125;</span></span><br><span class="line"><span class="emphasis">&#123;% referfrom &#x27;[9]&#x27;,&#x27;小康的butterfly主题使用文档&#x27;,&#x27;https://www.antmoe.com/posts/3b43914f/&#x27; %&#125;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>Akilar の糖果屋(akilar.top)是一个私人性质的博客<span class="hidden-anchor" id="referto_[1]"></span><sup class="reference"><a href="#referfrom_[1]">[1]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">Akilarの糖果屋群聊简介</span><span class="reference-title">参考资料</span></span></span>，从各类教程至生活点滴，无话不谈。建群的目的是提供一个闲聊的场所。博客采用 Hexo 框架<span class="hidden-anchor" id="referto_[2]"></span><sup class="reference"><a href="#referfrom_[2]">[2]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">Hexo中文文档</span><span class="reference-title">参考资料</span></span></span>，Butterfly 主题<span class="hidden-anchor" id="referto_[3]"></span><sup class="reference"><a href="#referfrom_[3]">[3]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">Butterfly 安装文档(一) 快速开始</span><span class="reference-title">参考资料</span></span></span></p><p>本项目参考了 Volantis<span class="hidden-anchor" id="referto_[4]"></span><sup class="reference"><a href="#referfrom_[4]">[4]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">hexo-theme-volantis 标签插件</span><span class="reference-title">参考资料</span></span></span>的标签样式。引入<code>[tag].js</code>，并针对<code>butterfly</code>主题修改了相应的<code>[tag].styl</code>。在此鸣谢<code>Volantis</code>主题众开发者。<br>主要参考内容包括各个 volantis 的内置标签插件文档<span class="hidden-anchor" id="referto_[5]"></span><sup class="reference"><a href="#referfrom_[5]">[5]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">Volantis文档:内置标签插件</span><span class="reference-title">参考资料</span></span></span><br>Butterfly 主题的各个衍生魔改<span class="hidden-anchor" id="referto_[6]"></span><sup class="reference"><a href="#referfrom_[6]">[6]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">Butterfly 安装文档:标签外挂（Tag Plugins</span><span class="reference-title">参考资料</span></span></span><span class="hidden-anchor" id="referto_[7]"></span><sup class="reference"><a href="#referfrom_[7]">[7]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">小弋の生活馆全样式预览</span><span class="reference-title">参考资料</span></span></span><span class="hidden-anchor" id="referto_[8]"></span><sup class="reference"><a href="#referfrom_[8]">[8]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">l-lin-font-awesome-animation</span><span class="reference-title">参考资料</span></span></span><span class="hidden-anchor" id="referto_[9]"></span><sup class="reference"><a href="#referfrom_[9]">[9]</a></sup><span class="reference-bubble"><span class="reference-item"><span class="reference-literature">小康的butterfly主题使用文档</span><span class="reference-title">参考资料</span></span></span></p><div class="reference-source"><span class="hidden-anchor" id="referfrom_[1]"></span><a class="reference-anchor" href="#referto_[1]">[1]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://jq.qq.com/?_wv=1027&k=pGLB2C0N">Akilarの糖果屋群聊简介</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[2]"></span><a class="reference-anchor" href="#referto_[2]">[2]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://hexo.io/zh-cn/docs/">Hexo中文文档</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[3]"></span><a class="reference-anchor" href="#referto_[3]">[3]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://butterfly.js.org/posts/21cfbf15/">Butterfly 安装文档(一) 快速开始</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[4]"></span><a class="reference-anchor" href="#referto_[4]">[4]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://volantis.js.org/v5/tag-plugins/">hexo-theme-volantis 标签插件</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[5]"></span><a class="reference-anchor" href="#referto_[5]">[5]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://volantis.js.org/tag-plugins/">Volantis文档:内置标签插件</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[6]"></span><a class="reference-anchor" href="#referto_[6]">[6]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://butterfly.js.org/posts/4aa8abbe/#%E6%A8%99%E7%B1%A4%E5%A4%96%E6%8E%9B%EF%BC%88Tag-Plugins%EF%BC%89">Butterfly 安装文档:标签外挂（Tag Plugins</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[7]"></span><a class="reference-anchor" href="#referto_[7]">[7]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://lovelijunyi.gitee.io/posts/c898.html">小弋の生活馆全样式预览</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[8]"></span><a class="reference-anchor" href="#referto_[8]">[8]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://github.com/l-lin/font-awesome-animation">l-lin-font-awesome-animation</a></div><div class="reference-source"><span class="hidden-anchor" id="referfrom_[9]"></span><a class="reference-anchor" href="#referto_[9]">[9]<div class="reference-anchor-up fa-solid fa-angles-up"></div></a><a class="reference-link" href="https://www.antmoe.com/posts/3b43914f/">小康的butterfly主题使用文档</a></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-29-PDF-展示">2.29 PDF 展示</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% pdf 文件路径 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li><code>文件路径</code>: 可以是相对路径或者是在线链接</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 1.本地文件:在md文件路径下创建一个同名文件夹，其内放pdf文件名为xxx.pdf的文件</span></span><br><span class="line">&#123;% pdf xxx.pdf %&#125;</span><br><span class="line"><span class="section"># 2.在线链接</span></span><br><span class="line">&#123;% pdf https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/pdf/小作文讲义.pdf %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><p>2.在线链接(要放到最外层才能起作用)</p><pre><code>&lt;div class=&quot;row&quot;&gt;&lt;embed src=&quot;https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/pdf/小作文讲义.pdf&quot; width=&quot;100%&quot; height=&quot;550&quot; type=&quot;application/pdf&quot;&gt;&lt;/div&gt;</code></pre><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-30-Hexo-tag-map-插件">2.30 Hexo-tag-map 插件</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% + 标签值 + 经度 + 纬度 + 文本 + 缩放等级 + 宽 + 高 + 默认图层 + %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><table><thead><tr><th style="text-align:center">地图名</th><th style="text-align:center">标签值 &lt;必填&gt;</th><th style="text-align:center">宽 (默认 100%) / 高 (默认 360px)</th><th style="text-align:center">缩放等级 (默认 14)</th><th style="text-align:center">宽 (默认 100%) / 高 (默认 360px)</th><th style="text-align:center">默认图层 (默认 1)</th></tr></thead><tbody><tr><td style="text-align:center">混合地图</td><td style="text-align:center">map</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 3~18</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~7</td></tr><tr><td style="text-align:center">谷歌地图</td><td style="text-align:center">googleMap</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~20</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~3</td></tr><tr><td style="text-align:center">高德地图</td><td style="text-align:center">gaodeMap</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 3~18</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~3</td></tr><tr><td style="text-align:center">百度地图</td><td style="text-align:center">baiduMap</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 4~18</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~2</td></tr><tr><td style="text-align:center">Geoq 地图</td><td style="text-align:center">geoqMap</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~18</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~5</td></tr><tr><td style="text-align:center">openstreet 地图</td><td style="text-align:center">openstreetMap</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">取值 1~18</td><td style="text-align:center">百分数或具体值 (100% 或 360px)</td><td style="text-align:center">不支持此参数</td></tr></tbody></table><ol><li>参数之间，用英文逗号相隔</li><li>参数必须按上述事例顺序输入，不得为空</li><li>同一个页面，同一组经纬度值，只能插入一个相同标签值的地图 (若有需要，可以将第二个地图上，经度或纬度末尾删除一两个数)</li><li>参数取值必须在上述范围内</li><li>默认图层：即地图叠加层的值，默认常规地图还是卫星地图，可按地图显示顺序取值</li><li>缩放等级，数字越大，地图比例尺越小，显示的越精细</li><li>除标签值外，其他参数选填，但 每个参数的左边的参数必填</li><li>谷歌地图需要外网才能加载查看</li></ol><p>坐标获取：<a href="https://lbs.amap.com/tools/picker">高德地图坐标拾取系统</a> 、<a href="https://api.map.baidu.com/lbsapi/getpoint/index.html">百度地图坐标拾取系统</a></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% map 120.101101,30.239119 %&#125;</span><br><span class="line">&#123;% googleMap 120.101101,30.239119, 这里是西湖灵隐寺，据说求姻缘很灵验哦！ %&#125;</span><br><span class="line">&#123;% geoqMap 120.101101,30.239119, 这里是西湖灵隐寺，据说求姻缘很灵验哦！, 13, 90%, 320px, 3 %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><link rel="stylesheet" href="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.css"><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.js"></script><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet.ChineseTmsProviders@1.0.4.js"></script><div class="map-box" style="margin: 0.8rem 0 1.6rem 0;"><div id="map-120.101101-30.239119" style="max-width:100%; height:360px;display: block;margin:0 auto;z-index:1;border-radius: 5px;"></div></div><script type="text/javascript">var normalm=L.tileLayer.chinaProvider('GaoDe.Normal.Map',{maxZoom:20,minZoom:1,attribution:'高德地图'});var imgm=L.tileLayer.chinaProvider('GaoDe.Satellite.Map',{maxZoom:20,minZoom:1,attribution:'高德地图'});var imga=L.tileLayer.chinaProvider('GaoDe.Satellite.Annotion',{maxZoom:20,minZoom:1,attribution:'高德地图'});var normalMap=L.tileLayer.chinaProvider('Google.Normal.Map',{maxZoom:20,minZoom:1,attribution:'Google Maps'}),satelliteMap=L.tileLayer.chinaProvider('Google.Satellite.Map',{maxZoom:21,minZoom:1,attribution:'Google Maps'});routeMap=L.tileLayer.chinaProvider('Google.Satellite.Annotion',{maxZoom:21,minZoom:1});var normalMap=L.tileLayer.chinaProvider('Google.Normal.Map',{maxZoom:21,minZoom:1,attribution:'Google Maps'}),satelliteMap=L.tileLayer.chinaProvider('Google.Satellite.Map',{maxZoom:21,minZoom:1,attribution:'Google Maps'}),routeMap=L.tileLayer.chinaProvider('Google.Satellite.Annotion',{maxZoom:21,minZoom:1,attribution:'Google Maps'});var normalm1=L.tileLayer.chinaProvider('Geoq.Normal.Map',{maxZoom:21,minZoom:1,attribution:'GeoQ'});var normal=L.layerGroup([normalm]),image=L.layerGroup([imgm,imga]);var baseLayers={"高德地图":normal,"智图地图":normalm1,"谷歌地图":normalMap,"高德卫星地图":imgm,"谷歌卫星地图":satelliteMap,"高德卫星标注":image,"谷歌卫星标注":routeMap};var mymap=L.map('map-120.101101-30.239119',{center:[30.239119,120.101101],zoom:14,layers:[normal],zoomControl:false});L.control.layers(baseLayers,null).addTo(mymap);L.control.zoom({zoomInTitle:'放大',zoomOutTitle:'缩小'}).addTo(mymap);</script><br><link rel="stylesheet" href="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.css"><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.js"></script><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet.ChineseTmsProviders@1.0.4.js"></script><div id="googleMap-120.101101-30.239119" style="max-width:100%; height:360px;display: block;margin:0 auto;z-index:1;border-radius: 5px;"></div><script type="text/javascript">var normalMap=L.tileLayer.chinaProvider('Google.Normal.Map',{maxZoom:22,minZoom:1,attribution:'Google Maps'}),satelliteMap=L.tileLayer.chinaProvider('Google.Satellite.Map',{maxZoom:22,minZoom:1,attribution:'Google Maps'}),routeMap=L.tileLayer.chinaProvider('Google.Satellite.Annotion',{maxZoom:22,minZoom:1,attribution:'Google Maps'});var baseLayers={"谷歌地图":normalMap,"谷歌卫星图":satelliteMap,"谷歌卫星标注": routeMap};var overlayLayers={};var mymap=L.map("googleMap-120.101101-30.239119",{center:[30.239119,120.101101],zoom:14,layers:[normalMap],zoomControl:false});L.control.layers(baseLayers,null).addTo(mymap);L.control.zoom({zoomInTitle:'放大',zoomOutTitle:'缩小'}).addTo(mymap);var marker = L.marker(['30.239119','120.101101']).addTo(mymap);marker.bindPopup("这里是西湖灵隐寺，据说求姻缘很灵验哦！").openPopup();</script><br><link rel="stylesheet" href="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.css"><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet@1.7.1.js"></script><script data-pjax src="//unpkg.com/hexo-tag-map/lib/leaflet.ChineseTmsProviders@1.0.4.js"></script><div id="geoqMap-120.101101-30.239119" style="max-width:90%; height:320px;display: block;margin:0 auto;z-index:1;border-radius: 5px;"></div><script type="text/javascript">var normalm1=L.tileLayer.chinaProvider('Geoq.Normal.Map',{maxZoom:20,minZoom:1,attribution:'GeoQ'});var normalm2=L.tileLayer.chinaProvider('Geoq.Normal.PurplishBlue',{maxZoom:20,minZoom:1,attribution:'GeoQ'});var normalm3=L.tileLayer.chinaProvider('Geoq.Normal.Gray',{maxZoom:20,minZoom:1,attribution:'GeoQ'});var normalm4=L.tileLayer.chinaProvider('Geoq.Normal.Warm',{maxZoom:20,minZoom:1,attribution:'GeoQ'});var normalm5=L.tileLayer.chinaProvider('Geoq.Theme.Hydro',{maxZoom:20,minZoom:1,attribution:'GeoQ'});var normal=L.layerGroup([normalm1,normalm2,normalm3,normalm4,normalm5]);var baseLayers={"智图地图":normalm1,"午夜蓝":normalm2,"灰色":normalm3,"暖色":normalm4,"水系":normalm5};var mymap=L.map("geoqMap-120.101101-30.239119",{center:[30.239119,120.101101],zoom:13,layers:[normalm3],zoomControl:false});L.control.layers(baseLayers,null).addTo(mymap);L.control.zoom({zoomInTitle:'放大',zoomOutTitle:'缩小'}).addTo(mymap);var marker = L.marker(['30.239119','120.101101']).addTo(mymap);marker.bindPopup("这里是西湖灵隐寺，据说求姻缘很灵验哦！").openPopup();</script><br><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="2-31-隐藏块">2.31 隐藏块</h2><div class="tabs" id="分栏"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#分栏-1">标签语法</button></li><li class="tab"><button type="button" data-href="#分栏-2">参数配置</button></li><li class="tab"><button type="button" data-href="#分栏-3">示例源码</button></li><li class="tab"><button type="button" data-href="#分栏-4">渲染演示</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="分栏-1"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;% hideBlock display,bg,color %&#125;</span><br><span class="line">content</span><br><span class="line">&#123;% endhideBlock %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-2"><ol><li>content：要隐藏的内容</li><li>display：展示前按钮显示的文字（可选）</li><li>bg：按钮的背景颜色（可选）</li><li>color：按钮显示的文字的颜色（可选）</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-3"><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% hideBlock 点我预览, blue %&#125;</span><br><span class="line">这里有张图片：</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&quot;https://s1.vika.cn/space/2022/10/30/b35fce448bc9404a8d65c3ce1e6e46eb&quot;</span> <span class="attr">alt</span>=<span class="string">&quot;image (1)&quot;</span> <span class="attr">style</span>=<span class="string">&quot;zoom:67%;&quot;</span> /&gt;</span></span></span><br><span class="line">&#123;% endhideBlock %&#125;</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="分栏-4"><div class="hide-block"><button type="button" class="hide-button" style="background-color:  blue;">点我预览    </button><div class="hide-content"><p>这里有张图片：<br><img src="https://s1.vika.cn/space/2022/10/30/b35fce448bc9404a8d65c3ce1e6e46eb" alt="image (1)" style="zoom:67%;" /></p></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h1>鸣谢</h1><div class="note default flat"><p>文章参考于：<br><a href="https://www.fomal.cc/posts/2013454d.html">www.fomal.cc的个人博客</a><br><a href="https://blog.csdn.net/xdnxl/article/details/129518943">MarkDown 语法大总结【全网汇总，从 0 到深大全版】</a><br><a href="https://blog.csdn.net/u014061630/article/details/81359144">Markdown 语法图文全面详解(10 分钟学会)</a><br><a href="https://blog.csdn.net/qq_43732429/article/details/108034518">Markdown 语法字体颜色大小及文字底色设置</a></p></div>]]></content>
    
    
    <summary type="html">🥧本文汇总Markdown格式以及外挂标签在网页端的渲染效果，可作为文档进行查询</summary>
    
    
    
    <category term="Web" scheme="https://home.y1xuanyun.cn/categories/Web/"/>
    
    
    <category term="语法" scheme="https://home.y1xuanyun.cn/tags/%E8%AF%AD%E6%B3%95/"/>
    
    <category term="指南" scheme="https://home.y1xuanyun.cn/tags/%E6%8C%87%E5%8D%97/"/>
    
    <category term="Markdown" scheme="https://home.y1xuanyun.cn/tags/Markdown/"/>
    
    <category term="外挂标签" scheme="https://home.y1xuanyun.cn/tags/%E5%A4%96%E6%8C%82%E6%A0%87%E7%AD%BE/"/>
    
  </entry>
  
  <entry>
    <title>算法经典题型解析（C++）</title>
    <link href="https://home.y1xuanyun.cn/posts/24cpp02.html"/>
    <id>https://home.y1xuanyun.cn/posts/24cpp02.html</id>
    <published>2024-06-01T10:00:00.000Z</published>
    <updated>2024-09-20T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>前言</h1><div class="note info flat"><p>本篇文稿为站长阶段性学习笔记，建议读者精通C++包含STL并深入学习数据结构的前提下阅读。</p></div><h1>滑动检索/双指针/前缀和</h1><p>一般和数据结构中的队列相似，符合先进先出规则，区别为需不断更新处理数据</p><h2 id="核心：载入💾更新💽弹出🖨️">核心：载入💾更新💽弹出🖨️</h2><ol><li>载入💾：下标为<code>i</code>的元素进入窗口，更新相关统计量。</li></ol><div class="note info flat"><p>当<code>窗口载入&lt;窗口长度</code>时即<code>i&lt;k−1 </code>，需不断重复执行该步骤填满窗口</p></div><ol start="2"><li>更新💽：更新答案，检索并处理<code>在窗数据</code>。一般是更新最大值/最小值/平均值。</li><li>弹出🖨️：下标为<code>i−k+1</code>的元素离开窗口，更新相关统计量。</li></ol><h2 id="注意事项">注意事项</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">double</span> m_age = <span class="number">-1000</span>; <span class="comment">// 注意初始化特殊情况</span></span><br><span class="line"><span class="keyword">if</span>(i &lt; k - <span class="number">1</span>) <span class="keyword">continue</span>; <span class="comment">// 满窗即可运行 i=k-1时</span></span><br><span class="line">iw = <span class="built_in">min</span>(w, iw); <span class="comment">// 注意逻辑顺序，先结算后移动</span></span><br></pre></td></tr></table></figure><h2 id="例题-半径为-k-的子数组平均值">例题: 半径为 k 的子数组平均值</h2><blockquote><p>给你一个下标从 0 开始的数组 nums ，数组中有 n 个整数，另给你一个整数 k 。<br>半径为 k 的子数组平均值 是指：nums 中一个以下标 i 为 中心 且 半径 为 k 的子数组中所有元素的平均值，即下标在 i - k 和 i + k 范围（含 i - k 和 i + k）内所有元素的平均值。如果在下标 i 前或&gt; 后不足 k 个元素，那么 半径为 k 的子数组平均值 是 -1 。<br>构建并返回一个长度为 n 的数组 avgs ，其中 avgs[i] 是以下标 i 为中心的子数组的 半径为 k 的子数组平均值 。<br>x 个元素的 平均值 是 x 个元素相加之和除以 x ，此时使用截断式 整数除法 ，即需要去掉结果的小数部分。</p></blockquote><div class="note info flat"><p>例如，四个元素 2、3、1 和 5 的平均值是 (2 + 3 + 1 + 5) / 4 = 11 / 4 = 2.75，截断后得到 2 。</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">getAverages</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums, <span class="type">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> n = nums.<span class="built_in">size</span>();</span><br><span class="line">        <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">ans</span><span class="params">(n, <span class="number">-1</span>)</span></span>; </span><br><span class="line">        <span class="comment">// 特殊情况筛选=窗&gt;数组，左右和本身2k+1</span></span><br><span class="line">        <span class="keyword">if</span> (k * <span class="number">2</span> + <span class="number">1</span> &lt;= n) &#123; </span><br><span class="line">            <span class="type">long</span> <span class="type">long</span> sum =</span><br><span class="line">                <span class="built_in">accumulate</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">begin</span>() + k * <span class="number">2</span> + <span class="number">1</span>, <span class="number">0LL</span>);</span><br><span class="line">            <span class="comment">// 等同于循环求和，窗口全部载入</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> i = k; i + k &lt; n; ++i) &#123; </span><br><span class="line">              <span class="comment">// k为中心，移动</span></span><br><span class="line">                <span class="keyword">if</span> (i != k) &#123;</span><br><span class="line">                    sum += nums[i + k] - nums[i - k - <span class="number">1</span>]; <span class="comment">// 滑动更新</span></span><br><span class="line">                &#125;</span><br><span class="line">                ans[i] = sum / (k * <span class="number">2</span> + <span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1>二分查找/最值算法</h1><h2 id="核心：定区🧵收束🪡边界判断🖼️">核心：定区🧵收束🪡边界判断🖼️</h2><ol><li>定区🧵：<br>通常设置三个变量：二分中间值<code>mid</code>、左边界<code>left</code>，右边界<code>right</code></li><li>收束🪡：不断求取二分值覆盖边界以压缩区间<br>以中间值<code>mid</code>来将其赋值给左或右区间作边界</li><li>边界判断🖼️：通常可选闭、开、半开闭区间，其影响<code>区间定义</code>、<code>收束条件</code>、<code>终止判断</code><br>闭区间：边界可与数据覆盖，直接判断收束，重叠即终止<br>开区间：边界包围数据，判断收束需加减，包围仅一数据终止</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="comment">//区间定义</span></span><br><span class="line"><span class="keyword">while</span>()&#123;<span class="comment">//收束终止判断</span></span><br><span class="line">    <span class="keyword">if</span>()&#123;<span class="comment">//收束条件</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125; </span><br><span class="line">m%<span class="number">2</span>==<span class="number">0</span>?m=m/<span class="number">2</span>:m=(m<span class="number">+1</span>)/<span class="number">2</span>;  <span class="comment">//此处获取二分值，缺点：int类型取整</span></span><br><span class="line">left&lt;X&amp;&amp;right&lt;X?left=m:right=m;  <span class="comment">//根据对比结果将二分指赋为区间边界</span></span><br><span class="line"><span class="comment">//上述为直观二分法，不推荐使用，仅为方便理解</span></span><br><span class="line"><span class="type">int</span> mid,left=<span class="number">0</span>,right=nums.<span class="built_in">size</span>()<span class="number">-1</span>;<span class="comment">//1.定区 此为闭区间写法</span></span><br><span class="line">mid=left+(right-left)/<span class="number">2</span>;<span class="comment">//2.收束 此为逻辑写法</span></span><br><span class="line">mid=(right+left)/<span class="number">2</span>;<span class="comment">//此为简化写法</span></span><br></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 闭区间写法</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">lower_bound</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> left = <span class="number">0</span>, right = (<span class="type">int</span>) nums.<span class="built_in">size</span>() - <span class="number">1</span>; <span class="comment">// 闭区间 [left, right]</span></span><br><span class="line">    <span class="keyword">while</span> (left &lt;= right) &#123; <span class="comment">// 区间不为空</span></span><br><span class="line">        <span class="type">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid] &lt; target) &#123;<span class="comment">// nums[left-1] &lt; target</span></span><br><span class="line">            left = mid + <span class="number">1</span>; <span class="comment">// 范围左缩小到 [mid+1, right]</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;<span class="comment">// nums[right+1] &gt;= target</span></span><br><span class="line">            right = mid - <span class="number">1</span>; <span class="comment">// 范围右缩小到 [left, mid-1]</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 左闭右开区间写法</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">lower_bound2</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> left = <span class="number">0</span>, right = nums.<span class="built_in">size</span>(); <span class="comment">// 左闭右开区间 [left, right)</span></span><br><span class="line">    <span class="keyword">while</span> (left &lt; right) &#123; <span class="comment">// 区间不为空</span></span><br><span class="line">        <span class="type">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid] &lt; target) &#123; <span class="comment">// nums[left-1] &lt; target</span></span><br><span class="line">            left = mid + <span class="number">1</span>; <span class="comment">// 范围缩小到 [mid+1, right)</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;<span class="comment">// nums[right] &gt;= target</span></span><br><span class="line">            right = mid; <span class="comment">// 范围缩小到 [left, mid)</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 开区间写法</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">lower_bound3</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> left = <span class="number">-1</span>, right = nums.<span class="built_in">size</span>(); <span class="comment">// 开区间 (left, right)</span></span><br><span class="line">    <span class="keyword">while</span> (left + <span class="number">1</span> &lt; right) &#123; <span class="comment">// 区间不为空</span></span><br><span class="line">        <span class="type">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid] &lt; target) &#123;<span class="comment">// nums[left] &lt; target</span></span><br><span class="line">            left = mid; <span class="comment">// 范围缩小到 (mid, right)</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;<span class="comment">// nums[right] &gt;= target</span></span><br><span class="line">            right = mid; <span class="comment">// 范围缩小到 (left, mid)</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> right;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="注意事项-2">注意事项</h2><p><code>mid</code>是否能将区间均分不重要，应关注区间如何收束</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 明确循环不变量：</span></span><br><span class="line">nums[left] <span class="comment">//闭区间加减</span></span><br><span class="line">nums[right] <span class="comment">//开区间不便</span></span><br><span class="line">nums[mid] <span class="comment">//由区间类型定义</span></span><br><span class="line"><span class="comment">// 常用二分收束</span></span><br><span class="line"><span class="type">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br></pre></td></tr></table></figure><h2 id="例题-统计公平数对的数目">例题: 统计公平数对的数目</h2><blockquote><p>给你一个下标从 0 开始、长度为 n 的整数数组 nums ，和两个整数 lower 和 upper ，返回 公平数对的数目 。<br>如果 (i, j) 数对满足以下情况，则认为它是一个 公平数对 ：<br>0 &lt;= i &lt; j &lt; n，且<br>lower &lt;= nums[i] + nums[j] &lt;= upper</p></blockquote><div class="note info flat"><p>例如，输入：nums = [0,1,7,4,4,5], lower = 3, upper = 6 ；输出：6 ；<br>解释：共计 6 个公平数对：(0,3)、(0,4)、(0,5)、(1,3)、(1,4) 和 (1,5) 。</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="type">long</span> <span class="title">countFairPairs</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> lower, <span class="type">int</span> upper)</span> </span>&#123;</span><br><span class="line">        <span class="type">long</span> ans = <span class="number">0</span>;</span><br><span class="line">        Arrays.<span class="built_in">sort</span>(nums);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; nums.length; ++j) &#123;</span><br><span class="line">            <span class="type">int</span> r = <span class="built_in">lowerBound</span>(nums, j, upper - nums[j] + <span class="number">1</span>); <span class="comment">// &lt;= upper-nums[j] 的 nums[i] 的个数</span></span><br><span class="line">            <span class="type">int</span> l = <span class="built_in">lowerBound</span>(nums, j, lower - nums[j]); <span class="comment">// &lt; lower-nums[j] 的 nums[i] 的个数</span></span><br><span class="line">            ans += r - l;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="type">int</span> <span class="title">lowerBound</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> right, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> left = <span class="number">-1</span>; <span class="comment">// 开区间 (left, right)</span></span><br><span class="line">        <span class="keyword">while</span> (left + <span class="number">1</span> &lt; right) &#123; <span class="comment">// 区间不为空</span></span><br><span class="line">            <span class="comment">// 循环不变量：</span></span><br><span class="line">            <span class="comment">// nums[left] &lt; target</span></span><br><span class="line">            <span class="comment">// nums[right] &gt;= target</span></span><br><span class="line">            <span class="type">int</span> mid = (left + right) &gt;&gt;&gt; <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] &lt; target)</span><br><span class="line">                left = mid; <span class="comment">// 范围缩小到 (mid, right)</span></span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                right = mid; <span class="comment">// 范围缩小到 (left, mid)</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> right;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>递归搜索树/DFS/BFS💎</h1><h2 id="核心：寻根🔍纵深🥏递归终止🎯">核心：寻根🔍纵深🥏递归终止🎯</h2><ol><li>寻找根节点，分析问题，来确定根节点如何开始。</li><li>树型数据结构深度，通常与问题中的数据数目相互挂钩。</li><li>选择合适的递归终止的判断条件，并记录结果，以减少运算时间。</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">fun</span><span class="params">(<span class="type">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">//逻辑代码区，递归终止条件</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">fun</span>(a) + <span class="built_in">fun</span>(b) + ...;<span class="comment">//树型递归</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="注意事项-3">注意事项</h2><p>不应关注楼梯阶数，应思考每一步的选择，根据选择判断阶数是否达标<br>在输入数据的问题规模&lt;10^5,两者速度差不多，当问题规模&gt;10^5,cin和cout速度将会慢一倍或更多。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//输入输出流选择</span></span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;n);</span><br><span class="line">cin &gt;&gt; n;<span class="comment">//不推荐</span></span><br></pre></td></tr></table></figure><h2 id="例题">例题:</h2><blockquote><p>一个楼梯共有 n级台阶，每次可以走一级或者两级，问从第0级台阶走到第n级台阶一共有多少种方案。</p></blockquote><div class="note info flat"><p>1≤n≤15,输入格式:共一行，包含一个整数 n;输出格式:共一行，包含一个整数，表示方案数。</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">dg</span><span class="params">(<span class="type">int</span> dep)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (dep == <span class="number">1</span>)  <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (dep == <span class="number">2</span>)  <span class="keyword">return</span> <span class="number">2</span>; </span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">dg</span>(dep - <span class="number">1</span>) + <span class="built_in">dg</span>(dep - <span class="number">2</span>);<span class="comment">//树形递归，统计所有情况</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;n);<span class="comment">//录入台阶数n</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%d\n&quot;</span>, <span class="built_in">dg</span>(n)); <span class="comment">//n--&gt;dep</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>动态规划（DP）/记忆化搜索💎</h1><h2 id="核心：暴力🥊记忆🎰动态规划📊">核心：暴力🥊记忆🎰动态规划📊</h2><ol><li>暴力递归：<br>会随着数据量的增大时间复杂度呈指数型上升，最终会有超时的风险。</li><li>记忆化搜索：<br>是在暴力递归的基础上对中间过程进行过计算的结果进行保存，以便在下一次递归调用的时候可以直接读取，一般经过记忆化优化，在数据量很大的情况下，效果很明显。</li><li>动态规划：<br>动态规划常用来解决方案数和最优解两类问题，当前状态往往都是有前一步子问题的状态推导而来，存在递推公式。</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//记忆化搜索，通常借助哈希表实现对重复数据的检索</span></span><br><span class="line">Map&lt;Integer, Integer&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"><span class="comment">//语法详见《算法基础导读》</span></span><br></pre></td></tr></table></figure><h2 id="例题-数组返回特定和">例题: 数组返回特定和</h2><blockquote><p>给你一个由 不同 整数组成的数组 nums ，和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。<br>题目数据保证答案符合 32 位整数范围。</p></blockquote><div class="note info flat"><p>暴力搜索dfs+回溯会超时，可以考虑使用dfs+备忘录的模式，一般是优化dfs，也就是记忆化搜索。</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    Map&lt;Integer, Integer&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">    <span class="comment">/*使用map，记录递归过程sum的值，以及出现的次数；下一次需要sum的时候，如果map中存在，直接取出来即可，因为之前已经计算过了 */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">dfs</span>(nums, target, <span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="type">int</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target, <span class="type">int</span> sum)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (sum == target) &#123; <span class="comment">//特殊情况处理</span></span><br><span class="line">            <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 当前sum值在备忘录中已经计算过，则直接取出来返回</span></span><br><span class="line">        <span class="keyword">if</span> (map.<span class="built_in">containsKey</span>(sum)) &#123;</span><br><span class="line">            <span class="keyword">return</span> map.<span class="built_in">get</span>(sum);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 每一层都可以从数组的0位置开始搜索</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            <span class="comment">// 添加限制条件</span></span><br><span class="line">            <span class="keyword">if</span> (sum + num &lt;= target) &#123;</span><br><span class="line">                res += <span class="built_in">dfs</span>(nums, target, sum + num);</span><br><span class="line">                <span class="comment">// 一定要将当前计算的结果存到备忘录中</span></span><br><span class="line">                map.<span class="built_in">put</span>(sum, res);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><div class="note info flat"><p>求方案个数，还有一种思路就是利用动态规划的思想，定义dp数组表示 当目标值为n的时候数组中的组合方案数，存在递推公式：<code>f(n) = sum( f(n-i) ) 0&lt;i&lt;=n</code>且需要存在物品重量等于i，则可以循环物品，针对每一个小于等于n的物品，计算f(n-i)值累积求和.</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span>[] dp = <span class="keyword">new</span> <span class="type">int</span>[target + <span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">1</span>; <span class="comment">//对特殊情况的数组赋初值</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= target; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;<span class="comment">//快速遍历数组nums，省去for循环遍历</span></span><br><span class="line">                <span class="keyword">if</span> (num &lt;= i) &#123;</span><br><span class="line">                    dp[i] += dp[i-num];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[target];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="注意事项-4">注意事项</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> a : x) <span class="comment">//快速遍历，a:接收容器，x:遍历数组地址</span></span><br></pre></td></tr></table></figure><h1>贪心💎</h1><h2 id="核心：尝试✏️退回⌛最优解⏱️">核心：尝试✏️退回⌛最优解⏱️</h2><ol><li>先分析问题，将复杂问题简单化，结合暴力枚举，逐一尝试</li><li>通常需要根据题意创建两个或多个变量计数，以便可退回至最优解法</li><li>记录每次枚举是否最优，来共同组成最后答案</li></ol><h2 id="例题-返回最大子序列">例题: 返回最大子序列</h2><blockquote><p>给你一个下标从 0 开始的字符串 text 和另一个下标从 0 开始且长度为 2 的字符串 pattern ，两者都只包含小写英文字母。<br>你可以在 text 中任意位置插入<code>一个</code>字符，这个插入的字符必须是<code>pattern[0]</code>或者<code>pattern[1]</code>。注意，这个字符可以插入在 text 开头或者结尾的位置。<br>请你返回插入一个字符后，text 中最多包含多少个等于 pattern 的 子序列 。<br>子序列 指的是将一个字符串删除若干个字符后（也可以不删除），剩余字符保持原本顺序得到的字符串。</p></blockquote><div class="note info flat"><p>没有特判 x=y 的情况，要先更新答案，再更新 cnt_X，这可以保证更新答案时 cnt_X 表示的是当前字母左边的 x 的出现次数，cnt_X 尚未计入当前字母。</p></div><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">maximumSubsequenceCount</span><span class="params">(string text, string pattern)</span> </span>&#123;</span><br><span class="line">        <span class="type">char</span> x = pattern[<span class="number">0</span>], y = pattern[<span class="number">1</span>];<span class="comment">//分别提取插入字符</span></span><br><span class="line">        <span class="type">long</span> <span class="type">long</span> ans = <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> cnt_x = <span class="number">0</span>, cnt_y = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> c : text) &#123;<span class="comment">//快捷遍历</span></span><br><span class="line">            <span class="keyword">if</span> (c == y) &#123;<span class="comment">//可插入x</span></span><br><span class="line">                ans += cnt_x;<span class="comment">//简洁求和，类似二分</span></span><br><span class="line">                cnt_y++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (c == x) &#123;<span class="comment">//可插入y</span></span><br><span class="line">                cnt_x++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//因为可能x与y同时出现，会导致计数重复</span></span><br><span class="line">        <span class="keyword">return</span> ans + <span class="built_in">max</span>(cnt_x, cnt_y);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1>特别鸣谢</h1><div class="note default flat"><p>思路参考：<a href="https://leetcode.cn/u/endlesscheng/">茶灵山艾府</a></p></div>]]></content>
    
    
    <summary type="html">📝高频算法知识点📊与强思维例题⏱️题单汇总⌛</summary>
    
    
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/categories/%E7%AE%97%E6%B3%95/"/>
    
    
    <category term="C++" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="数据结构" scheme="https://home.y1xuanyun.cn/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    
    <category term="题单" scheme="https://home.y1xuanyun.cn/tags/%E9%A2%98%E5%8D%95/"/>
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="笔记" scheme="https://home.y1xuanyun.cn/tags/%E7%AC%94%E8%AE%B0/"/>
    
    <category term="进阶" scheme="https://home.y1xuanyun.cn/tags/%E8%BF%9B%E9%98%B6/"/>
    
  </entry>
  
  <entry>
    <title>C++算法基础题解(第393场周赛)</title>
    <link href="https://home.y1xuanyun.cn/posts/24czs02.html"/>
    <id>https://home.y1xuanyun.cn/posts/24czs02.html</id>
    <published>2024-04-14T10:00:00.000Z</published>
    <updated>2024-08-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>替换字符可以得到的最晚时间</h1><h2 id="题目">题目</h2><ol><li>给你一个字符串 s，表示一个 12 小时制的时间格式，其中一些数字（可能没有）被 “?” 替换。</li><li>12 小时制时间格式为 “HH:MM” ，其中 HH 的取值范围为 00 至 11，MM 的取值范围为 00 至 59。最早的时间为 00:00，最晚的时间为 11:59。</li><li>你需要将 s 中的 所有 “?” 字符替换为数字，使得结果字符串代表的时间是一个 有效 的 12 小时制时间，并且是可能的 最晚 时间。</li></ol><ul><li>返回结果字符串。</li></ul><h2 id="测试案例">测试案例</h2><blockquote><p><font color=rad>示例 1：<br>输入： s = “1?:?4”<br>输出： “11:54”<br>解释： 通过替换 “?” 字符，可以得到的最晚12小时制时间是 “11:54”。</p></blockquote><blockquote><p>示例 2：<br>输入： s = “0?:5?”<br>输出： “09:59”<br>解释： 通过替换 “?” 字符，可以得到的最晚12小时制时间是 “09:59”。<br></font></p></blockquote><h2 id="提示">提示</h2><div class="note info flat"><p>s.length == 5，且s[2] 是字符 “:”，除 s[2] 外，其他字符都是数字或 “?”<br>输入保证在替换 “?” 字符后至少存在一个介于 “00:00” 和 “11:59” 之间的时间。</p></div><h2 id="解析：">解析：</h2><blockquote><p><font>利用小时位范围（0-11）逐一遍历，优先置于最外层循环递减，并分层筛选特殊条件<font></p></blockquote><h2 id="代码示例">代码示例</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">string <span class="title">findLatestTime</span><span class="params">(string s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> h = <span class="number">11</span>; ; h--) &#123;</span><br><span class="line">            <span class="keyword">if</span> (s[<span class="number">0</span>] != <span class="string">&#x27;?&#x27;</span> &amp;&amp; s[<span class="number">0</span>] - <span class="string">&#x27;0&#x27;</span> != h / <span class="number">10</span> || s[<span class="number">1</span>] != <span class="string">&#x27;?&#x27;</span> &amp;&amp; s[<span class="number">1</span>] - <span class="string">&#x27;0&#x27;</span> != h % <span class="number">10</span>) &#123;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> m = <span class="number">59</span>; m &gt;= <span class="number">0</span>; m--) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s[<span class="number">3</span>] != <span class="string">&#x27;?&#x27;</span> &amp;&amp; s[<span class="number">3</span>] - <span class="string">&#x27;0&#x27;</span> != m / <span class="number">10</span> || s[<span class="number">4</span>] != <span class="string">&#x27;?&#x27;</span> &amp;&amp; s[<span class="number">4</span>] - <span class="string">&#x27;0&#x27;</span> != m % <span class="number">10</span>) &#123;</span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="type">char</span> ans[<span class="number">6</span>];</span><br><span class="line">                <span class="built_in">sprintf</span>(ans, <span class="string">&quot;%02d:%02d&quot;</span>, h, m);</span><br><span class="line">                <span class="keyword">return</span> <span class="built_in">string</span>(ans);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1>质数的最大距离</h1><h2 id="题目-2">题目</h2><ol><li>给你一个整数数组 nums。</li><li>返回两个（不一定不同的）质数在 nums 中下标的最大距离。</li></ol><h2 id="测试案例-2">测试案例</h2><blockquote><p><font color=rad>示例 1：<br>输入： nums = [4,2,9,5,3]<br>输出： 3<br>解释： nums[1]、nums[3] 和 nums[4] 是质数。因此答案是 |4 - 1| = 3。</p></blockquote><blockquote><p>示例 2：<br>输入： nums = [4,8,2,8]<br>输出： 0<br>解释： nums[2] 是质数。因为只有一个质数，所以答案是 |2 - 2| = 0。<br></font></p></blockquote><h2 id="提示-2">提示</h2><div class="note info flat"><p>1 &lt;= nums.length &lt;= 3 * 105 ， 1 &lt;= nums[i] &lt;= 100<br>输入保证 nums 中至少有一个质数。</p></div><h2 id="解析：-2">解析：</h2><blockquote><p><font><font></p></blockquote><h2 id="代码示例-2">代码示例</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">is_prime</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">2</span>; i * i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (n % i == <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> n &gt;= <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">maximumPrimeDifference</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (!<span class="built_in">is_prime</span>(nums[i])) &#123;</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> j = nums.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (!<span class="built_in">is_prime</span>(nums[j])) &#123;</span><br><span class="line">            j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> j - i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="致谢">致谢</h2><div class="note default flat"><p>思路来源：<a href="https://leetcode.cn/u/endlesscheng/">茶灵山艾府</a></p></div>]]></content>
    
    
    <summary type="html">⛳算法基础例题：1.替换字符可以得到的最晚时间 2.质数的最大距离</summary>
    
    
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/categories/%E7%AE%97%E6%B3%95/"/>
    
    
    <category term="C++" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="字符串" scheme="https://home.y1xuanyun.cn/tags/%E5%AD%97%E7%AC%A6%E4%B8%B2/"/>
    
    <category term="数学计算" scheme="https://home.y1xuanyun.cn/tags/%E6%95%B0%E5%AD%A6%E8%AE%A1%E7%AE%97/"/>
    
    <category term="LeetCode" scheme="https://home.y1xuanyun.cn/tags/LeetCode/"/>
    
    <category term="题解" scheme="https://home.y1xuanyun.cn/tags/%E9%A2%98%E8%A7%A3/"/>
    
  </entry>
  
  <entry>
    <title>微软office全家桶免费使用指南！</title>
    <link href="https://home.y1xuanyun.cn/posts/24pc01.html"/>
    <id>https://home.y1xuanyun.cn/posts/24pc01.html</id>
    <published>2024-03-23T10:00:00.000Z</published>
    <updated>2024-04-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="note warning flat"><p>免责声明：本篇博客遵循BY-NC-SA 4.0协议，仅作学习交流使用。</p></div><h2 id="准备工作">准备工作</h2><ul><li>前往下方连接下载微软office全家桶部署工具<code>Office Tool Plus</code>并打开</li></ul><div class="tag link"><a class="link-card" title="Office Tool Plus官网" href="https://otp.landian.vip/zh-cn/"><div class="left"><img src="https://otp.landian.vip/static/images/logo.webp"/></div><div class="right"><p class="text">Office Tool Plus官网</p><p class="url">https://otp.landian.vip/zh-cn/</p></div></a></div><br><h2 id="移除原有版本">移除原有版本</h2><p>侧边栏<code>工具箱</code>➡️office工具➡️移除office➡️移除</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/1.png"/></div></div><h2 id="部署office">部署office</h2><p>侧边栏<code>部署</code>➡️部署office➡️更新通道<code>半年度企业通道</code></p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/2.png"/></div></div><h2 id="产品列表选择">产品列表选择</h2><p>⏬当前页面下拉➡️产品列表➡️选择<code>Microsoft 365 企业应用版</code><br>可在下方勾选需要的office应用</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/3s.png"/></div></div><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/3.png"/></div></div><h2 id="添加许可证">添加许可证</h2><p>侧边栏<code>激活</code>➡️许可证管理➡️安装许可证➡️安装<code>Mondo 2016 批量许可证</code></p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/4.png"/></div></div><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/4s.png"/></div></div><h2 id="设置KMS主机">设置KMS主机</h2><p>⏬当前页面<code>下拉</code>➡️KMS管理➡️KMS主机➡️输入以下域名（三选一）➡️设置主机</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">kms.loli.beer:1688</span><br><span class="line">kms.loli.beer</span><br><span class="line">kms.catqu.beer</span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/5.png"/></div></div><h2 id="查看激活">查看激活</h2><p>⏬当前页面<code>下拉</code>➡️office许可证➡️许可证详细信息</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://file.y1xuanyun.cn/posts/24pc01/6.png"/></div></div><p>显示✅已激活，就代表成功了！！！✨✨✨</p><div class="note info flat"><p>虽然激活期限只有半年，但是该许可证会自动续期，无需担心失效问题</p></div>]]></content>
    
    
    <summary type="html">✨关于如何免费使用office办公软件，官方原装无第三方隐患插件</summary>
    
    
    
    <category term="演示" scheme="https://home.y1xuanyun.cn/categories/%E6%BC%94%E7%A4%BA/"/>
    
    
    <category term="Office" scheme="https://home.y1xuanyun.cn/tags/Office/"/>
    
    <category term="破解" scheme="https://home.y1xuanyun.cn/tags/%E7%A0%B4%E8%A7%A3/"/>
    
    <category term="Windows" scheme="https://home.y1xuanyun.cn/tags/Windows/"/>
    
    <category term="办公" scheme="https://home.y1xuanyun.cn/tags/%E5%8A%9E%E5%85%AC/"/>
    
    <category term="软件" scheme="https://home.y1xuanyun.cn/tags/%E8%BD%AF%E4%BB%B6/"/>
    
    <category term="教程" scheme="https://home.y1xuanyun.cn/tags/%E6%95%99%E7%A8%8B/"/>
    
  </entry>
  
  <entry>
    <title>算法基础导读（C++）</title>
    <link href="https://home.y1xuanyun.cn/posts/24cpp01.html"/>
    <id>https://home.y1xuanyun.cn/posts/24cpp01.html</id>
    <published>2024-02-28T10:00:00.000Z</published>
    <updated>2024-09-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<h1>前言</h1><div class="note info flat"><p>学习算法的前提是掌握至少一门编程语言，并对其语法和数据结构做到了如指掌，建议读者有C语言和基本的数据结构基础。</p></div><h1>数据结构与算法</h1><ul><li>数据结构是算法的基石。数据结构为算法提供了结构化存储的数据，以及操作数据的方法。</li><li>算法是数据结构发挥作用的舞台。数据结构本身仅存储数据信息，结合算法才能解决特定问题。</li><li>算法通常可以基于不同的数据结构实现，但执行效率可能相差很大，选择合适的数据结构是关键。</li></ul><h1>C++语法概要</h1><p>C语言为C++子集，因此C语言涉及的语法部分将不再说明</p><h2 id="C-标准格式">C++标准格式</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span>  <span class="comment">//标准输入输出流 头文件引入</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; <span class="comment">//开辟命名空间</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="comment">//程序内容</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;<span class="comment">//程序顺利运行</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="常用头文件">常用头文件</h2><p>容器、算法、迭代器等高级用法暂不引入</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span> <span class="comment">//C++万能标准头文件</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cstdio&gt;</span>  <span class="comment">//C风格输入输出</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span>  <span class="comment">//标准输入输出流</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iomanip&gt;</span>   <span class="comment">//输入输出流格式化</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sstream&gt;</span>   <span class="comment">//字符串流</span></span></span><br></pre></td></tr></table></figure><h2 id="输入输出流">输入输出流</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cout&lt;&lt;<span class="string">&quot;字符串&quot;</span>&lt;&lt;<span class="string">&#x27;\n&#x27;</span>;<span class="comment">//endl等效&#x27;\n&#x27;</span></span><br><span class="line">cout&lt;&lt;<span class="string">&quot;字符串&quot;</span>&lt;&lt;endl;<span class="comment">//输出流</span></span><br><span class="line">cin&gt;&gt;<span class="string">&quot;&quot;</span>;<span class="comment">//输入流</span></span><br><span class="line">cerr&lt;&lt;<span class="string">&quot;&quot;</span>&lt;&lt;endl;<span class="comment">//错误流</span></span><br><span class="line">clog&lt;&lt;<span class="string">&quot;&quot;</span>&lt;&lt;endl:<span class="comment">//日志流</span></span><br></pre></td></tr></table></figure><h2 id="存储类">存储类</h2><p>存储类定义 C++ 程序中变量/函数的范围（可见性）和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C++ 程序中可用的存储类：</p><ol><li>auto：这是默认的存储类说明符，通常可以省略不写。auto 指定的变量具有自动存储期，即它们的生命周期仅限于定义它们的块（block）。auto 变量通常在栈上分配。</li><li>register：用于建议编译器将变量存储在CPU寄存器中以提高访问速度。在 C++11 及以后的版本中，register 已经是一个废弃的特性，不再具有实际作用。</li><li>static：用于定义具有静态存储期的变量或函数，它们的生命周期贯穿整个程序的运行期。在函数内部，static变量的值在函数调用之间保持不变。在文件内部或全局作用域，static变量具有内部链接，只能在定义它们的文件中访问。</li><li>extern：用于声明具有外部链接的变量或函数，它们可以在多个文件之间共享。默认情况下，全局变量和函数具有 extern 存储类。在一个文件中使用extern声明另一个文件中定义的全局变量或函数，可以实现跨文件共享。</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="comment">// 全局变量，具有外部链接，默认存储类为extern</span></span><br><span class="line"><span class="type">int</span> globalVar;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">function</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 局部变量，具有自动存储期，默认存储类为auto</span></span><br><span class="line">    <span class="keyword">auto</span> <span class="type">int</span> localVar = <span class="number">10</span>;</span><br><span class="line">    <span class="comment">// 静态变量，具有静态存储期，生命周期贯穿整个程序</span></span><br><span class="line">    <span class="type">static</span> <span class="type">int</span> staticVar = <span class="number">20</span>;</span><br><span class="line">    <span class="type">const</span> <span class="type">int</span> constVar = <span class="number">30</span>; <span class="comment">// const变量默认具有static存储期</span></span><br><span class="line">    <span class="comment">// 尝试修改const变量，编译错误</span></span><br><span class="line">    <span class="comment">// constVar = 40;</span></span><br><span class="line">    <span class="comment">// mutable成员变量，可以在const成员函数中修改</span></span><br><span class="line">    <span class="keyword">class</span> <span class="title class_">MyClass</span> &#123;</span><br><span class="line">    <span class="keyword">public</span>:</span><br><span class="line">        <span class="keyword">mutable</span> <span class="type">int</span> mutableVar;</span><br><span class="line">        <span class="function"><span class="type">void</span> <span class="title">constMemberFunc</span><span class="params">()</span> <span class="type">const</span> </span>&#123;</span><br><span class="line">            mutableVar = <span class="number">50</span>; <span class="comment">// 允许修改mutable成员变量</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="comment">// 线程局部变量，每个线程有自己的独立副本</span></span><br><span class="line">    <span class="keyword">thread_local</span> <span class="type">int</span> threadVar = <span class="number">60</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">extern</span> <span class="type">int</span> externalVar; <span class="comment">// 声明具有外部链接的变量</span></span><br><span class="line">    <span class="built_in">function</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="引用与指针">引用与指针</h2><h3 id="区别">区别</h3><p>引用很容易与指针混淆，它们之间有三个主要的不同：</p><ol><li>不存在空引用。引用必须连接到一块合法的内存。</li><li>一旦引用被初始化为一个对象，就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。</li><li>引用必须在创建时被初始化。指针可以在任何时间被初始化。</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> var = <span class="number">26</span>;    <span class="comment">// 实际变量的声明</span></span><br><span class="line"><span class="comment">// 指针</span></span><br><span class="line"><span class="type">int</span>  *ip;        <span class="comment">// 指针变量的声明</span></span><br><span class="line">ip = &amp;var;       <span class="comment">// 在指针变量中存储 var 的地址</span></span><br><span class="line"><span class="comment">// 引用</span></span><br><span class="line"><span class="type">int</span>&amp;  a = var;   <span class="comment">// 引用变量 var</span></span><br></pre></td></tr></table></figure><h3 id="创建引用">创建引用</h3><p>变量名称是变量附属在内存位置中的标签，可以把引用当成是变量附属在内存位置中的第二个标签。因此，我们可以通过原始变量名称或引用来访问变量的内容。例如：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> i = <span class="number">17</span>;</span><br><span class="line"><span class="comment">// 我们可以为 i 声明引用变量，如下所示：</span></span><br><span class="line"><span class="type">int</span>&amp;  r = i;</span><br><span class="line"><span class="type">double</span>&amp; s = d;</span><br></pre></td></tr></table></figure><p>在这些声明中，&amp; 读作引用。因此，第一个声明可以读作 “r 是一个初始化为 i 的整型引用”，第二个声明可以读作 “s 是一个初始化为 d 的 double 型引用”。</p><h1>C++数据结构</h1><h2 id="vector-容器">vector 容器</h2><p>C++ 中的 vector 是一种序列容器，它允许你在运行时动态地插入和删除元素。<br>vector 是基于数组的数据结构，但它可以自动管理内存，这意味着你不需要手动分配和释放内存。<br>与 C++ 数组相比，vector 具有更多的灵活性和功能，使其成为 C++ 中常用的数据结构之一。<br>vector 是 C++ 标准模板库（STL）的一部分，提供了灵活的接口和高效的操作。</p><h3 id="基本特性">基本特性</h3><ol><li>动态大小：vector 的大小可以根据需要自动增长和缩小。</li><li>连续存储：vector 中的元素在内存中是连续存储的，这使得访问元素非常快速。</li><li>可迭代：vector 可以被迭代，你可以使用循环（如 for 循环）来访问它的元素。</li><li>元素类型：vector 可以存储<code>任何类型</code>的元素，包括内置类型、对象、指针等。</li></ol><h3 id="使用场景">使用场景</h3><ol><li>当你需要一个可以动态增长和缩小的数组时。</li><li>当你需要频繁地在序列的末尾添加或移除元素时。</li><li>当你需要一个可以高效随机访问元素的容器时。</li><li>要使用 vector，首先需要包含 <vector> 头文件：</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br></pre></td></tr></table></figure><h3 id="创建-Vector">创建 Vector</h3><p>创建一个 vector 可以像创建其他变量一样简单：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">std::vector&lt;<span class="type">int</span>&gt; myVector; <span class="comment">// 创建一个存储整数的空 vector</span></span><br></pre></td></tr></table></figure><p>这将创建一个空的整数向量,也可以在创建时指定初始大小和初始值：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">std::vector&lt;<span class="type">int</span>&gt; <span class="title">myVector</span><span class="params">(<span class="number">5</span>)</span></span>; <span class="comment">// 创建一个包含 5 个整数的 vector，每个值都为默认值（0）</span></span><br><span class="line"><span class="function">std::vector&lt;<span class="type">int</span>&gt; <span class="title">myVector</span><span class="params">(<span class="number">5</span>, <span class="number">10</span>)</span></span>; <span class="comment">// 创建一个包含 5 个整数的 vector，每个值都为 10</span></span><br><span class="line"><span class="comment">// 或：</span></span><br><span class="line">std::vector&lt;<span class="type">int</span>&gt; vec; <span class="comment">// 默认初始化一个空的 vector</span></span><br><span class="line">std::vector&lt;<span class="type">int</span>&gt; vec2 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>&#125;; <span class="comment">// 初始化一个包含元素的 vector</span></span><br></pre></td></tr></table></figure><h3 id="添加元素">添加元素</h3><p>可以使用 push_back 方法向 vector 中添加元素：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">myVector.<span class="built_in">push_back</span>(<span class="number">7</span>); <span class="comment">// 将整数 7 添加到 vector 的末尾</span></span><br></pre></td></tr></table></figure><h3 id="访问元素">访问元素</h3><p>可以使用下标操作符 [] 或 at() 方法访问 vector 中的元素：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> x = myVector[<span class="number">0</span>]; <span class="comment">// 获取第一个元素</span></span><br><span class="line"><span class="type">int</span> y = myVector.<span class="built_in">at</span>(<span class="number">1</span>); <span class="comment">// 获取第二个元素</span></span><br></pre></td></tr></table></figure><h3 id="获取大小">获取大小</h3><p>可以使用 size() 方法获取 vector 中元素的数量：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> size = myVector.<span class="built_in">size</span>(); <span class="comment">// 获取 vector 中的元素数量</span></span><br></pre></td></tr></table></figure><h3 id="迭代访问">迭代访问</h3><p>可以使用迭代器遍历 vector 中的元素：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> it = myVector.<span class="built_in">begin</span>(); it != myVector.<span class="built_in">end</span>(); ++it) &#123;</span><br><span class="line">    std::cout &lt;&lt; *it &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>或者使用范围循环：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> element : myVector) &#123;</span><br><span class="line">    std::cout &lt;&lt; element &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="删除元素">删除元素</h3><p>可以使用 erase() 方法删除 vector 中的元素：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">myVector.<span class="built_in">erase</span>(myVector.<span class="built_in">begin</span>() + <span class="number">2</span>); <span class="comment">// 删除第三个元素</span></span><br></pre></td></tr></table></figure><h3 id="清空-Vector">清空 Vector</h3><p>可以使用 clear() 方法清空 vector 中的所有元素：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">myVector.<span class="built_in">clear</span>(); <span class="comment">// 清空 vector</span></span><br></pre></td></tr></table></figure><h3 id="实例">实例</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建一个空的整数向量</span></span><br><span class="line">    std::vector&lt;<span class="type">int</span>&gt; myVector;</span><br><span class="line">    <span class="comment">// 添加元素到向量中</span></span><br><span class="line">    myVector.<span class="built_in">push_back</span>(<span class="number">3</span>);</span><br><span class="line">    myVector.<span class="built_in">push_back</span>(<span class="number">7</span>);</span><br><span class="line">    myVector.<span class="built_in">push_back</span>(<span class="number">11</span>);</span><br><span class="line">    myVector.<span class="built_in">push_back</span>(<span class="number">5</span>);</span><br><span class="line">    <span class="comment">// 访问向量中的元素并输出</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Elements in the vector: &quot;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> element : myVector) &#123;</span><br><span class="line">        std::cout &lt;&lt; element &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    std::cout &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 访问向量中的第一个元素并输出</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;First element: &quot;</span> &lt;&lt; myVector[<span class="number">0</span>] &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 访问向量中的第二个元素并输出</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Second element: &quot;</span> &lt;&lt; myVector.<span class="built_in">at</span>(<span class="number">1</span>) &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 获取向量的大小并输出</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Size of the vector: &quot;</span> &lt;&lt; myVector.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 删除向量中的第三个元素</span></span><br><span class="line">    myVector.<span class="built_in">erase</span>(myVector.<span class="built_in">begin</span>() + <span class="number">2</span>);</span><br><span class="line">    <span class="comment">// 输出删除元素后的向量</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Elements in the vector after erasing: &quot;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> element : myVector) &#123;</span><br><span class="line">        std::cout &lt;&lt; element &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    std::cout &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 清空向量并输出</span></span><br><span class="line">    myVector.<span class="built_in">clear</span>();</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Size of the vector after clearing: &quot;</span> &lt;&lt; myVector.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="顺序表🥖list">顺序表🥖list</h2><p><list> 是 C++ 标准模板库（STL）中的一个序列容器，它允许在容器的任意位置快速插入和删除元素。与数组或向量（<vector>）不同，<list> 不需要在创建时指定大小，并且可以在任何位置添加或删除元素，而不需要重新分配内存。</p><h3 id="语法">语法</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引用头文件</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;list&gt;</span>  </span></span><br><span class="line"><span class="comment">//声明列表，其中 T 是存储在列表中的元素类型。</span></span><br><span class="line">std::list&lt;T&gt; mylist; </span><br><span class="line"><span class="comment">//插入元素                   </span></span><br><span class="line">mylist.<span class="built_in">push_back</span>(value);</span><br><span class="line"><span class="comment">//删除元素    </span></span><br><span class="line">mylist.<span class="built_in">pop_back</span>(); 或 mylist.<span class="built_in">erase</span>(iterator);</span><br><span class="line"><span class="comment">//访问元素</span></span><br><span class="line">mylist.<span class="built_in">front</span>(); 和 mylist.<span class="built_in">back</span>();</span><br><span class="line"><span class="comment">//遍历遍历列表：使用迭代器</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">auto</span> it = mylist.<span class="built_in">begin</span>(); it != mylist.<span class="built_in">end</span>(); ++it)</span><br></pre></td></tr></table></figure><h3 id="特点">特点</h3><p>双向迭代：<list> 提供了双向迭代器，可以向前和向后遍历元素。<br>动态大小：与数组不同，<list> 的大小可以动态变化，不需要预先分配固定大小的内存。<br>快速插入和删除：可以在列表的任何位置快速插入或删除元素，而不需要像向量那样移动大量元素。</p><h3 id="注意事项">注意事项</h3><p><list> 的元素是按插入顺序存储的，而不是按元素值排序。<br>由于 <list> 的元素存储在不同的内存位置，所以它不适合需要随机访问的场景。<br>与向量相比，<list> 的内存使用效率较低，因为每个元素都需要额外的空间来存储指向前后元素的指针。</p><h2 id="链表🥨forward-list">链表🥨forward_list</h2><p>与双向链表（std::list）不同，std::forward_list 只支持单向遍历。它适用于需要频繁进行前向遍历和插入、删除操作的场景。以下是对 std::forward_list 的详细说明：</p><ul><li>单向链表：<br>std::forward_list 是单向链表，只能从前往后遍历，不能反向遍历。<br>由于其单向链表的结构，插入和删除操作在已知位置的情况下非常高效（O(1) 复杂度）。</li><li>低内存开销：<br>与 std::list 相比，std::forward_list 只需要一个指向下一个节点的指针，节省了内存。</li><li>不支持随机访问：<br>不支持通过索引访问元素，不能使用 operator[] 或 at 方法，只能通过迭代器进行访问。</li></ul><h3 id="构造函数">构造函数</h3><p>std::forward_list 提供了多种构造函数，包括：<br>默认构造函数：创建一个空的 forward_list。<br>带初始值的构造函数：创建一个包含给定初始值的 forward_list。<br>带范围的构造函数：创建一个包含指定范围内元素的 forward_list。</p><h3 id="常用成员函数">常用成员函数</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">push_front</span><span class="params">(<span class="type">const</span> T&amp; value)</span>  <span class="comment">//在列表的前端插入一个元素。</span></span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">pop_front</span><span class="params">()</span>                 <span class="comment">//移除列表前端的元素。</span></span></span><br><span class="line"><span class="function">iterator <span class="title">before_begin</span><span class="params">()</span>          <span class="comment">//返回指向列表前端之前的迭代器。</span></span></span><br><span class="line"><span class="function">iterator <span class="title">begin</span><span class="params">()</span>                 <span class="comment">//返回指向列表前端的迭代器。</span></span></span><br><span class="line"><span class="function">iterator <span class="title">end</span><span class="params">()</span>                   <span class="comment">//返回指向列表末尾的迭代器。</span></span></span><br></pre></td></tr></table></figure><h2 id="队列🍣queue">队列🍣queue</h2><p>C++ 标准库中的 <queue> 头文件提供了队列（Queue）数据结构的实现。队列是一种先进先出（FIFO, First In First Out）的数据结构，它允许在一端添加元素（称为队尾），并在另一端移除元素（称为队首）。</p><h3 id="基本操作">基本操作</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">empty</span>()     <span class="comment">//检查队列是否为空。</span></span><br><span class="line"><span class="built_in">size</span>()      <span class="comment">//返回队列中的元素数量。</span></span><br><span class="line"><span class="built_in">front</span>()     <span class="comment">//返回队首元素的引用。</span></span><br><span class="line"><span class="built_in">back</span>()      <span class="comment">//返回队尾元素的引用。</span></span><br><span class="line"><span class="built_in">push</span>()      <span class="comment">//在队尾添加一个元素。</span></span><br><span class="line"><span class="built_in">pop</span>()       <span class="comment">//移除队首元素。</span></span><br></pre></td></tr></table></figure><h3 id="语法-2">语法</h3><p>在 C++ 中，队列的语法如下：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;queue&gt;</span></span></span><br><span class="line"><span class="comment">// 声明队列</span></span><br><span class="line">std::queue&lt;Type&gt; q;</span><br><span class="line"><span class="comment">//这里 Type 是队列中存储元素的数据类型。</span></span><br></pre></td></tr></table></figure><h2 id="栈🍡stack">栈🍡stack</h2><p><stack> 是 C++ 标准模板库（STL）的一部分，它实现了一个后进先出（LIFO，Last In First Out）的数据结构。这种数据结构非常适合于需要&quot;最后添加的元素最先被移除&quot;的场景。<br><stack> 容器适配器提供了一个栈的接口，它基于其他容器（如 deque 或 vector）来实现。栈的元素是线性排列的，但只允许在一端（栈顶）进行添加和移除操作。</p><h3 id="基本操作-2">基本操作</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">push</span>()      <span class="comment">//在栈顶添加一个元素。</span></span><br><span class="line"><span class="built_in">pop</span>()       <span class="comment">//移除栈顶元素。</span></span><br><span class="line"><span class="built_in">top</span>()       <span class="comment">//返回栈顶元素的引用，但不移除它。</span></span><br><span class="line"><span class="built_in">empty</span>()     <span class="comment">//检查栈是否为空。</span></span><br><span class="line"><span class="built_in">size</span>()      <span class="comment">//返回栈中元素的数量。</span></span><br></pre></td></tr></table></figure><h3 id="语法-3">语法</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stack&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    std::stack&lt;<span class="type">int</span>&gt; s;</span><br><span class="line">    <span class="comment">// 向栈中添加元素</span></span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">1</span>);</span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">2</span>);</span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">3</span>);</span><br><span class="line">    <span class="comment">// 访问栈顶元素</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Top element is: &quot;</span> &lt;&lt; s.<span class="built_in">top</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 移除栈顶元素</span></span><br><span class="line">    s.<span class="built_in">pop</span>();</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;After popping, top element is: &quot;</span> &lt;&lt; s.<span class="built_in">top</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 检查栈是否为空</span></span><br><span class="line">    <span class="keyword">if</span> (!s.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        std::cout &lt;&lt; <span class="string">&quot;Stack is not empty.&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 打印栈的大小</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Size of stack: &quot;</span> &lt;&lt; s.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="红黑树🍬map">红黑树🍬map</h2><p>在 C++ 中，<map> 是标准模板库（STL）的一部分，它提供了一种关联容器，用于存储键值对（key-value pairs）。</p><p>map 容器中的元素是按照键的顺序自动排序的，这使得它非常适合需要快速查找和有序数据的场景。</p><h3 id="定义和特性">定义和特性</h3><p>键值对：map 存储的是键值对，其中每个键都是唯一的。<br>排序：map 中的元素按照键的顺序自动排序，通常是升序。<br>唯一性：每个键在 map 中只能出现一次。<br>双向迭代器：map 提供了双向迭代器，可以向前和向后遍历元素。</p><h3 id="基本语法">基本语法</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//包含头文件:</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;map&gt;</span></span></span><br><span class="line"><span class="comment">//声明 map 容器:</span></span><br><span class="line">std::map&lt;key_type, value_type&gt; myMap;</span><br><span class="line">key_type <span class="comment">//是键的类型。</span></span><br><span class="line">value_type <span class="comment">//是值的类型。</span></span><br><span class="line"><span class="comment">//插入元素:</span></span><br><span class="line">myMap[key] = value;</span><br><span class="line"><span class="comment">//访问元素:</span></span><br><span class="line">value = myMap[key];</span><br><span class="line"><span class="comment">//遍历 map:</span></span><br><span class="line"><span class="keyword">for</span> (std::map&lt;key_type, value_type&gt;::iterator it = myMap.<span class="built_in">begin</span>(); it != myMap.<span class="built_in">end</span>(); ++it) &#123;</span><br><span class="line">    std::cout &lt;&lt; it-&gt;first &lt;&lt; <span class="string">&quot; =&gt; &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; std::endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="哈希表🍨unordered-map">哈希表🍨unordered_map</h2><p>在 C++ 中，&lt;unordered_map&gt; 是标准模板库（STL）的一部分，提供了一种基于哈希表的键值对容器。</p><h3 id="定义和特性-2">定义和特性</h3><p>与 std::map 不同，unordered_map 不保证元素的排序，但通常提供更快的查找速度。<br>unordered_map 是一个关联容器，它存储了键值对（key-value pairs），其中每个键（key）都是唯一的。unordered_map 使用哈希表来存储元素，这使得它在查找、插入和删除操作中具有平均常数时间复杂度。</p><h3 id="语法-4">语法</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;unordered_map&gt;</span></span></span><br><span class="line">std::unordered_map&lt;key_type, value_type&gt; map_name;</span><br><span class="line">key_type <span class="comment">//是键的类型。</span></span><br><span class="line">value_type <span class="comment">//是值的类型。</span></span><br><span class="line"><span class="comment">//构造函数</span></span><br><span class="line">unordered_map <span class="comment">//可以以多种方式构造：</span></span><br><span class="line"><span class="comment">// 默认构造</span></span><br><span class="line">std::unordered_map&lt;<span class="type">int</span>, std::string&gt; myMap;</span><br><span class="line"><span class="comment">// 构造并初始化</span></span><br><span class="line">std::unordered_map&lt;<span class="type">int</span>, std::string&gt; myMap = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;&#125;;</span><br><span class="line"><span class="comment">// 构造并指定初始容量</span></span><br><span class="line"><span class="function">std::unordered_map&lt;<span class="type">int</span>, std::string&gt; <span class="title">myMap</span><span class="params">(<span class="number">10</span>)</span></span>;</span><br><span class="line"><span class="comment">// 构造并复制另一个 unordered_map</span></span><br><span class="line">std::unordered_map&lt;<span class="type">int</span>, std::string&gt; anotherMap = myMap;</span><br><span class="line">基本操作</span><br><span class="line"><span class="comment">//插入元素:</span></span><br><span class="line">myMap.<span class="built_in">insert</span>(&#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;);</span><br><span class="line"><span class="comment">//访问元素:</span></span><br><span class="line">std::string value = myMap[<span class="number">1</span>]; <span class="comment">// 获取键为1的值</span></span><br><span class="line"><span class="comment">//删除元素:</span></span><br><span class="line">myMap.<span class="built_in">erase</span>(<span class="number">1</span>); <span class="comment">// 删除键为1的元素</span></span><br><span class="line"><span class="comment">//查找元素:</span></span><br><span class="line"><span class="keyword">auto</span> it = myMap.<span class="built_in">find</span>(<span class="number">2</span>); <span class="comment">// 查找键为2的元素</span></span><br><span class="line"><span class="keyword">if</span> (it != myMap.<span class="built_in">end</span>()) &#123;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Found: &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; std::endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1>C++11和C++17特性</h1><h2 id="raw-string-literal-技术">raw string literal 技术</h2><p>在第三代C++标准中，引入了<code>raw string literal</code>技术，该技术解决了传统语法中的逐行打印输出的不便，更方便用于控制台命令窗口程序的设计，对于部分赛题略有帮助。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    std::cout&lt;&lt;<span class="string">R&quot;(//由此开始</span></span><br><span class="line"><span class="string">//批量级字符串输出</span></span><br><span class="line"><span class="string">//由此结束)&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="存储类-2">存储类</h2><ol><li>auto 关键字在C++11中用于两种情况：声明变量时根据初始化表达式自动推断该变量的类型、声明函数时函数返回值的占位符。</li><li>mutable：用于修饰类中的成员变量，允许在const成员函数中修改这些变量的值。通常用于缓存或计数器等需要在const上下文中修改的数据。</li><li>thread_local：用于定义具有线程局部存储期的变量，每个线程都有自己的独立副本。线程局部变量的生命周期与线程的生命周期相同。</li></ol><h1>致谢</h1><div class="note default flat"><p>本文参考于：<a href="https://www.educoder.net/paths/co8zyp75">头歌实践：C&amp;C++程序设计（国防科大）</a> <a href="https://www.bilibili.com/video/BV1b7411N798">哔哩哔哩：王道计算机考研 数据结构</a></p></div>]]></content>
    
    
    <summary type="html">🧩从程序设计💻向数据结构⚙️过渡并与之结合应用的学习文档📖</summary>
    
    
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/categories/%E7%AE%97%E6%B3%95/"/>
    
    
    <category term="C++" scheme="https://home.y1xuanyun.cn/tags/C/"/>
    
    <category term="程序设计" scheme="https://home.y1xuanyun.cn/tags/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
    
    <category term="数据结构" scheme="https://home.y1xuanyun.cn/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    
    <category term="题单" scheme="https://home.y1xuanyun.cn/tags/%E9%A2%98%E5%8D%95/"/>
    
    <category term="语法" scheme="https://home.y1xuanyun.cn/tags/%E8%AF%AD%E6%B3%95/"/>
    
    <category term="算法" scheme="https://home.y1xuanyun.cn/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="笔记" scheme="https://home.y1xuanyun.cn/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>SpringBoot工程配置笔记</title>
    <link href="https://home.y1xuanyun.cn/posts/24web01.html"/>
    <id>https://home.y1xuanyun.cn/posts/24web01.html</id>
    <published>2024-02-21T10:00:00.000Z</published>
    <updated>2024-03-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-blue"  style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><p>该文章长期更新</p></div></div><h2 id=""></h2><h1>热部署</h1><h2 id="基本概念">基本概念</h2><div class="note info flat"><p>热部署（Hot Deployment）是指在不停止当前运行程序的情况下，对代码或资源配置进行更新，且这些更新能够被即时反映到正在运行的程序中的一种技术。</p></div><h2 id="开发环境热部署">开发环境热部署</h2><ul><li>在<code>pom.xml</code>配置文件中添加<code>dev-tools</code>依赖。</li><li>使用<code>optional=true</code>表示依赖不会传递，即该项目依赖<code>devtools</code>; 其他项目如果引入此项目生成的JAR包，则不会包含<code>devtools</code>。</li></ul><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-devtools<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true&lt;/optional &gt;</span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><div class="note info flat"><p>在实际的项目开发调试过程中会频繁地修改后台类文件，导致需要重新编译、重新启动，整个过程非常麻烦，影响开发效率。</p></div><ul><li>而Spring Boot提供了<code>spring-boot-devtools</code>组件，使得无须手动重启Spring Boot应用即可重新编译启动项目， 大大缩短编译启动的时间。</li><li><code>devtools</code>会监听<code>classpath</code>下的文件变动，触发<code>Restart</code>类加载器重新加载该类，从而实现类文件和属性文件的热部署。</li><li>并不是所有的更改都需要重启应用（如静态资源、视图模板），可以通过设置<code>spring.devtools.restart.exclude</code>属性来指定—些文件或目录的修改不用重启应用。</li></ul><h2 id="配置devtools。">配置devtools。</h2><ul><li>在<code>application.properties</code>中修改以下代码。</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 热部署生效</span><br><span class="line">spring.devtools.restart.enabled=<span class="literal">true</span></span><br><span class="line"># 设置重启目录</span><br><span class="line">spring.devtools.restart.additional-paths=src/main/java</span><br><span class="line"># 设置classpath目录下的WEB-INF 文件夹以下内容</span><br><span class="line">spring.devtools.restart.exclude=<span class="keyword">static</span><span class="comment">/**</span></span><br></pre></td></tr></table></figure><h2 id="非IDEA编译器配置">非IDEA编译器配置</h2><ul><li>如果使用了Eclipse，那么在修改完代’码 并保存之后， 项目将自动编译并触发重<br>启，而如果使用了lntelliJ IDEA， 还需要配置项目自动编译。</li><li>打开<code>Settings</code>页面， 在妇力的菜单栏依次找到Build，Execution，Deployment的<code>Compile</code>，勾选<code>Build project automatically</code></li><li>*按<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>／</kbd>快捷键调出<code>Maintenance</code>页面，单击<code>Registry</code>，勾选<code>compiler.automake.allow.when.app.running</code>复选框。</li><li>做完这两步配置之后， 若开发者再次在lntelliJ IDEA中修改代码， 则项目会自动重启。</li></ul><div class="note info flat"><p>21 版本的idea 没有这个选项要去<code>settings</code>里找到<code>Advansed Settings</code>勾选<code>Allow auto-make</code>那个选项就可以了<br>汉语版的是：即使开发的应用程序当前正在运行，也允许自动make启动</p></div><h1>引导html</h1><p>用于非前后端分离式JavaWeb项目，脱离Nginx部署（IDEA）</p><h2 id="基本概念-2">基本概念</h2><div class="note info flat"></div><h2 id="开发环境热部署-2">开发环境热部署</h2><ol><li><p>创建一个<code>Spring Boot</code>项目。如果你还没有创建，可以使用<code>Spring Initializr（https://start.spring.io/）</code>生成一个基本的Spring Boot项目结构。在<code>Dependencies</code>选项卡中，选择<code>Web</code>依赖项。</p></li><li><p>将你的HTML文件放在项目的<code>src/main/resources/static</code>目录下。这个目录是<code>Spring Boot</code>默认的静态资源目录，用于存放HTML、CSS和JavaScript文件。</p></li><li><p>在你的Spring Boot项目中，创建一个<code>Controller</code>类来处理HTTP请求。例如，你可以创建一个名为<code>MyController</code>的类，并添加一个方法来处理对HTML文件的请求。这个方法应该返回一个<code>ModelAndView</code>对象，其中包含要渲染的视图名称（即HTML文件的名称）和一个包含视图所需的数据的<code>Map</code>对象。</p></li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Controller;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.ModelAndView;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyController</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> ModelAndView <span class="title function_">index</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">ModelAndView</span> <span class="variable">modelAndView</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ModelAndView</span>(<span class="string">&quot;index&quot;</span>);</span><br><span class="line">        modelAndView.addObject(<span class="string">&quot;message&quot;</span>, <span class="string">&quot;Hello, Spring Boot!&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> modelAndView;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="4"><li>在<code>src/main/resources/templates</code>目录下创建一个名为<code>index.html</code>的文件，并在其中编写HTML代码。例如：</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Controller;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.ModelAndView;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">HomeController</span> &#123;</span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> ModelAndView <span class="title function_">index</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">ModelAndView</span> <span class="variable">modelAndView</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ModelAndView</span>(<span class="string">&quot;index&quot;</span>);</span><br><span class="line">        modelAndView.addObject(<span class="string">&quot;message&quot;</span>, <span class="string">&quot;Hello, Spring Boot!&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> modelAndView;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Spring Boot HTML Example<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>&#123;&#123; message &#125;&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="非IDEA编译器配置-2">非IDEA编译器配置</h2><ul><li>如果使用了Eclipse，那么在修改完代’码 并保存之后， 项目将自动编译并触发重<br>启，而如果使用了lntelliJ IDEA， 还需要配置项目自动编译。</li><li>打开<code>Settings</code>页面， 在妇力的菜单栏依次找到Build，Execution，Deployment的<code>Compile</code>，勾选<code>Build project automatically</code></li><li>*按<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>／</kbd>快捷键调出<code>Maintenance</code>页面，单击<code>Registry</code>，勾选<code>compiler.automake.allow.when.app.running</code>复选框。</li><li>做完这两步配置之后， 若开发者再次在lntelliJ IDEA中修改代码， 则项目会自动重启。</li></ul><div class="note info flat"><p>21 版本的idea 没有这个选项要去<code>settings</code>里找到<code>Advansed Settings</code>勾选<code>Allow auto-make</code>那个选项就可以了<br>汉语版的是：即使开发的应用程序当前正在运行，也允许自动make启动</p></div>]]></content>
    
    
    <summary type="html">🎠传统JavaEE企业级开发环境中借助Maven进行配置（IDEA）</summary>
    
    
    
    <category term="Web" scheme="https://home.y1xuanyun.cn/categories/Web/"/>
    
    
    <category term="Java" scheme="https://home.y1xuanyun.cn/tags/Java/"/>
    
    <category term="环境配置" scheme="https://home.y1xuanyun.cn/tags/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/"/>
    
    <category term="Spring" scheme="https://home.y1xuanyun.cn/tags/Spring/"/>
    
    <category term="热部署" scheme="https://home.y1xuanyun.cn/tags/%E7%83%AD%E9%83%A8%E7%BD%B2/"/>
    
    <category term="IDEA" scheme="https://home.y1xuanyun.cn/tags/IDEA/"/>
    
    <category term="Maven" scheme="https://home.y1xuanyun.cn/tags/Maven/"/>
    
    <category term="HTML" scheme="https://home.y1xuanyun.cn/tags/HTML/"/>
    
  </entry>
  
  <entry>
    <title>关于Windows系统操作技巧</title>
    <link href="https://home.y1xuanyun.cn/posts/24pc02.html"/>
    <id>https://home.y1xuanyun.cn/posts/24pc02.html</id>
    <published>2024-02-07T10:00:00.000Z</published>
    <updated>2024-04-01T14:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<div class="progress"><div class="progress-bar-animated progress-bar progress-bar-striped bg-blue"  style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><p>该文章长期更新</p></div></div><h1>万物皆可 win+R</h1><p>在Windows操作系统中按下<kbd>win</kbd>+<kbd>R</kbd>即可调出运行</p><h2 id="系统自带可运行程序">系统自带可运行程序</h2><p>即检索系统注册表AppPaths目录和系统环境变量path中写入的程序<br>那么也就是就说，将我们下载的第三方软件或是bat脚本提前配置到环境变量就能快速访问</p><figure class="highlight moonscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">注册表AppPaths目录</span><br><span class="line">\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths</span><br></pre></td></tr></table></figure><h3 id="🧰-EXE实用小工具">🧰.EXE实用小工具</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">calc - 启动计算器</span><br><span class="line">charmap - 启动字符映射表</span><br><span class="line">chkdsk - Chkdsk磁盘检查</span><br><span class="line">cleanmgr - 磁盘清理</span><br><span class="line">clipbrd - 剪贴板查看器</span><br><span class="line">cmd.exe - CMD命令提示符</span><br><span class="line">dvdplay - DVD播放器</span><br><span class="line">dxdiag - DirectX诊断工具</span><br><span class="line">eudcedit - 造字程序（专用字符编辑程序）</span><br><span class="line">explorer - 资源管理器</span><br><span class="line">magnify - 放大镜</span><br><span class="line">msconfig - 系统配置</span><br><span class="line">mspaint - 画图板</span><br><span class="line">mstsc - 远程桌面连接</span><br><span class="line">narrator - 屏幕“讲述人”</span><br><span class="line">notepad - 打开记事本</span><br><span class="line">nslookup - IP地址侦测器</span><br><span class="line">osk - 打开屏幕键盘</span><br><span class="line">regedit - 注册表编辑器</span><br><span class="line">sndrec32 - 录音机</span><br><span class="line">sndvol32 - 音量控制程序</span><br><span class="line">taskmgr - 任务管理器</span><br><span class="line">winchat - XP自带局域网聊天</span><br><span class="line"><span class="built_in">write</span> - 写字板</span><br><span class="line">dcomcnfg - 系统组件服务</span><br><span class="line">ddeshare - DDE共享设置</span><br><span class="line">nslookup - 网络管理的工具向导</span><br><span class="line">ntbackup - 系统备份和还原</span><br><span class="line">mobsync - 同步中心</span><br><span class="line">winmsd - 系统信息</span><br><span class="line">winver - 检查Windows版本</span><br><span class="line">wiaacmgr - 扫描仪和照相机向导</span><br><span class="line">wscript - windows脚本宿主设置</span><br><span class="line">wupdmgr - windows更新程序</span><br></pre></td></tr></table></figure><h3 id="📟-MSC微软管理控制台程序">📟.MSC微软管理控制台程序</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">mmc - 管理控制台</span><br><span class="line">certmgr.msc - 证书管理</span><br><span class="line">ciadv.msc - 索引服务程序</span><br><span class="line">comexp.msc - 组件服务</span><br><span class="line">compmgmt.msc - 计算机管理</span><br><span class="line">devmgmt.msc - 设备管理器</span><br><span class="line">dfrg.msc - 磁盘碎片整理程序</span><br><span class="line">diskmgmt.msc - 磁盘管理</span><br><span class="line">eventvwr.msc - 事件查看器</span><br><span class="line">fsmgmt.msc - 共享文件夹管理器</span><br><span class="line">gpedit.msc - 组策略管理器（本地组策略编辑器）</span><br><span class="line">lusrmgr.msc - 本机用户和组</span><br><span class="line">ntmsmgr.msc - 移动存储管理器</span><br><span class="line">ntmsoprq.msc - 移动存储管理员操作请求</span><br><span class="line">perfmon.msc - 性能监视器</span><br><span class="line">rsop.msc - 组策略结果集</span><br><span class="line">secpol.msc - 本地安全策略</span><br><span class="line">services.msc - 本地服务设置</span><br><span class="line">wmimgmt.msc - windows管理体系结构WMI（控制台根节点\WMI控件）</span><br></pre></td></tr></table></figure><h2 id="插入第三方程序">插入第三方程序</h2><ol><li>将.exe程序所在路径复制</li><li><kbd>右键</kbd>此电脑➡️属性➡️高级系统设置➡️环境变量➡️系统变量</li><li>找到<code>path</code>双击打开➡️新建粘贴.exe程序所在路径</li></ol><div class="note info flat"><p>仅适用win10及以上操作系统</p></div><h2 id="插入-bat脚本">插入.bat脚本</h2><p>如法炮制以上操作，建议将一文件夹作为容器存放各第三方软件.exe快捷方式和.bat脚本<br>以快速访问指定网站为例，在运行中输入bat脚本文件名即可访问本站</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">explorer https://home.y1xuanyun.cn/  访问网站</span><br></pre></td></tr></table></figure><h2 id="查询当前系统版本">查询当前系统版本</h2><p>Windows系统版本分为 <code>零售版</code> <code>OEM版</code> <code>大批量授权（KMS/MAK）</code> <code>开发者版</code><br>通过命令提示符键入以下内容进行查询<br>对应代码为 <code>Retail</code> <code>OEM</code> <code>VOL</code></p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">slmgr.vbs /dli</span><br></pre></td></tr></table></figure><h2 id="python打包exe程序">python打包exe程序</h2><p>在源代码文件夹下直接在资源管理器目录栏键入<code>cmd</code>运行以下代码</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pyinstaller -F -w -i snake.ico --add-data &quot;circle.png;.&quot; gluttonous.py</span><br></pre></td></tr></table></figure><h1>注册表</h1><p>注册表是windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的核心“数据库”，也可以说是一个非常巨大的树状分层结构的数据库系统。<br>注册表记录了用户安装在计算机上的软件和每个程序的相互关联信息，它包括了计算机的硬件配置，包括自动配置的即插即用的设备和已有的各种设备说明、状态属性以及各种状态信息和数据。<br>利用一个功能强大的注册表数据库来统一集中地管理系统硬件设施、软件配置等信息，从而方便了管理，增强了系统的稳定性。<br>注册表文件的数据信息保存在system.dat和user.dat中、利用regedit.exe程序能够存取注册表文件</p><h2 id="调出注册表">调出注册表</h2><kbd>win</kbd>+<kbd>R</kbd>调出运行窗口<p>➡️输入<code>regedit</code>运行程序</p><div class="note danger flat"><p>注意：修改注册表为高危险操作，建议充分学习后慎重考虑！</p></div><h2 id="问题一：删除程序系统应用列表依然存在">问题一：删除程序系统应用列表依然存在</h2><p>通常未按应用卸载程序或系统应用列表界面卸载程序以及移动程序文件夹导致<br>例如：进入程序目标文件夹直接进行移动/删除文件操作等</p><h3 id="表现">表现</h3><p>在系统应用列表卸载该程序将提示<code>未找到卸载程序</code>，且该记录无法删除</p><h3 id="分析">分析</h3><p>该提示表明原程序所在目标文件夹中没有找到对应卸载程序</p><ol><li>程序所在文件被移动，注册表键值路径信息未更新</li><li>程序未正常卸载，导致注册表信息未擦除，且C盘中仍存有用户信息文件</li></ol><h3 id="解决">解决</h3><p>调出注册表➡️输入以下路径➡️转入系统应用列表信息源➡️找到对应程序文件夹➡️删除</p><div class="note info flat"><p>部分文件名为16进制字符串，在右侧可查看“名称”“类型”“数值”。</p></div><figure class="highlight moonscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">注册表系统应用列表源</span><br><span class="line">\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\</span><br></pre></td></tr></table></figure><h1>一劳永逸，一键无限推迟Windows更新</h1><kbd>win</kbd>+<kbd>R</kbd>调出运行窗口，输入以下代码并回车，即可在` 设置 `->` Windows更新 `中设置更长的推迟时间。<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reg <span class="keyword">add</span><span class="language-bash"> <span class="string">&quot;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings&quot;</span> /v FlightSettingsMaxPauseDays /t reg_dword /d 10000 /f</span></span><br></pre></td></tr></table></figure><h1>深入理解环境变量与PATH配置</h1><blockquote><p>掌握环境变量配置，告别命令行报错困扰</p></blockquote><p>当你在Windows命令提示符或PowerShell中输入一个命令时，是否经常遇到 <strong>“不是内部或外部命令，也不是可运行的程序或批处理文件”</strong> 的报错？这个令人沮丧的问题通常源于环境变量——特别是<strong>PATH变量</strong>——配置不当。本文将深入解析环境变量的工作原理，并提供多种解决方案，让你彻底摆脱这类错误。</p><h2 id="一、为什么会出现-不是内部命令-错误？">一、为什么会出现&quot;不是内部命令&quot;错误？</h2><p>当你在命令行输入一个程序名（如<code>python</code>、<code>java</code>或<code>git</code>）时，Windows会按照特定顺序查找该可执行文件：</p><ol><li>首先在当前目录查找</li><li>然后在<strong>系统变量</strong>的PATH路径中顺序查找</li><li>最后在<strong>用户变量</strong>的PATH路径中查找</li></ol><p>如果所有位置都找不到匹配的可执行文件（<code>.exe</code>、<code>.bat</code>等），系统就会抛出&quot;<strong>不是内部或外部命令</strong>&quot;的错误。这通常表示：</p><ul><li>程序未安装</li><li>程序已安装但未添加到PATH</li><li>PATH路径拼写错误</li><li>需要重新启动终端使PATH更改生效</li></ul><h2 id="二、环境变量基础：系统变量-vs-用户变量">二、环境变量基础：系统变量 vs 用户变量</h2><p>在Windows中，环境变量分为两大类，它们在作用范围和权限上有明显区别：</p><table><thead><tr><th><strong>特性</strong></th><th><strong>用户变量</strong></th><th><strong>系统变量</strong></th></tr></thead><tbody><tr><td><strong>作用范围</strong></td><td>仅对当前用户有效</td><td>对所有用户有效</td></tr><tr><td><strong>存储位置</strong></td><td><code>HKEY_CURRENT_USER\Environment</code></td><td><code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment</code></td></tr><tr><td><strong>修改权限</strong></td><td>当前用户可修改</td><td>需要管理员权限</td></tr><tr><td><strong>优先级</strong></td><td>较高（覆盖同名系统变量）</td><td>较低</td></tr><tr><td><strong>典型用途</strong></td><td>用户专属工具路径、临时设置</td><td>系统级工具路径、公共配置</td></tr></tbody></table><p><strong>关键规则</strong>：</p><ul><li>环境变量<strong>不区分大小写</strong>（PATH与path相同）</li><li>对于PATH变量，系统会<strong>合并用户PATH和系统PATH</strong>的值</li><li>当同一个程序出现在系统PATH和用户PATH中时，<strong>系统PATH中的版本优先执行</strong></li></ul><h2 id="三、深入理解PATH变量">三、深入理解PATH变量</h2><p>PATH是Windows中最关键的环境变量之一，它存储了<strong>可执行文件的搜索路径列表</strong>。其工作流程如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">graph TD</span><br><span class="line">    A[输入命令] --&gt; B&#123;当前目录存在？&#125;</span><br><span class="line">    B -- 是 --&gt; C[执行程序]</span><br><span class="line">    B -- 否 --&gt; D&#123;系统PATH中找到？&#125;</span><br><span class="line">    D -- 是 --&gt; C</span><br><span class="line">    D -- 否 --&gt; E&#123;用户PATH中找到？&#125;</span><br><span class="line">    E -- 是 --&gt; C</span><br><span class="line">    E -- 否 --&gt; F[抛出&quot;不是内部命令&quot;错误]</span><br></pre></td></tr></table></figure><h1>系统图标库升级：从SHELL32.dll到imageres.dll</h1><p>探索Windows系统中更美观的图标资源</p><h2 id="图标库的转变">图标库的转变</h2><p>Windows系统默认图标库经历了重要转变：<br>• 传统路径：<code>C:\WINDOWS\System32\SHELL32.dll</code><br>• 现代路径：<code>%SystemRoot%\system32\imageres.dll</code><br><code>%SystemRoot%</code>是系统变量，通常指向<code>C:\Windows</code></p><h2 id="为何选择imageres-dll？">为何选择imageres.dll？</h2><h3 id="视觉升级">视觉升级</h3><table><thead><tr><th>特性</th><th>SHELL32.dll</th><th>imageres.dll</th></tr></thead><tbody><tr><td>设计风格</td><td>拟物化设计</td><td>扁平化设计</td></tr><tr><td>图标数量</td><td>约100+</td><td>300+</td></tr><tr><td>视觉效果</td><td>简单渐变</td><td>丰富透明效果</td></tr><tr><td>系统支持</td><td>Windows XP</td><td>Win7+最佳</td></tr></tbody></table><h3 id="核心优势">核心优势</h3><ol><li><strong>精致扁平化设计</strong>：符合现代UI趋势</li><li><strong>丰富图标资源</strong>：包含计算机、回收站、文件夹等各种状态图标</li><li><strong>动态状态感知</strong>：如回收站满/空状态图标</li><li><strong>高分辨率支持</strong>：适应4K等高清显示屏</li></ol><h3 id="实用图标示例">实用图标示例</h3><p>imageres.dll包含众多精美图标：<br>• <strong>系统核心</strong>：计算机(<code>-109</code>)、网络(<code>-25</code>)、控制面板(<code>-28</code>)<br>• <strong>回收站</strong>：满(<code>-54</code>)、空(<code>-55</code>)<br>• <strong>设备图标</strong>：打印机、CD/DVD、USB设备<br>• <strong>文件夹类型</strong>：文档、图片、音乐、视频</p><h2 id="应用指南">应用指南</h2><h3 id="更改快捷方式图标">更改快捷方式图标</h3><ol><li>右击快捷方式 &gt; 属性 &gt; 快捷方式选项卡</li><li>点击&quot;更改图标&quot;</li><li>输入路径：<code>%SystemRoot%\system32\imageres.dll</code></li><li>选择心仪图标</li></ol><h2 id="注意事项">注意事项</h2><ol><li><strong>安全第一</strong>：<br>• 禁止直接替换imageres.dll文件<br>• 注册表修改前务必备份（<code>regedit &gt; 文件 &gt; 导出</code>）</li><li><strong>兼容性</strong>：<br>• 最佳支持Windows 7及更新系统<br>• 旧系统可能无法正确显示新图标</li><li><strong>使用权限</strong>：<br>• 系统图标仅限个人/学习用途<br>• 商业用途需授权</li></ol><h2 id="未来展望">未来展望</h2><p>微软持续推进图标设计进化：<br>• 全面应用Fluent Design设计语言<br>• 增强跨平台一致性<br>• 探索动态图标效果<br>• 优化色彩组合增强辨识度</p><blockquote><p><strong>小贴士</strong>：通过主题配置文件(<code>.theme</code>)可统一管理所有图标效果。</p></blockquote><h1>致谢</h1><div class="note default flat"><p>笔者水平有限，部分内容参考如下，专业详解可前往：<br><a href="https://blog.csdn.net/m0_46168848/article/details/132656958">Windows注册表内容详解</a><br><a href="https://blog.csdn.net/qq_22182989/article/details/122614610">Windows 批处理(bat)语法大全</a><br><a href="https://blog.csdn.net/weixin_39748445/article/details/110897260">office系统图标 imagemso7345</a><br><a href="https://zhuanlan.zhihu.com/p/93719752">环境变量的用户变量与系统变量的区别</a></p></div>]]></content>
    
    
    <summary type="html">✨了解运行与注册表，并借助bat脚本提升我们的使用效率和解决一些小问题</summary>
    
    
    
    <category term="408" scheme="https://home.y1xuanyun.cn/categories/408/"/>
    
    
    <category term="环境配置" scheme="https://home.y1xuanyun.cn/tags/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/"/>
    
    <category term="Windows" scheme="https://home.y1xuanyun.cn/tags/Windows/"/>
    
    <category term="操作系统" scheme="https://home.y1xuanyun.cn/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    
    <category term="注册表" scheme="https://home.y1xuanyun.cn/tags/%E6%B3%A8%E5%86%8C%E8%A1%A8/"/>
    
    <category term="指南" scheme="https://home.y1xuanyun.cn/tags/%E6%8C%87%E5%8D%97/"/>
    
    <category term="脚本" scheme="https://home.y1xuanyun.cn/tags/%E8%84%9A%E6%9C%AC/"/>
    
  </entry>
  
</feed>
