当前位置: 首页 > news >正文

【左程云算法03】对数器算法和数据结构大致分类

目录

对数器的实现

代码实现与解析

1. 随机样本生成器 (randomArray)

2. 核心驱动逻辑 (main 方法)

3. 辅助函数 (copyArray 和 sameArray)

对数器的威力

算法和数据结构简介​编辑

1. 硬计算类算法 (Hard Computing)

2. 软计算类算法 (Soft Computing)

核心观点

一个宏观的数据结构分类

1. 连续结构 (Continuous Structure)

2. 跳转结构 (Jumping Structure)


视频链接

算法讲解005【入门】对数器-验证的重要手段

算法讲解008【入门】算法和数据结构简介

对数器的实现

对数器的本质,就是通过大规模的随机样本测试,来对比我们实现的“精巧算法”和一个“绝对正确”的暴力方法,从而验证我们算法的正确性。

构建一个对数器的完整流程分为以下六步:

  1. 你要有一个想测的方法 a(最优解)
    这是我们自己实现的、希望验证其正确性的算法。

  2. 实现一个复杂度不好但是容易实现的方法 b(暴力解)
    这个方法是我们的“真理标杆”。我们不要求它性能好,但必须保证它的逻辑是绝对正确的。通常,我们会用最直观、最暴力的方式来实现它。

  3. 实现一个随机样本产生器
    我们需要一个函数,能够生成各种随机情况的测试数据(例如,长度随机、值也随机的数组)。

  4. 把方法 a 和方法 b 跑相同的输入样本,看看得到的结果是否一样
    这是对数器的核心对比环节。对于同一个随机样本,分别用方法 a 和方法 b 去处理。

  5. 如果有某个随机样本使得比对结果不一致,打印出这个出错的样本进行人工干预,改对方法 a 和方法 b
    一旦发现不一致,就意味着我们的方法 a 存在 bug。对数器会自动捕获这个导致错误的“反例”,我们就可以用这个具体的样本去轻松地进行 debug。

  6. 当样本数量很多时比对依然正确,可以确定方法 a(最优解)已经正确。
    经过成千上万,甚至几十万次随机样本的“轰炸”都未曾出错,我们就可以非常有信心地认为,我们的算法 a 是正确的。

代码实现与解析

下面,我们结合截图中的 Java 代码,来一步步拆解对数器的具体实现。这里的例子是用来同时验证我们写的多个排序算法是否正确。

1. 随机样本生成器 (randomArray)

负责源源不断地提供测试数据。

// 得到一个随机数组,长度是n
// 数组中每个数,都在1~v之间,随机得到
public static int[] randomArray(int n, int v) {int[] arr = new int[n];for (int i = 0; i < n; i++) {// Math.random() -> double -> [0,1)的一个小数// Math.random() * v -> double -> [0,v)的一个小数// (int)(Math.random() * v) -> int -> 0 1 2 3 ... v-1,等概率的!// (int)(Math.random() * v) + 1 -> int -> 1 2 3 .... v,等概率的!arr[i] = (int) (Math.random() * v) + 1;}return arr;
}

这个函数接收最大长度 n 和最大值 v,生成一个长度和值都在指定范围内的随机数组。注释清晰地解释了 Math.random() 如何通过一系列变换,生成我们需要的 [1, v] 范围内的随机整数。

2. 核心驱动逻辑 (main 方法)

这里是对数器的“发动机”,它组织了整个测试流程。

// 为了验证
public static void main(String[] args) {// 随机数组最大长度int N = 100;// 随机数组每个值,在1~V之间随机int V = 1000;// 测试次数int testTimes = 50000;System.out.println("测试开始");for (int i = 0; i < testTimes; i++) {// 随机得到一个长度,长度在[0~N-1]int n = (int) (Math.random() * N);// 得到随机数组int[] arr = randomArray(n, V);// 拷贝数组,确保每个排序算法处理的是相同的原始数据int[] arr1 = copyArray(arr);int[] arr2 = copyArray(arr);int[] arr3 = copyArray(arr);// 分别用不同方法排序selectionSort(arr1);bubbleSort(arr2);insertionSort(arr3);// 对比排序结果if (!sameArray(arr1, arr2) || !sameArray(arr1, arr3)) {System.out.println("出错了!");// 当出错时,可以把原始样本arr打印出来,// 方便把这个例子带入到每个方法去debug!}}System.out.println("测试结束");
}

关键点解析

在后续的很多题目中,对数器都会是我们验证复杂算法(如动态规划、贪心等)的得力助手。

算法和数据结构简介

  • 循环测试:通过 testTimes 控制测试次数,量级越大,覆盖的样本情况就越全面,结果越可靠。

  • 拷贝数组:copyArray(arr) 这一步至关重要!因为排序是原地操作,会修改原数组。如果不拷贝,那么第一个排序(selectionSort)完成后,arr2 和 arr3 拿到的将是一个有序数组,测试就失去了意义。必须保证每个待测算法都工作在完全相同的、未经修改的原始样本上。

  • 结果比对:if (!sameArray(arr1, arr2) || !sameArray(arr1, arr3)) 负责检查。这里我们让多个排序算法互相验证

    3. 辅助函数 (copyArray 和 sameArray)

    这两个是保证对数器能正确运行的工具函数。

    copyArray:

    。如果其中任何两个的结果不一致,就说明至少有一个算法出了问题。

    // 为了验证
    public static int[] copyArray(int[] arr) {int n = arr.length;int[] ans = new int[n];for (int i = 0; i < n; i++) {ans[i] = arr[i];}return ans;
    }```
    功能很简单:创建一个和原数组一模一样的新数组,避免引用传递导致的问题。**`sameArray`:**
    ```java
    // 为了验证
    public static boolean sameArray(int[] arr1, int[] arr2) {// 这里可以先补充长度是否相等的判断int n = arr1.length;for (int i = 0; i < n; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;
    }

    对数器的威力

    对数器的门槛其实是比较高的,因为它往往需要你用两种不同的思路去实现相同功能的方法。但它的价值是巨大的:

  • 信心:它是你验证自己算法正确性的最强后盾。

  • 能力:它锻炼你从不同角度思考同一个问题的能力(暴力解 vs. 最优解)。

  • 效率:它能自动找到你手动很难想到的边界“反例”,让你的 debug 过程从大海捞针变成按图索骥。

一个有趣、有用的算法分类

首先,左老师提出了一种非官方但极具现实意义的算法分类方法,将算法分为两大类。

注意:这两个名词都不是计算机科学或算法中的标准术语。

1. 硬计算类算法 (Hard Computing)

定义:追求精确解、最优解的算法。

特点:为了找到那个唯一的、精确的答案,可能会导致算法的复杂度较高。

应用场景:这是目前绝大多数程序员面试、笔试、ACM/ICPC 类竞赛考察的核心。无论是大厂还是初创公司,面试中考察的算法基本都属于硬计算的范畴。

重要性硬计算类算法是所有程序员岗位都必须会考、任何写代码的工作都会用到的基础能力。无论是前端、后端、架构,算法的所有岗位都需要用到。

2. 软计算类算法 (Soft Computing)

核心观点

任何数据结构都一定是这两个结构拼出来的!没有例外!

这是一个非常重要的论断。我们将来要学习的各种纷繁复杂的数据结构,例如:

等等,无论它们看起来多么复杂,其最底层的实现原理,都离不开“连续的内存”和“跳转的指针”这两种基本构造单元的组合与运用。

在后续的课程中,我们将会深入学习这些具体的数据结构,届时可以回头再来体会这个宏观分类的精妙之处。

一个宏观的数据结构分类

接着,左老师提出了一个同样宏观的、用于理解所有数据结构的底层逻辑分类。他认为,无论多么复杂的数据结构,其底层都是由两种最基本的结构“拼”出来的。

1. 连续结构 (Continuous Structure)

可以理解为像数组这样的结构。数据在内存中是连续存放的,一个挨着一个,可以通过索引直接计算出内存地址,实现快速的随机访问。

2. 跳转结构 (Jumping Structure)

可以理解为像链表这样的结构。数据在内存中是离散存放的,每个节点通过一个指针或引用,“跳转”到下一个节点的位置。

  • 定义:更注重逼近一个可接受的解决方案,而不是强求精确的最优解。

  • 特点:计算时间可控,允许在一定程度上牺牲精度来换取效率。

  • 典型例子:模糊逻辑、神经网络、进化计算、概率论、混沌理论、支持向量机、群体智能等。这些通常是机器学习、人工智能领域的核心算法。

  • 重要性:对于普通的开发岗位,软计算不是必须掌握的。但对于算法工程师,除了必须精通硬计算类算法之外,还需要掌握软计算类算法。

  • 链表

  • 队列、栈

  • 树(二叉树、平衡树、B树等)

  • 可持久化线段树

  • 树链剖分

  • 后缀数组


文章转载自:

http://nlCs4iXR.xgchm.cn
http://xq6BfrSJ.xgchm.cn
http://bj38CW9p.xgchm.cn
http://QNQYjH55.xgchm.cn
http://UldhMwYa.xgchm.cn
http://oIY5v3hT.xgchm.cn
http://qfXnLtFd.xgchm.cn
http://9VU9UMka.xgchm.cn
http://seAVNQK5.xgchm.cn
http://36JUqiEe.xgchm.cn
http://FBluOtfs.xgchm.cn
http://EeUKFa9J.xgchm.cn
http://ifzKmVKK.xgchm.cn
http://sv6UgLfp.xgchm.cn
http://Sv1kzDMt.xgchm.cn
http://HJh5MvoX.xgchm.cn
http://ZI80wyao.xgchm.cn
http://4hkKrGzh.xgchm.cn
http://SgOItrAT.xgchm.cn
http://uzQd1rfS.xgchm.cn
http://eHD5nRjN.xgchm.cn
http://jb5FvOAl.xgchm.cn
http://IyfoN8ed.xgchm.cn
http://p2swzowP.xgchm.cn
http://Kdp5UHmk.xgchm.cn
http://WWmFATId.xgchm.cn
http://yGavAmHi.xgchm.cn
http://GjVFoJz1.xgchm.cn
http://Z03M9kUt.xgchm.cn
http://T0pfa6Tp.xgchm.cn
http://www.dtcms.com/a/370492.html

相关文章:

  • 2.2 Web和Http
  • CuTe C++ 简介02,gemm_device cuda kernel 的实现
  • uniapp开发APP隐私检测不通过解决
  • Monorepo 是什么?如何使用并写自己的第三方库
  • 【56页PPT】华为集成服务交付ISD业务变革总体方案(附下载方式)
  • 九月六号练习题
  • 深度学习——PyTorch保存模型与调用模型
  • Go基础(⑤Consul)
  • 验证平台中所有的组件应该派生自UVM中的类
  • 企业微信智能表格高效使用指南
  • 自动化运维之ansible
  • 2025年上海市星光计划第十一届职业院校技能大赛高职组“信息安全管理与评估”赛项交换部分前6题详解(仅供参考)
  • Orin-Apollo园区版本:订阅多个摄像头画面拼接与硬编码RTMP推流
  • 多线程(六) ~ 定时器与锁
  • OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​
  • Qt图表功能学习
  • 【营销策略算法】关联规则学习-购物篮分析
  • 部署AIRI
  • 深度学习基础概念回顾(Pytorch架构)
  • 基于LSTM深度学习的网络流量测量算法matlab仿真
  • 【PyTorch实战:Tensor变形】5、 PyTorch Tensor指南:从基础操作到Autograd与GPU加速实战
  • 【基础-判断】@Entry装饰的自定义组件将作为页面的入口。在单个页面中可以使用多个@Entry装饰不同自定义组件。
  • 驱动开发系列71 - GLSL编译器实现 - 指令选择
  • 贪心算法应用:化工反应器调度问题详解
  • OpenAvatarChat项目在Windows本地运行指南
  • canal+DataX实现数据全量/实时同步
  • Jenkins运维之路(自动获得分支tag自动构建)
  • 服务器内存和普通计算机内存在技术方面有什么区别?
  • 同一台nginx中配置多个前端项目的三种方式
  • 【LeetCode热题100道笔记】排序链表