顺序查找与二分查找:C语言实现与算法效率深度解析
1. 项目概述从“找东西”到“找数据”的算法思维在程序员的日常里“查找”这个动作其本质和我们生活中在书架上找一本书、在通讯录里找一个电话号码没什么两样。但正是这个看似简单的动作在计算机科学里却演化出了一整套精妙的理论和算法。今天我们就来聊聊两种最基础、也最经典的查找算法顺序查找和二分查找并用最纯粹的C语言来实现它们。这不仅仅是写几行代码更是理解算法效率差异的起点是构建高效程序思维的基石。无论你是刚接触数据结构的新手还是想重温基础的老手这篇文章都将带你从零开始手把手实现这两种算法。我们会深入探讨它们各自的适用场景、时间复杂度背后的含义以及在实际编码中那些容易被忽略的细节和“坑”。你会发现简单的算法背后藏着对数据组织方式的深刻理解。准备好了吗让我们开始这场从“蛮力”到“智慧”的查找之旅。2. 算法核心思想与适用场景解析2.1 顺序查找最朴素的“地毯式搜索”顺序查找顾名思义就是按照数据存储的顺序从头到尾或从尾到头逐个进行比较直到找到目标元素或遍历完整个数据集。它的思想直白得就像你在一本没有目录的书中逐页寻找某个关键词。2.1.1 算法逻辑与时间复杂度其核心逻辑可以用一句话概括遍历数组将每个元素与目标值比较相等则返回位置索引遍历完毕未找到则返回一个特定值如-1。用伪代码表示就是for i from 0 to n-1: if array[i] target: return i return -1这种算法的时间复杂度是O(n)。这意味着在最坏情况下目标元素在末尾或不存在你需要检查数组中的每一个元素。n是数据规模执行时间随n线性增长。2.1.2 为什么它依然重要既然效率不高为什么还要学它原因有三普适性极强顺序查找对数据没有任何要求。无论数组是否有序无论存储的是什么类型的数据它都能工作。这是它的最大优势。实现简单不易出错代码逻辑清晰是初学者理解循环和条件判断的绝佳案例。小数据量的实用选择当数据量非常小比如几十个元素时顺序查找的绝对耗时很短且省去了为数据排序的开销排序本身也是耗时的此时它可能比先排序再使用高效查找算法更经济。注意在实际工程中如果查找操作非常频繁即使数据量不大也应考虑使用更高效的数据结构如哈希表来替代顺序查找。顺序查找更适合于“一次性”或“低频次”的查找场景。2.2 二分查找基于有序的“分而治之”二分查找是算法效率提升的一个经典范例。它的前提是数据必须有序通常是升序排列。其思想类似于我们查字典你不会从第一页开始逐页翻而是先翻开中间根据中间页的字母决定是向前还是向后查找不断将搜索范围减半。2.2.1 算法逻辑与时间复杂度算法步骤如下确定当前查找范围的左边界left和右边界right初始时left0,rightn-1。计算中间位置mid left (right - left) / 2。这里使用这种写法而非(leftright)/2是为了防止leftright可能导致的整数溢出。比较array[mid]与目标值target如果array[mid] target查找成功返回mid。如果array[mid] target说明目标值只可能存在于右半部分调整left mid 1。如果array[mid] target说明目标值只可能存在于左半部分调整right mid - 1。重复步骤2-3直到left right此时查找失败返回-1。二分查找的时间复杂度是O(log n)。这是一个极其高效的增长级别。举例来说在一个包含10亿1,000,000,000个元素的有序数组中查找一个值顺序查找最坏需要10亿次比较而二分查找最坏仅需约30次比较因为 2^30 ≈ 10.7亿。效率差距天壤之别。2.2.2 适用场景与局限性二分查找的强大建立在有序的基础上。因此它的典型应用场景包括静态有序表查找如字典、电话簿、商品价格表等一旦建立就很少变动且需要频繁查找的数据集合。编程语言标准库中的实现如C的std::binary_searchJava的Arrays.binarySearch()其内部都使用了二分或变种算法。解决复杂问题的子步骤在许多算法问题中如“在旋转排序数组中搜索”二分查找的思想是解题关键。其局限性也很明显必须有序这是硬性要求。如果数据集经常插入、删除维护有序性的成本每次操作后重新排序或使用平衡二叉搜索树等数据结构必须被考虑在内。仅适用于顺序存储结构二分查找依赖于通过下标随机访问元素因此数组是最佳搭档。对于链表这类顺序访问的结构二分查找无法发挥其优势。数据量太小不划算如果数据只有几个或几十个排序加上二分查找的总开销可能超过直接顺序查找。3. C语言实现详解与关键代码剖析理解了思想接下来我们用C语言将其实现。我们将分别实现顺序查找和二分查找的函数并提供一个完整的测试程序。3.1 顺序查找的C实现/** * 顺序查找函数 * param arr 整型数组 * param n 数组长度 * param target 要查找的目标值 * return 如果找到目标值返回其索引0-based如果未找到返回-1。 */ int sequential_search(int arr[], int n, int target) { for (int i 0; i n; i) { if (arr[i] target) { return i; // 找到立即返回索引 } } return -1; // 遍历完毕未找到 }代码要点与避坑指南参数设计将数组、数组长度和目标值作为参数传入这是C语言处理数组的通用做法。切记C数组作为函数参数时会退化为指针因此必须显式传递长度n。循环条件i n确保了遍历从0到n-1的所有有效索引。这是避免数组越界访问的关键。提前返回在循环内部一旦找到目标立即使用return返回。这是一个好的习惯避免了使用额外的标志变量。返回值选择使用-1表示查找失败是一个广泛接受的约定因为有效的数组索引是非负的。3.2 二分查找的C实现迭代版本迭代版本使用循环是更常用且直观的实现方式。/** * 二分查找函数迭代版本 * param arr 升序排列的整型数组 * param n 数组长度 * param target 要查找的目标值 * return 如果找到目标值返回其索引如果未找到返回-1。 */ int binary_search_iterative(int arr[], int n, int target) { int left 0; int right n - 1; // 注意初始右边界是有效索引 while (left right) { // 关键何时循环继续 // 防止(leftright)溢出等同于(leftright)/2 int mid left (right - left) / 2; if (arr[mid] target) { return mid; } else if (arr[mid] target) { // 目标在右半部分调整左边界 left mid 1; // 注意mid已经检查过所以从mid1开始 } else { // 目标在左半部分调整右边界 right mid - 1; // 注意mid已经检查过所以到mid-1结束 } } // 循环结束意味着 left right查找区间为空未找到 return -1; }这是二分查找最容易出错的部分我们来逐行解析循环条件while (left right)这是核心。left right意味着当前的查找区间[left, right]是有效的、非空的。当left right时区间内还有一个元素需要检查。如果写成left right那么当left right时即区间内只剩一个元素循环会提前退出导致这个元素没有被检查可能造成查找失败。务必记住确保了区间内所有元素都被考虑到。中间位置计算mid left (right - left) / 2这是标准的防溢出写法。当left和right都是很大的正数时left right可能会超出int类型的最大值导致溢出变成负数进而计算出错误的mid。而left (right - left) / 2在数学上等价但避免了加法运算更安全。虽然在学习阶段数据量小可能遇不到但养成这个习惯是专业性的体现。边界调整left mid 1和right mid - 1这是另一个关键点。因为我们在if条件中已经明确判断了arr[mid]不等于target所以mid这个位置绝对不可能是目标值。因此下一步的搜索区间应该完全排除mid这个索引。将左边界设为mid1或将右边界设为mid-1可以有效地缩小搜索范围避免死循环例如当left和right相邻时如果只设left mid或right mid可能会导致区间无法继续缩小。3.3 二分查找的C实现递归版本递归版本体现了二分查找“分而治之”的思想本质代码更简洁但会有递归调用的开销。/** * 二分查找的递归辅助函数 * param arr 升序数组 * param left 当前查找区间的左边界 * param right 当前查找区间的右边界 * param target 目标值 * return 找到返回索引未找到返回-1 */ int binary_search_recursive_helper(int arr[], int left, int right, int target) { // 递归基查找区间无效说明未找到 if (left right) { return -1; } int mid left (right - left) / 2; if (arr[mid] target) { return mid; } else if (arr[mid] target) { // 递归搜索右半部分 return binary_search_recursive_helper(arr, mid 1, right, target); } else { // 递归搜索左半部分 return binary_search_recursive_helper(arr, left, mid - 1, target); } } /** * 二分查找函数递归版本的对外接口 * param arr 升序排列的整型数组 * param n 数组长度 * param target 要查找的目标值 * return 如果找到目标值返回其索引如果未找到返回-1。 */ int binary_search_recursive(int arr[], int n, int target) { return binary_search_recursive_helper(arr, 0, n - 1, target); }递归版本注意事项递归深度二分查找的递归深度是 O(log n)对于通常的数据规模比如n10^9这个深度不会导致栈溢出。但理论上如果数组极其巨大这几乎不会发生在内存数组中需要考虑递归深度问题。简洁与开销递归代码逻辑清晰直接反映了算法定义。但每次递归调用都会产生函数调用的开销压栈、跳转等在性能极其敏感的场合迭代版本通常是更优的选择。4. 完整测试程序与结果分析理论结合实践下面是一个完整的测试程序它包含了数组定义、两种查找算法的调用以及详细的输出。#include stdio.h #include time.h // 用于简单计时对比 // 此处插入上面定义的三个函数sequential_search, // binary_search_iterative, binary_search_recursive int main() { // 测试用例设计 int sorted_arr[] {2, 5, 8, 12, 16, 23, 38, 45, 56, 67, 78, 89, 90}; int unsorted_arr[] {23, 5, 78, 45, 16, 2, 90, 67, 38, 8, 12, 56, 89}; int n sizeof(sorted_arr) / sizeof(sorted_arr[0]); // 计算数组长度 int targets[] {23, 1, 90, 45}; // 要查找的目标值存在首中后、不存在 int num_targets sizeof(targets) / sizeof(targets[0]); printf( 顺序查找测试 (无序数组) \n); for (int i 0; i num_targets; i) { int result sequential_search(unsorted_arr, n, targets[i]); if (result ! -1) { printf(目标值 %d 在无序数组中找到索引为: %d\n, targets[i], result); } else { printf(目标值 %d 在无序数组中未找到。\n, targets[i]); } } printf(\n 二分查找测试 (有序数组) \n); printf(有序数组内容: ); for (int i 0; i n; i) printf(%d , sorted_arr[i]); printf(\n\n); for (int i 0; i num_targets; i) { int result_iter binary_search_iterative(sorted_arr, n, targets[i]); int result_recur binary_search_recursive(sorted_arr, n, targets[i]); printf(目标值: %d\n, targets[i]); printf( 迭代版本结果: %s (索引: %d)\n, result_iter ! -1 ? 找到 : 未找到, result_iter); printf( 递归版本结果: %s (索引: %d)\n, result_recur ! -1 ? 找到 : 未找到, result_recur); // 验证两个版本结果是否一致 if (result_iter result_recur) { printf( [验证通过] 两种实现结果一致。\n); } else { printf( [错误] 两种实现结果不一致\n); } printf(\n); } // 简单性能对比演示思想非严谨基准测试 printf( 简单效率对比演示 \n); // 创建一个更大的有序数组用于对比 const int large_n 10000; int large_arr[large_n]; for (int i 0; i large_n; i) large_arr[i] i * 2; // 填充一个有序大数组 int target_exist 18998; // 存在于数组中 int target_miss 18999; // 不存在于数组中 clock_t start, end; double cpu_time_used; // 测试顺序查找存在 start clock(); sequential_search(large_arr, large_n, target_exist); end clock(); cpu_time_used ((double)(end - start)) / CLOCKS_PER_SEC; printf(顺序查找 (存在元素) 耗时: %.6f 秒\n, cpu_time_used); // 测试二分查找存在 start clock(); binary_search_iterative(large_arr, large_n, target_exist); end clock(); cpu_time_used ((double)(end - start)) / CLOCKS_PER_SEC; printf(二分查找 (存在元素) 耗时: %.6f 秒\n, cpu_time_used); // 测试顺序查找不存在-最坏情况 start clock(); sequential_search(large_arr, large_n, target_miss); end clock(); cpu_time_used ((double)(end - start)) / CLOCKS_PER_SEC; printf(顺序查找 (不存在元素-最坏) 耗时: %.6f 秒\n, cpu_time_used); // 测试二分查找不存在-最坏情况 start clock(); binary_search_iterative(large_arr, large_n, target_miss); end clock(); cpu_time_used ((double)(end - start)) / CLOCKS_PER_SEC; printf(二分查找 (不存在元素-最坏) 耗时: %.6f 秒\n, cpu_time_used); printf(\n提示以上时间仅供参考实际运行时间受系统负载影响。但数量级差异清晰可见。\n); return 0; }测试程序解析与预期输出测试用例设计我们准备了一个有序数组sorted_arr和一个无序数组unsorted_arr内容相同但顺序不同。目标值数组targets包含了存在于数组中间、开头、末尾以及不存在的值以测试各种边界情况。顺序查找测试在无序数组上进行验证其普适性。二分查找测试在有序数组上进行并同时调用迭代和递归版本验证它们结果的一致性。这是交叉验证的好方法。简单性能对比通过clock()函数粗略计算两种算法在较大数据量10000个元素下的耗时。请注意这种单次测量并不严谨用于教学演示可以直观感受 O(n) 和 O(log n) 的差异。在实际项目中需要使用更专业的基准测试工具和方法。预期输出会显示顺序查找能正确在无序数组中找到存在的值。二分查找两种实现能在有序数组中找到存在的值且结果一致。对于不存在的值两种算法都返回-1。在效率对比部分二分查找的耗时将远低于顺序查找尤其是对于“不存在”的最坏情况尽管绝对时间可能很短但相对差距显著。5. 常见问题、边界条件与实战技巧即使理解了原理和代码在实际编码和面试中依然会遇到一些陷阱。下面是我总结的几个关键点和实战技巧。5.1 二分查找的“坑”与变体1. 死循环问题最常见的错误出在循环条件和边界更新上。如果你将循环条件写为while (left right)但更新边界时用了right mid或left mid在某些情况下例如left 3, right 4, mid 3且arr[3] target更新后left mid (3)区间没有变化导致无限循环。牢记标准写法while (left right)配合left mid 1/right mid - 1。2. 查找第一个/最后一个等于目标值的位置有重复元素标准的二分查找找到任意一个等于目标值的索引就返回。但如果数组中有重复元素题目要求找到第一个或最后一个出现的位置呢例如数组[1, 2, 2, 2, 3]查找2要求返回第一个索引1或最后一个索引3。查找第一个等于target的位置当arr[mid] target时不立即返回而是让right mid - 1继续在左半部分查找直到循环结束。最后检查left是否越界以及arr[left]是否等于target。查找最后一个等于target的位置当arr[mid] target时让left mid 1继续在右半部分查找直到循环结束。最后检查right是否越界以及arr[right]是否等于target。3. 查找第一个大于等于target的位置lower_bound这是C STL中lower_bound的功能非常有用。它返回第一个不小于target 的元素位置。实现时当arr[mid] target则left mid 1否则arr[mid] targetright mid - 1并记录可能的答案mid。循环条件通常用while (left right)最终返回left或记录的有效答案。5.2 工程实践中的考量1. 如何选择顺序查找还是二分查找做一个简单的决策流程图数据是否有序如果否且排序成本高或查找频次低 -顺序查找。数据量是否非常小例如n20如果是 -顺序查找代码简单常数因子小。否则 -二分查找。如果数据动态变化频繁插入删除需要高效查找 - 考虑二叉搜索树BST、平衡树AVL红黑树或跳表Skip List它们能在保持有序的同时支持高效的动态操作。2. 泛型实现我们的示例是针对int类型的。在C语言中要实现泛型查找可以使用void*指针和比较函数回调类似于标准库的qsort和bsearch函数。这是进阶C程序员必须掌握的技能。// 仿照 bsearch 的泛型二分查找思路 void* generic_binary_search(const void* key, const void* base, size_t num, size_t size, int (*compar)(const void*, const void*)) { const char* left (const char*)base; const char* right left (num - 1) * size; while (left right) { size_t offset ((right - left) / (2 * size)) * size; // 计算字节偏移量 const char* mid left offset; int cmp_result compar(key, (const void*)mid); if (cmp_result 0) { return (void*)mid; } else if (cmp_result 0) { left mid size; } else { right mid - size; } } return NULL; }3. 浮点数比较如果数组元素是浮点数float,double直接使用比较可能因精度问题失败。应该判断两数之差的绝对值是否小于一个极小的阈值如1e-9。#include math.h int compare_double(const void* a, const void* b) { double diff *(double*)a - *(double*)b; if (fabs(diff) 1e-9) return 0; return (diff 0) ? 1 : -1; }5.3 调试与验证技巧打印日志法在二分查找的循环内打印出left,right,mid以及arr[mid]的值。这是理解算法执行过程、定位边界错误最直观的方法。单步调试使用GDB或IDE的调试器一步步执行观察变量变化对于理解递归版本的调用栈尤其有帮助。编写单元测试针对各种情况编写测试用例空数组、单元素数组、目标在开头、目标在末尾、目标不存在、有重复元素等。确保你的函数在所有边界条件下都能正确工作。压力测试生成大规模随机有序数组用你的二分查找和标准库的bsearch如果可用进行对比验证正确性和性能。查找算法是编程世界里的基本功。顺序查找教会我们最朴素的遍历思想而二分查找则展示了利用数据特性有序性来大幅提升效率的威力。从看懂到写对再到能处理各种变体问题需要不断的练习和思考。我个人的体会是每次重写二分查找都要在心里默念一遍循环条件和边界更新这能有效避免阴沟里翻船。当你能够不假思索地写出无bug的二分查找并清晰地说出while(left right)和left mid 1的缘由时你对这部分知识的掌握才算真正过关。

相关新闻

从零实现C++ unique_ptr:深入理解独占所有权与RAII机制

从零实现C++ unique_ptr:深入理解独占所有权与RAII机制

1. 项目概述:从“智能指针”到“独占所有权” 在C的世界里,内存管理一直是开发者必须直面的核心挑战。手动 new 和 delete 的配对操作,稍有不慎就会导致内存泄漏、悬垂指针或双重释放等顽疾。C11标准引入的“智能指针”家族,正…

2026/10/10 18:37:33 阅读更多 →
ViGEmBus虚拟游戏控制器驱动:Windows游戏设备兼容性完整解决方案

ViGEmBus虚拟游戏控制器驱动:Windows游戏设备兼容性完整解决方案

ViGEmBus虚拟游戏控制器驱动:Windows游戏设备兼容性完整解决方案 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 想要在Windows系统上完美使用各…

2026/10/15 9:49:36 阅读更多 →
深信服入选Gartner®《私有云市场指南》代表厂商

深信服入选Gartner®《私有云市场指南》代表厂商

近日,Gartner 发布《私有云市场指南》,深信服凭借云平台托管私有云的完整能力,入选代表厂商。我们从报告中总结得出,受VMware替代、AI规模落地、应用现代化与数据主权合规驱动,私有云市场迎来新一轮增长。Gartner给出若…

2026/10/6 2:14:45 阅读更多 →

最新新闻

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

1. 频谱分析仪基础认知与选型指南在射频测试测量领域,频谱分析仪就像工程师的"电子显微镜",能够将看不见的电磁信号转化为可视化的频谱图形。是德科技(Keysight)的N9020B、安捷伦(Agilent)N9020A…

2026/10/15 9:48:45 阅读更多 →
工具过载时代的caveman思维:用最原始的方法高效解决问题

工具过载时代的caveman思维:用最原始的方法高效解决问题

上周六凌晨两点,我在生产环境里排查一个数据对不上的问题。链路里用了三套中间件、五个微服务,日志平台里的调用链视图看起来一切正常,可最终落库的数字就是和账本差了几百条。我盯着APM面板上花花绿绿的曲线,突然意识到自己这十年…

2026/10/15 9:48:45 阅读更多 →
Python实现网页自动化归档与长截图工具开发

Python实现网页自动化归档与长截图工具开发

1. 项目背景与核心价值最近在整理技术文档时发现一个痛点:很多优质的技术文档站点会突然关闭或改版,导致之前收藏的链接失效。更麻烦的是,有些文档内容需要以完整长图形式保存便于分享或打印。市面上的网页保存工具要么功能单一,要…

2026/10/15 9:48:44 阅读更多 →
npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

1. 项目概述:一个被误读的“完美”工具名,以及它背后真实的CLI生态位最近在多个技术社区和前端开发者群聊里,“impeccable”这个词频繁跳出——不是作为形容词用在代码评审里夸人“写得无可挑剔”,而是作为一个具体可执行的命令出…

2026/10/15 9:48:44 阅读更多 →
hyperframes:高帧率视频处理的帧组架构与工程实践

hyperframes:高帧率视频处理的帧组架构与工程实践

1. 为什么我会盯上 hyperframes 这个方向hyperframes 这个词,我第一次看到是在一个客户的招标参数里,他们要做高速机械臂的视觉引导,要求抓拍速度到120fps,而且不能丢帧。我当时第一反应是:直接堆硬件不就完事了&#…

2026/10/15 9:48:44 阅读更多 →
2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析在婚姻家事纠纷处理中,不同于普通民商事案件的刚性法条适用,离婚诉讼更看重本地法院裁判尺度、家事审判惯例、法官自由裁量标准。2026年东莞家事司法审判日趋精细化,抚…

2026/10/15 9:47:44 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

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

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

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

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

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

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

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

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

2026/10/15 9:49:14 阅读更多 →