c++算法 | 排序| 泛型排序一劳永逸

github热门推荐 › c++算法 | 排序| 泛型排序一劳永逸 (第 75 章)
文章工具
C++ 片段需补全 main() 函数才能运行在实训台打开 →
<span leaf=""><span class="code-snippet__comment">// ====================== C++ 泛型排序完整指南 ======================</span></span></code><code><span leaf=""><span class="code-snippet__comment">// 场景:Product(价格/库存)、Student(分数/年龄)等都需要按某个字段排序</span></span></code><code><span leaf=""><span class="code-snippet__comment">// 目标:写一次排序函数,所有类通用,类型安全,零开销</span></span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string"><iostream></span></span></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string"><vector></span></span></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string"><algorithm></span></span></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string"><functional></span></span></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string"><string></span></span></span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 示例类(待排序) ======================</span></span></code><code><span leaf=""><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Product</span> {</span></code><code><span leaf=""><span class="code-snippet__keyword">public</span>:</span></code><code><span leaf="">    std::string name;</span></code><code><span leaf="">    <span class="code-snippet__type">double</span> price;</span></code><code><span leaf="">    <span class="code-snippet__type">int</span> stock;</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__built_in">Product</span>(<span class="code-snippet__type">const</span> std::string& n, <span class="code-snippet__type">double</span> p, <span class="code-snippet__type">int</span> s) </span></code><code><span leaf="">        : <span class="code-snippet__built_in">name</span>(n), <span class="code-snippet__built_in">price</span>(p), <span class="code-snippet__built_in">stock</span>(s) {}</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__function"><span class="code-snippet__type">void</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">print</span></span><span class="code-snippet__function"><span class="code-snippet__params">()</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__type">const</span></span><span class="code-snippet__function"> </span>{</span></code><code><span leaf="">        std::cout << name << <span class="code-snippet__string">" | 价格:"</span> << price << <span class="code-snippet__string">" | 库存:"</span> << stock << std::endl;</span></code><code><span leaf="">    }</span></code><code><span leaf="">};</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Student</span> {</span></code><code><span leaf=""><span class="code-snippet__keyword">public</span>:</span></code><code><span leaf="">    std::string name;</span></code><code><span leaf="">    <span class="code-snippet__type">int</span> score;</span></code><code><span leaf="">    <span class="code-snippet__type">int</span> age;</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__built_in">Student</span>(<span class="code-snippet__type">const</span> std::string& n, <span class="code-snippet__type">int</span> s, <span class="code-snippet__type">int</span> a) </span></code><code><span leaf="">        : <span class="code-snippet__built_in">name</span>(n), <span class="code-snippet__built_in">score</span>(s), <span class="code-snippet__built_in">age</span>(a) {}</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__function"><span class="code-snippet__type">void</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">print</span></span><span class="code-snippet__function"><span class="code-snippet__params">()</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__type">const</span></span><span class="code-snippet__function"> </span>{</span></code><code><span leaf="">        std::cout << name << <span class="code-snippet__string">" | 分数:"</span> << score << <span class="code-snippet__string">" | 年龄:"</span> << age << std::endl;</span></code><code><span leaf="">    }</span></code><code><span leaf="">};</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 方案1:成员指针(最推荐,零开销) ======================</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> FieldType></span></span></code><code><span leaf=""><span class="code-snippet__type">void</span> <span class="code-snippet__title">sortByField</span><span class="code-snippet__params">(std::vector<T>& items, FieldType T::* fieldPtr, </span><span class="code-snippet__params"><span class="code-snippet__type">bool</span></span><span class="code-snippet__params"> ascending = </span><span class="code-snippet__params"><span class="code-snippet__literal">true</span></span><span class="code-snippet__params">)</span> {</span></code><code><span leaf="">    std::<span class="code-snippet__built_in">sort</span>(items.<span class="code-snippet__built_in">begin</span>(), items.<span class="code-snippet__built_in">end</span>(), [fieldPtr, ascending](<span class="code-snippet__type">const</span> T& a, <span class="code-snippet__type">const</span> T& b) {</span></code><code><span leaf="">        <span class="code-snippet__keyword">if</span> (ascending)</span></code><code><span leaf="">            <span class="code-snippet__keyword">return</span> a.*fieldPtr < b.*fieldPtr;</span></code><code><span leaf="">        <span class="code-snippet__keyword">else</span></span></code><code><span leaf="">            <span class="code-snippet__keyword">return</span> a.*fieldPtr > b.*fieldPtr;</span></code><code><span leaf="">    });</span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 方案2:支持多种比较器(更灵活) ======================</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> Comparator></span></span></code><code><span leaf=""><span class="code-snippet__type">void</span> <span class="code-snippet__title">sortCustom</span><span class="code-snippet__params">(std::vector<T>& items, Comparator cmp)</span> {</span></code><code><span leaf="">    std::<span class="code-snippet__built_in">sort</span>(items.<span class="code-snippet__built_in">begin</span>(), items.<span class="code-snippet__built_in">end</span>(), cmp);</span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// 辅助生成比较器(按字段,可升降序)</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> FieldType></span></span></code><code><span leaf=""><span class="code-snippet__keyword">auto</span> <span class="code-snippet__title">makeComparator</span><span class="code-snippet__params">(FieldType T::* fieldPtr, </span><span class="code-snippet__params"><span class="code-snippet__type">bool</span></span><span class="code-snippet__params"> ascending = </span><span class="code-snippet__params"><span class="code-snippet__literal">true</span></span><span class="code-snippet__params">)</span> {</span></code><code><span leaf="">    <span class="code-snippet__keyword">return</span> [fieldPtr, ascending](<span class="code-snippet__type">const</span> T& a, <span class="code-snippet__type">const</span> T& b) {</span></code><code><span leaf="">        <span class="code-snippet__keyword">return</span> ascending ? (a.*fieldPtr < b.*fieldPtr) : (a.*fieldPtr > b.*fieldPtr);</span></code><code><span leaf="">    };</span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 方案3:链式多字段排序 ======================</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function">... FieldPtrs></span></span></code><code><span leaf=""><span class="code-snippet__type">void</span> <span class="code-snippet__title">sortByMultipleFields</span><span class="code-snippet__params">(std::vector<T>& items, FieldPtrs... fields)</span> {</span></code><code><span leaf="">    std::<span class="code-snippet__built_in">sort</span>(items.<span class="code-snippet__built_in">begin</span>(), items.<span class="code-snippet__built_in">end</span>(), [fields...](<span class="code-snippet__type">const</span> T& a, <span class="code-snippet__type">const</span> T& b) {</span></code><code><span leaf="">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__built_in">compareTuple</span>(a, b, fields...);</span></code><code><span leaf="">    });</span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// 递归比较多个字段</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> FieldType, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function">... Rest></span></span></code><code><span leaf=""><span class="code-snippet__type">bool</span> <span class="code-snippet__title">compareTuple</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">const</span></span><span class="code-snippet__params"> T& a, </span><span class="code-snippet__params"><span class="code-snippet__type">const</span></span><span class="code-snippet__params"> T& b, FieldType T::* first, Rest... rest)</span> {</span></code><code><span leaf="">    <span class="code-snippet__keyword">if</span> (a.*first != b.*first)</span></code><code><span leaf="">        <span class="code-snippet__keyword">return</span> a.*first < b.*first;</span></code><code><span leaf="">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">constexpr</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__params">(</span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__keyword">sizeof</span></span></span><span class="code-snippet__function"><span class="code-snippet__params">...(rest) > </span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__number">0</span></span></span><span class="code-snippet__function"><span class="code-snippet__params">)</span></span></span></code><code><span leaf="">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__title">compareTuple</span><span class="code-snippet__params">(a, b, rest...)</span>;</span></code><code><span leaf="">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;  <span class="code-snippet__comment">// 完全相等</span></span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 方案4:极简封装(一行调用) ======================</span></span></code><code><span leaf=""><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">SortHelper</span> {</span></code><code><span leaf=""><span class="code-snippet__keyword">public</span>:</span></code><code><span leaf="">    <span class="code-snippet__function"><span class="code-snippet__keyword">template</span></span><span class="code-snippet__function"><</span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> T, </span><span class="code-snippet__function"><span class="code-snippet__keyword">typename</span></span><span class="code-snippet__function"> FieldType></span></span></code><code><span leaf="">    <span class="code-snippet__type">static</span> <span class="code-snippet__type">void</span> <span class="code-snippet__title">by</span><span class="code-snippet__params">(std::vector<T>& items, FieldType T::* field, </span><span class="code-snippet__params"><span class="code-snippet__type">bool</span></span><span class="code-snippet__params"> asc = </span><span class="code-snippet__params"><span class="code-snippet__literal">true</span></span><span class="code-snippet__params">)</span> {</span></code><code><span leaf="">        std::<span class="code-snippet__built_in">sort</span>(items.<span class="code-snippet__built_in">begin</span>(), items.<span class="code-snippet__built_in">end</span>(), </span></code><code><span leaf="">                  [field, asc](<span class="code-snippet__type">const</span> T& a, <span class="code-snippet__type">const</span> T& b) {</span></code><code><span leaf="">                      <span class="code-snippet__keyword">return</span> asc ? a.*field < b.*field : a.*field > b.*field;</span></code><code><span leaf="">                  });</span></code><code><span leaf="">    }</span></code><code><span leaf="">};</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 方案5:宏简化(不推荐,仅作了解) ======================</span></span></code><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> SORT_BY_FIELD(vec, type, field, asc) </span></span></code><code><span leaf="">    std::sort(vec.begin(), vec.end(), [](const type& a, const type& b) { </span></code><code><span leaf="">        return asc ? a.field <span class="code-snippet__string">< b.field : a.field ></span> b.field; </span></code><code><span leaf="">    })</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><span class="code-snippet__comment">// ====================== 完整使用示例 ======================</span></span></code><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">int</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">main</span></span><span class="code-snippet__function"><span class="code-snippet__params">()</span></span><span class="code-snippet__function"> </span>{</span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"========== 原始数据 =========="</span> << std::endl;</span></code><code><span leaf="">    std::vector<Product> products = {</span></code><code><span leaf="">        {<span class="code-snippet__string">"鼠标"</span>, <span class="code-snippet__number">50.0</span>, <span class="code-snippet__number">100</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"键盘"</span>, <span class="code-snippet__number">200.0</span>, <span class="code-snippet__number">50</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"显示器"</span>, <span class="code-snippet__number">150.0</span>, <span class="code-snippet__number">30</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"耳机"</span>, <span class="code-snippet__number">80.0</span>, <span class="code-snippet__number">80</span>}</span></code><code><span leaf="">    };</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    std::vector<Student> students = {</span></code><code><span leaf="">        {<span class="code-snippet__string">"张三"</span>, <span class="code-snippet__number">85</span>, <span class="code-snippet__number">18</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"李四"</span>, <span class="code-snippet__number">92</span>, <span class="code-snippet__number">19</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"王五"</span>, <span class="code-snippet__number">78</span>, <span class="code-snippet__number">17</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"赵六"</span>, <span class="code-snippet__number">88</span>, <span class="code-snippet__number">20</span>}</span></code><code><span leaf="">    };</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__comment">// ----- 方案1:按价格升序 -----</span></span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"n[方案1] 产品按价格升序:"</span> << std::endl;</span></code><code><span leaf="">    <span class="code-snippet__built_in">sortByField</span>(products, &Product::price, <span class="code-snippet__literal">true</span>);</span></code><code><span leaf="">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__type">const</span> <span class="code-snippet__keyword">auto</span>& p : products) p.<span class="code-snippet__built_in">print</span>();</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__comment">// ----- 方案2:按分数降序(使用比较器)-----</span></span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"n[方案2] 学生按分数降序:"</span> << std::endl;</span></code><code><span leaf="">    <span class="code-snippet__keyword">auto</span> cmp = <span class="code-snippet__built_in">makeComparator</span>(&Student::score, <span class="code-snippet__literal">false</span>);</span></code><code><span leaf="">    <span class="code-snippet__built_in">sortCustom</span>(students, cmp);</span></code><code><span leaf="">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__type">const</span> <span class="code-snippet__keyword">auto</span>& s : students) s.<span class="code-snippet__built_in">print</span>();</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__comment">// ----- 方案3:多字段排序(价格优先,其次库存)-----</span></span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"n[方案3] 产品按价格升序,价格相同按库存降序:"</span> << std::endl;</span></code><code><span leaf="">    std::vector<Product> p2 = {</span></code><code><span leaf="">        {<span class="code-snippet__string">"鼠标"</span>, <span class="code-snippet__number">80.0</span>, <span class="code-snippet__number">100</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"键盘"</span>, <span class="code-snippet__number">80.0</span>, <span class="code-snippet__number">30</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"耳机"</span>, <span class="code-snippet__number">80.0</span>, <span class="code-snippet__number">80</span>}</span></code><code><span leaf="">    };</span></code><code><span leaf="">    <span class="code-snippet__built_in">sortByMultipleFields</span>(p2, &Product::price, &Product::stock);</span></code><code><span leaf="">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__type">const</span> <span class="code-snippet__keyword">auto</span>& p : p2) p.<span class="code-snippet__built_in">print</span>();</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__comment">// ----- 方案4:极简调用 -----</span></span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"n[方案4] 学生按年龄升序(SortHelper):"</span> << std::endl;</span></code><code><span leaf="">    std::vector<Student> s2 = {</span></code><code><span leaf="">        {<span class="code-snippet__string">"张三"</span>, <span class="code-snippet__number">85</span>, <span class="code-snippet__number">18</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"李四"</span>, <span class="code-snippet__number">92</span>, <span class="code-snippet__number">22</span>},</span></code><code><span leaf="">        {<span class="code-snippet__string">"王五"</span>, <span class="code-snippet__number">78</span>, <span class="code-snippet__number">17</span>}</span></code><code><span leaf="">    };</span></code><code><span leaf="">    SortHelper::<span class="code-snippet__built_in">by</span>(s2, &Student::age, <span class="code-snippet__literal">true</span>);</span></code><code><span leaf="">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__type">const</span> <span class="code-snippet__keyword">auto</span>& s : s2) s.<span class="code-snippet__built_in">print</span>();</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__comment">// ----- 方案5:宏(不推荐)-----</span></span></code><code><span leaf="">    std::cout << <span class="code-snippet__string">"n[方案5] 宏方式排序(仅演示):"</span> << std::endl;</span></code><code><span leaf="">    std::vector<Product> p3 = {{<span class="code-snippet__string">"A"</span>, <span class="code-snippet__number">100</span>, <span class="code-snippet__number">1</span>}, {<span class="code-snippet__string">"B"</span>, <span class="code-snippet__number">50</span>, <span class="code-snippet__number">2</span>}};</span></code><code><span leaf="">    <span class="code-snippet__built_in">SORT_BY_FIELD</span>(p3, Product, price, <span class="code-snippet__literal">true</span>);</span></code><code><span leaf="">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__type">const</span> <span class="code-snippet__keyword">auto</span>& p : p3) p.<span class="code-snippet__built_in">print</span>();</span></code><code><span leaf=""><br  /></span></code><code><span leaf="">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span leaf="">}</span></code><code><span leaf=""><br  /></span></code><code><span leaf=""><br  /></span>
// ====================== 输出效果预览 ======================// [方案1] 产品按价格升序:// 鼠标 | 价格:50 | 库存:100// 耳机 | 价格:80 | 库存:80// 显示器 | 价格:150 | 库存:30// 键盘 | 价格:200 | 库存:50//// [方案2] 学生按分数降序:// 李四 | 分数:92 | 年龄:19// 赵六 | 分数:88 | 年龄:20// 张三 | 分数:85 | 年龄:18// 王五 | 分数:78 | 年龄:17//// [方案3] 产品按价格升序,价格相同按库存降序:// 键盘 | 价格:80 | 库存:30// 耳机 | 价格:80 | 库存:80// 鼠标 | 价格:80 | 库存:100//// [方案4] 学生按年龄升序(SortHelper):// 王五 | 分数:78 | 年龄:17// 张三 | 分数:85 | 年龄:18// 李四 | 分数:92 | 年龄:22


#C++泛型编程
 #代码复用技巧 
#面试技巧 
#后端开发必会 
#排序算法实战

⚠️ 版权声明

本文为免费文章,欢迎转载。转载请注明出处:一木科技(https://www.pingquan.vip/2026/05/31/c%e7%ae%97%e6%b3%95-%e6%8e%92%e5%ba%8f-%e6%b3%9b%e5%9e%8b%e6%8e%92%e5%ba%8f%e4%b8%80%e5%8a%b3%e6%b0%b8%e9%80%b8/),并保留原文链接。