
c++
文章平均质量分 64
kupeThinkPoem
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
QPushButton设置菜单
/ 分离主按钮和菜单按钮。想单击按钮不弹出菜单,以为菜单是自己开发控制的,找了半天没有找到单击触发函数,原来qt中QPushButton可以设置菜单。在Qt中,可以通过QPushButton的setMenu()方法为其添加下拉菜单。3 禁用菜单项:action->setEnabled(false)。4 关联菜单:用button.setMenu(menu)设置菜单。-2菜单项图标:使用action->setIcon()添加图标。3 添加菜单项:使用menu.addAction()添加动作。原创 2025-05-30 18:18:56 · 650 阅读 · 0 评论 -
C++将地址转换为字符串
3 无前缀处理:需要纯十六进制数字时,使用方法三,但需确保 uintptr_t可用(C++11及以上)。直接利用流输出指针,自动格式化为十六进制并包含 `0x` 前缀。若需不带0x前缀,可将指针转换为 uintptr_t后输出为十六进制。通过C风格函数将指针格式化为字符串,需显式转换为 `void*`。1 默认格式:方法一和方法二生成的字符串通常包含 0x前缀。// 转换为 void* 确保类型正确。原创 2025-05-27 17:21:01 · 513 阅读 · 0 评论 -
已将析构函数隐式定义为“已删除”错误
在C++中,当联合体(union)的某个成员拥有非平凡的析构函数(如 std::string)时,联合体的析构函数会被隐式删除。2 隐式删除析构函数:若联合体包含需要析构的非平凡类型(如 std::string),编译器无法隐式生成析构函数,导致其被标记为 `= delete`。// 显式调用std::string的析构函数。特殊成员函数:联合体默认的复制/移动操作可能被删除,需手动实现(遵循三/五法则)。// 析构函数:根据标签调用对应成员的析构函数。// 标签,记录当前活跃的成员类型。原创 2025-05-22 17:38:28 · 395 阅读 · 0 评论 -
多线程环境下结构体赋值是否具有原子性?
对于基本数据类型(如 int、bool),某些情况下单次读/写可能是原子的,但结构体通常包含多个字段,其赋值操作可能涉及多个内存地址的修改,因此一般不具备原子性。1 数据大小:如果结构体的大小超过 CPU 的原子操作支持范围(例如,x86 中 8 字节的 mov 指令是原子的,但更大数据可能分多次操作)。x86/64:自然对齐的 8 字节数据(如 `int64_t`)的读写是原子的,但更大的结构体不保证。ARM:需要显式原子指令(如 LDREX/STREX),默认不保证原子性。// GCC 内存屏障。原创 2025-05-20 18:22:07 · 452 阅读 · 0 评论 -
bool变量在多线程中使用是否线程安全?
1) 无锁优化:若硬件保证原子性(如x86),可直接用`std::atomic<bool>,默认内存顺序memory_order_seq_cst保证可见性。编译器优化:编译器可能优化掉“无意义”的读取(如循环中重复读取`bool`),需用`volatile`或原子操作禁止此类优化。多线程同时写:若多个线程同时修改bool,即使单次写入是原子的,结果仍可能不确定(最后一次写入生效,但无法保证顺序)。),则不具备原子性,需额外同步。一写多读:单一写线程搭配其他读线程时,若未同步,读线程可能无法及时看到更新。原创 2025-05-20 17:45:31 · 441 阅读 · 0 评论 -
快速排序算法中的Lomuto分区
j=2, 元素 2 ≤ 4→ i=1, 交换 arr[1]和 arr[2] → 数组变为 [3, 2, 7, 5, 1, 4]。j=4, 元素 1 ≤ 4 → i=2, 交换 arr[2]和 arr[4] → 数组变为 [3, 2, 1, 5, 7, 4]。最终基准值 4位于索引 3,左子数组 [3, 2, 1]≤ 4,右子数组 [7, 5]> 4。放置基准值:交换 i+1=3和 high=5→ 数组变为 [3, 2, 1, 4, 7, 5]。原创 2025-04-14 15:23:07 · 559 阅读 · 0 评论 -
快速排序算法
由于所有元素均大于 2,基准被交换到索引 0,数组变为 [2,5,7,8,6]。分区后,5 < 6被保留在左侧,7 和 8 大于 6,最后交换基准到正确位置,数组变为 [2,5,6,8,7]。分区后,8 > 7 被交换到右侧,基准 7 被放到正确位置,数组变为 [2,5,6,7,8]。此时基准位置 pi=0,递归处理左半部分(空)和右半部分 [5,7,8,6]。对整个数组 [6,5,7,8,2]进行排序,low=0,high=4。三 分步说明(以数组 [6, 5, 7, 8, 2]为例)原创 2025-04-14 11:13:37 · 489 阅读 · 0 评论 -
_mm_malloc解析
mm_malloc 是用于内存分配的函数,专为SIMD指令集(如SSE、AVX等)设计,确保分配的内存满足特定字节对齐要求。通过合理使用_mm_malloc,可以显著提升SIMD代码的稳定性和性能,尤其在处理图像数据、科学计算等需要批量操作的场景中效果显著。原创 2025-04-03 09:45:48 · 367 阅读 · 0 评论 -
四个元素最大值的simd优化
3 数据类型:本示例适用于32位整数,浮点数需改用_mm_max_ps。2 减少指令数:从4次比较减少到2次向量操作。2)第一次移位后:[2, 6, 3, 1]4)第二次移位后:[3,3, 6, 6]5) 比较结果:[6, 6, 6, 6]1)初始向量:[6, 2, 1, 3]3)比较结果:[6, 6, 3, 3]原创 2025-04-03 09:31:50 · 416 阅读 · 0 评论 -
#pragma omp single 解析
pragma omp single 是 OpenMP(一种用于共享内存并行编程的 API)中的一种工作共享指令,用于在并行区域内指定一个代码块仅由单个线程执行,其他线程会等待该代码块执行完毕后再继续(除非显式取消同步)。1)单线程执行:在并行区域(#pragma omp parallel)内部,标记的代码块会被任意一个可用线程执行(不固定是主线程)。2)#pragma omp single:由任意一个线程执行,且默认有隐式同步。3)独立性:single 块内的变量默认是共享的(除非显式声明为私有变量)。原创 2025-04-02 09:37:36 · 544 阅读 · 0 评论 -
使用OpenMP并行化优化归并排序算法
4. 最终合并:将 [4,6,7] 和 [5,9] 合并为 [4,5,6,7,9]。2)左子数组继续分解为 [6,4] 和 [7]→ 合并为 [4,6,7];4) 最终合并 [4,6,7] 和 [5,9]→ [4,5,6,7,9]。2)左子任务 [0,1](长度2)触发串行处理 → 合并为 [4,6]。-分割为左 [0,2](6,4,7)和右 [3,4]($9,5$)。1)长度 3 > 2,继续并行分解为 [0,1] 和 [2,2]。3) 右子任务 [2,2] 直接返回 → 合并为 [4,6,7]。原创 2025-04-02 09:31:00 · 934 阅读 · 0 评论 -
_mm_storeu_si128解析
这是Intel SSE2指令集提供的内在函数(intrinsic),用于将128位SIMD寄存器(__m128i类型)中的数据非对齐存储到内存地址。函数原型:void _mm_storeu_si128(__m128i∗ mem_addr, __m128i a)对齐存储 _mm_store_si128 更快。非对齐存储 _mm_storeu_si128 稍慢。1)不对齐存储:允许存储到任意内存地址(无需16字节对齐)2)网络协议解析(非对齐数据包处理);原创 2025-04-01 10:48:40 · 262 阅读 · 0 评论 -
块交换递归算法
block_swap_rotate(arr, start, end, d) 处理数组的 [start, end]区间,旋转前 d个元素到末尾。对数组 [1,2,3,4,5,7,8]旋转3位后结果为 [4,5,7,8,1,2,3]。以{1, 2, 3, 4, 5, 6,7, 8}将前3个元素移到末尾为例。1. 将数组分为前`d`个元素(块A)和剩余元素(块B);// 交换右块和左块前right_len个元素。// 交换左块和右块前left_len个元素。d = d % n;1) 交换A和B的前d个元素;原创 2025-04-01 10:31:20 · 575 阅读 · 0 评论 -
三次反转法(手摇算法)
1 左移k位:修改为reverse(0, k-1) → reverse(k, n-1) → reverse(0, n-1)reverse(arr, k, n-1);2 负数处理:若k<0,转换为等效的正数位移(如左移2位等价于右移3位)。2. 前2个反转 → [4,5,3,2,1]3. 后3个反转 → [4,5,1,2,3]1. 整体反转 → [5,4,3,2,1]2 前k个元素反转:反转前k个元素。原创 2025-03-31 12:24:05 · 345 阅读 · 0 评论 -
两个有序序列的合并-手摇算法
以数组 [1,4,7,9,2,5,6,8]为例,合并左块 [1,4,7,9]和右块 [2,5,6,8]。7 > 5,找到右块中连续比 7 小的元素(5,6)。左块:[1,4,7,9] 右块:[2,5,6,8]数组变为:[1,2,4,7,9,5,6,8]数组变为:[1,2,4,5,6,7,9,8]数组变为:[1,2,4,5,6,7,8,9]数组:[1,4,7,9,2,5,6,8]原创 2025-03-31 11:29:43 · 562 阅读 · 0 评论 -
std::countr_zero
std::countr_zero 是 C++20 标准引入的位操作函数,用于计算无符号整数的二进制表示中末尾零(Trailing Zeros)的数量。旧代码可继续使用 __builtin_ctz,但需自行处理 x=0 的情况。通过 std::countr_zero,C++ 提供了一种高效且安全的位操作工具,适用于从底层系统编程到算法优化的广泛场景。若 x = 0,返回 T 的位数(例如 32 对应 uint32_t)。输入为 0 时,返回类型的位数(如 8 位类型返回 8),无未定义行为。原创 2025-03-29 20:29:17 · 574 阅读 · 0 评论 -
归并排序算法的非递归实现
代码的关键点在于正确控制子数组的大小和合并的边界条件,确保所有元素最终被合并排序。通过临时数组合并两个有序区间$[left, mid]和[mid+1, right]。1) 合并[5,6,7,8]和[2]$→ $[2,5,6,7,8]$1) 合并[5,6]和[7,8]→ [5,6,7,8]二 算法步骤(以数组[6,5,7,8,2]$为例)1) 合并[6]和[5] → [5,6]2) 合并[7]和[8] → [7,8]3) 数组变为:[5,6,7,8,2]2) 数组变为:[5,6,7,8,2]原创 2025-03-29 20:15:13 · 505 阅读 · 0 评论 -
_mm_blend_ps解析
mm_blend_ps 通过立即数掩码高效混合向量元素,适用于需静态确定数据源的 SIMD 优化场景。则结果向量为 { a[0], a[1], b[2], b[3] } → {1.0, 2.0, 13.0, 14.0}1)_mm_shuffle_ps 通过掩码重排元素,功能更复杂(支持跨通道复制),但需要更多时钟周期。2)_mm_blendv_ps 使用向量掩码(非立即数),掩码可动态计算,灵活性高但效率略低。3)_mm_blend_ps 立即数掩码,编译时确定,效率更高。原创 2025-03-28 10:44:23 · 473 阅读 · 0 评论 -
两个有序序列合并-双指针法
每次比较 arr1[i]和 arr2[j],将较小值放入结果数组。选择更小的 0,结果变为 [0],指针 j后移。选择 1,结果变为 [0,1],指针 i 后移。选择 2,结果变为 [0,1,2],指针 i后移。2 比较 arr1[0]=1和 arr2[1]=4。arr1: [1, 2, 3, 6, 9] 指针i=0。arr2: [0, 4, 5, 7, 8] 指针j=0。1 比较 arr1[0]=1和 arr2[0]=0。3 比较 arr1[1]=2和 arr2[1]=4。原创 2025-03-28 10:31:16 · 558 阅读 · 0 评论 -
_mm_blendv_ps解析
mm_blendv_ps 是 Intel SSE4.1 指令集 中的一条 SIMD 指令,用于对两个单精度浮点数向量(128 位)进行条件混合操作。其核心功能是:根据掩码(mask)向量的值,从两个输入向量中选择对应的元素组合成新向量。掩码通常通过比较指令生成(如 _mm_cmplt_ps、_mm_cmpgt_ps),或手动构造(如 _mm_set1_ps(-0.0f))。避免频繁生成掩码,尽量复用。原创 2025-03-27 11:46:43 · 376 阅读 · 0 评论 -
合并两个有序序列—逆向双指针
逆向双指针是一种常用于处理两个有序序列的高效算法技巧,其核心思想是从序列的末尾开始遍历,避免覆盖有效数据或多次移动元素。1)合并两个有序数组(如 nums1 和 nums2,其中 nums1 尾部有预留空间)。// 处理nums2剩余元素(无需处理nums1剩余,因为它们已在正确位置)1)比较 nums1[i] 和 nums2[j],将较大值放入 nums1[k]。3)处理剩余元素:若 nums2 有剩余元素,直接复制到 nums1 头部。i 指向第一个序列有效元素末尾(如 nums1 的最后一个元素)原创 2025-03-27 11:39:58 · 1306 阅读 · 0 评论 -
_mm_cmpgt_epi8 和_mm_cmpgt_epi32 详解
mm_cmpgt_epi8适用于细粒度(字节级别)的有符号整数比较_mm_cmpgt_epi32,适用于大范围(32 位整数)的有符号数值比较。若 a = [100, -200, 300, 400],b = [50, -100, 300, 0],则结果为 [0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF]。若 a = [10, -5, 3, ...],b = [5, -3, 3, ...],则结果为 [0xFF, 0x00, 0x00, ...]。原创 2025-03-26 09:48:37 · 298 阅读 · 0 评论 -
数组子序列冒泡比较的SIMD优化
使用_mm_loadu_si128加载每块中连续的4个整数(128位寄存器),通过_mm_cmpgt_epi32比较对应元素大小,生成掩码。用_mm_blendv_epi8根据掩码混合两个块的数据:将较大值保留在块i+1,较小值留在块i,最后将结果写回内存。若数组按16字节对齐,改用_mm_load_si128和_mm_store_si128提升加载/存储效率。依次遍历每对相邻块(块i与块i+1),若块i+1中某位置元素大于块i的对应位置元素,则交换二者。// 处理剩余不足4个的元素。原创 2025-03-26 09:38:59 · 1106 阅读 · 0 评论 -
_mm_blendv_epi8解析
mm_blendv_epi8是 Intel SIMD 指令集(SSE4.1 引入)中的一个函数,用于按字节(8 位)条件混合两个 128 位向量的内容。通过 _mm_blendv_epi8,开发者可以高效实现基于条件的逐字节数据选择,避免分支预测开销,提升 SIMD 代码性能。根据掩码(mask)向量的每个字节的最高位,选择两个输入向量(a和 b)对应字节的值。mask:控制混合的掩码向量(128 位,每个字节的最高位决定选择 a 或 b)。如果掩码字节的最高位为 0,则选择第一个向量 a的对应字节。原创 2025-03-25 16:27:48 · 360 阅读 · 0 评论 -
数组子序列比较的SIMD优化
给定数组 [6, 5, 7, 8, 2, 9],子序列间隔为3,可将其平均分为前3个和后3个元素。仅更新有效元素(前3个和后3个),忽略填充值。将前3个和后3个元素加载到两个128位向量(__m128i),填充第四个元素为0。分割数组:前半为 [6, 5, 7],后半为 [8, 2, 9]。2) 掩码混合:利用 _mm_blendv_epi8 快速选择保留的值。3) 通过SSE优化,将逐元素比较与交换转化为向量操作,提升了计算效率。结果:[6, 2, 7, 8, 5, 9]。// 根据掩码混合向量。原创 2025-03-25 15:55:57 · 866 阅读 · 0 评论 -
归并排序算法
4)最终合并 [5 6 7] 和 [2 8]→ [2 5 6 7 8]。3) 合并右半部分 [8] 和[2]→ 合并为 [2 8]。2)合并:将相邻有序子数组合并为一个有序数组,直到全部合并。2) 合并 [5 6] 和 [7] → [5 6 7]。[6 5 7] 和[8 2]。1)合并 [6]和 [5] → [5 6]。二、分步演示(数组[6 5 7 8 2])2)第2层分解左半部分 [6 5 7]3)第2层分解右半部分 [8 2]原创 2025-03-22 19:57:56 · 348 阅读 · 0 评论 -
Ciura序列
2) 后续增量可通过最后一个元素乘以2.25生成(如:701*2.25=1577,1577*2.25=3548...)。1)经验证最优的初始序列为:[1, 4, 10, 23, 57, 132, 301, 701]3)时间复杂度约为O(n^{3/2}),优于传统希尔排序的O(n^2)。3)性能优化:Ciura序列在中等规模数据(n ≤ 10^6)表现最佳。1)逆序使用序列:必须从最大间隔开始递减。原创 2025-03-22 19:24:39 · 234 阅读 · 0 评论 -
希尔排序中的Hibbard序列
递推公式:每次k增加1,计算 h_{k+1}=2^{k+1}-1。while ((1 << k) - 1 < n) { // 1<<k等价于2^k。作为希尔排序的步长(间隔序列),用于将数据分为多个子序列进行插入排序。其中k从1开始递增,序列为:1, 3, 7, 15, 31, 63, …1)最坏情况:O(n^{3/2}),优于原始希尔排序的O(n^2)。起始条件:k=1,对应h_1=2^1-1=1。// 找到最大的k使得2^k -1 < n。原创 2025-03-21 10:02:11 · 447 阅读 · 0 评论 -
希尔排序算法
希尔排序(Shell Sort)是一种基于插入排序的改进算法,通过分组插入排序逐步减少元素移动次数,提升排序效率。平均情况:O(n log n)到 O(n^{1.5}),优于直接插入排序。本例数组[6 5 7 8 2]长度为5,增量序列为:gap = 2 ->1。2 时间复杂度:最坏情况下为 O(n^2),但优于普通插入排序。排序后数组变为: [2, 5, 6,8,7]最坏情况:O(n^2)(取决于增量序列)。最终有序数组: [2,5, 6, 7, 8]插入排序后 → [2, 6, 7]原创 2025-03-18 08:57:54 · 750 阅读 · 0 评论 -
_mm_movemask_epi8解析
通过 _mm_movemask_epi8,开发者可以将 SIMD 并行计算结果快速压缩为标量掩码,从而简化分支处理和后续逻辑,是 SIMD 编程中的关键工具之一。_mm_movemask_epi8 是 Intel SIMD 指令集(SSE/AVX)中的一个重要函数,主要用于从 128 位向量寄存器中提取字节级别的掩码信息。AVX2 提供 _mm256_movemask_epi8,支持 256 位向量(生成 32 位掩码)。原创 2025-03-17 10:31:35 · 390 阅读 · 0 评论 -
std::merge和std::inplace_merge对比分析
std::merge需要输入区间和目标区间的迭代器 , std::inplace_merge为同一容器的迭代器。std::merge需要额外存储空间(目标区间),std::inplace_merge无需额外空间。2)std::inplace_merge合并同一容器的两个连续有序子区间。// 合并到 dst,结果为 {1,2,3,4,5,6}// 合并整个区间,v 变为 {1,2,3,4,5,6}原创 2025-03-15 16:36:54 · 258 阅读 · 0 评论 -
std::inplace_merge解析
std::inplace_merge 是 C++ 标准库 <algorithm> 中的算法,用于将 两个已排序的相邻范围 合并为一个有序范围,且 原地操作(无需额外存储空间)。将 [first, middle) 和 [middle, last) 合并为 [first, last),保持整体有序。[first, middle) 和 [middle, last) 必须已按相同顺序(升序/降序)排序。双向迭代器(如 std::list, std::deque, std::vector)。// 合并两个有序区间。原创 2025-03-15 16:19:09 · 617 阅读 · 0 评论 -
插入排序算法的SIMD优化
AVX 系列:AVX/AVX2(256位寄存器)。SSE 系列:SSE/SSE2/SSE3/SSE4(128位寄存器)。// 存储到[i-2, i-1, i, i+1]位置(右移一位)// 加载[i-3, i-2, i-1, i]位置的元素。使用数组右移一位的SIMD算法来优化插入排序算法。// 从倒数第二个元素开始处理。// SSE处理:每次4个元素,从右往左。// 处理剩余元素(无法组成4个的部分)// simd批量移动元素。// 找到插入位置pos。// 将末尾元素放到首位。// 保存最后一个元素。原创 2025-03-14 10:07:31 · 495 阅读 · 0 评论 -
数组右移一位SIMD优化
存储:向右移动一位,存储到i-2的位置(如i=5时,存储到arr[3], arr[4], arr[5], arr[6])加载:从i-3开始加载4个元素(如i=5时,加载arr[2], arr[3], arr[4], arr[5])// 存储到[i-2, i-1, i, i+1]位置(右移一位)// 加载[i-3, i-2, i-1, i]位置的元素。2)SSE批量移动:从右向左每次加载4个元素到寄存器,存储到右侧位置。3)处理剩余元素:对无法组成4个元素的剩余部分,用普通循环处理。原创 2025-03-14 09:48:29 · 686 阅读 · 0 评论 -
MEMCPY与MEMMOVE的区别
在 VS2015 的 memcpy 实现中,可能调用 SSE/AVX 指令集优化的块复制操作某些情况下会自动选择复制方向(类似 memmove),但非官方保证行为。if(s < d && s + n > d) { // 检测正向复制是否会导致覆盖。// 改为从高地址向低地址复制。// 从低地址向高地址复制。memmove 允许(自动处理重叠) 检测重叠区域,智能选择复制方向。安全性 低(需手动确保安全) 高(自动处理重叠)// 插入排序元素移动(源与目标区域重叠)原创 2025-03-13 09:49:38 · 426 阅读 · 0 评论 -
使用memmove优化插入排序
传统插入排序通过循环逐位移动元素完成插入,而memcpy/memmove优化利用内存操作函数批量移动连续内存,减少循环开销。插入4(i=1) 1次 1次(等效)2 )批量移动:将arr[0..0](元素6)后移1位。2)批量移动:将arr[0..3](4,6,7,8)后移1位。以数组 [6,4,7,8, 2] 为例来演示优化步骤。结果: [4, 6, 7, 8, 2]目标位置: [4,6,7,8 → 全部后移1位]结果: [2, 4, 6, 7, 8]原创 2025-03-13 09:16:23 · 208 阅读 · 0 评论 -
alignas解析
不能小于类型的自然对齐(可通过 alignof 查询),可叠加使用(取最大值)。它是C++11引入的对齐说明符(Alignment Specifier,允许显式指定变量或类型的对齐要求。作用:提高内存访问效率(硬件可能无法读取未对齐的数据)或满足硬件强制要求(如SIMD指令)。static_assert(alignof(Example) == 8, "对齐失败");3 实际对齐值取 alignas指定值和类型自然对齐的最大值。语法格式:alignas(N) 或 alignas(类型)。原创 2025-03-12 10:36:27 · 365 阅读 · 0 评论 -
C++数组拷贝
/ 仅复制指针,内存共享。// 直接赋值即可完成深拷贝。1. 优先使用 std::array或 std::vector。1. 浅拷贝(Shallow Copy):仅复制指针/地址。2. 深拷贝(Deep Copy):完整复制内存数据。2. 普通数组建议用 std::copy。2. 使用 std::copy(推荐)2)对象数组需注意拷贝构造函数。// 或使用 vector。原创 2025-03-12 08:50:07 · 605 阅读 · 0 评论 -
插入排序算法优化
对于未排序部分的每个元素,在已排序序列中从后向前扫描,找到合适位置插入。while (arr[j] > temp) { // 无需检查j >=0(因为首元素是哨兵)在寻找插入位置时,使用二分查找代替顺序查找,将比较次数从O(n)降低到O(log n)。比较次数O(n log n),移动次数仍为O(n^2)→ 整体O(n^2),但常数更小。i++) // 先找到最小值作为哨兵。1. 小规模数据(n< 1000):优先使用原始插入排序。最差:O(n^2)(完全逆序)最优:O(n)(已有序)原创 2025-03-11 10:41:20 · 991 阅读 · 0 评论 -
插入排序算法
/ 已排序区的末尾索引。// 插入到正确位置。[6 | 5 7 8 2] // 已排序区:6,未排序区:5 7 8 2。- 最差情况(完全逆序):总比较次数n(n-1)/2 O(n^2)[5 6 7 8 | 2] // 已排序区:5 6 7 8。[5 6 7 | 8 2] // 已排序区:5 6 7。[5 6 | 7 8 2] // 已排序区:5 6。- 最优情况(已有序):仅需比较n-1次 O(n)[2 5 6 7 8] // 排序完成。原创 2025-03-11 09:48:04 · 502 阅读 · 0 评论