目录

对数器的实现

代码实现与解析

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://www.pswp.cn/diannao/98252.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98252.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98252.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB | 绘图复刻(二十三)| Nature同款雷达图

Hello 真的好久不见&#xff0c;这期画一个Nature同款雷达图&#xff0c;原图是下图中的i图&#xff0c;长这样&#xff1a; 本图出自&#xff1a; Pan, X., Li, X., Dong, L. et al. Tumour vasculature at single-cell resolution. Nature 632, 429–436 (2024). https://d…

React Hooks UseCallback

开发环境&#xff1a;React Native Taro TypescriptuseCallback的用途&#xff0c;主要用于性能优化&#xff1a;1 避免不必要的子组件重渲染&#xff1a;当父组件重渲染时&#xff0c;如果传递给子组件的函数每次都是新创建的&#xff0c;即使子组件使用了 React.memo&#…

使用SD为VFX制作贴图

1.制作遮罩 Gradient Linear 1 通过Blend 可以混合出不同遮罩 2.径向渐变 Shape 节点 , 非常常用 色阶调节灰度和渐变过渡 曲线能更细致调节灰度 色阶还可以反向 和圆盘混合 就是 菲涅尔Fresnel 3. 屏幕后处理渐变 第二种方法 4. 极坐标 Gradient Circular Threshold 阈值节…

面经分享二:Kafka、RabbitMQ 、RocketMQ 这三中消息中间件实现原理、区别与适用场景

一、实现原理 (Implementation Principle) 1. Apache Kafka&#xff1a;分布式提交日志 (Distributed Commit Log) Kafka 的核心设计理念是作为一个分布式、高吞吐量的提交日志系统。它不追求消息的复杂路由&#xff0c;而是追求数据的快速、持久化流动。 存储结构&#xff1a;…

Android开发——初步了解AndroidManifest.xml

Android开发——初步了解AndroidManifest.xml ​ AndroidManifest.xml 是 Android 应用的清单文件&#xff0c;包含了应用的包名、组件声明、权限声明、API 版本信息等。它是 Android 应用的“说明书”&#xff0c;系统通过它了解应用的结构和行为。咱们的AndroidManifest文件实…

ecplise配置maven插件

1.下载maven 2.配置系统变量 MAVEN_HOME&#xff1a; E:\CODE\MAVEN\apache-maven-3.0.4 3.配置环境变量 %MAVEN_HOME%\bin 4.cmd&#xff1a;mvn -version 注1 如图所示为&#xff1a;成功 注1&#xff1a;配置成功的前提是要有配置JAVA_HOME,如果没有配置&#xff0c;则…

Vue 项目性能优化实战

性能优化有一套「发现 → 定位 → 解决」的闭环方法论。本文以真实项目为蓝本&#xff0c;从编码阶段到上线监控&#xff0c;给出一条可落地的 Vue 性能优化路线图。 一、量化指标定位性能瓶颈 任何优化之前先用量化证据锁死问题。 Lighthouse 一键跑分&#xff1a;首屏、交互、…

阿里云智能多模态大模型岗三面面经

阿里云智能多模态大模型岗三面面经&#xff08;详细问题感受&#xff09; 最近面试了 阿里云智能集团 - 多模态大模型岗位&#xff0c;三轮技术面&#xff0c;整体体验还不错。问题整体偏常规&#xff0c;但对项目的追问比较细致。这里整理一下完整面经&#xff0c;供准备类似岗…

C++ 条件变量 通知 cv.notify_all() 先释放锁再通知

简短的回答是&#xff1a;先释放锁&#xff0c;再通知&#xff08;notify_one 或 notify_all&#xff09;通常是更优的选择。 虽然标准允许两种顺序&#xff0c;但“先解锁&#xff0c;后通知”的性能通常更好。 下面我们来详细解释原因和两种方式的区别。 先通知&#xff0c;后…

案例精选 | 南京交通职业技术学院安全运营服务建设标杆

导语 随着教育信息化的深入推进&#xff0c;高校已成为数字化转型的前沿阵地。然而&#xff0c;伴随着教学、科研、管理等业务系统的全面上云与互联互通&#xff0c;高校网络环境日益复杂&#xff0c;面临的网络安全威胁也愈发严峻。勒索病毒、数据泄露、APT攻击等安全事件频发…

AI安全必修课:模型偏见检测与缓解实战

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;AI偏见——看不见的技术债务 2018年&#xff0c…

Trae + MCP : 一键生成专业封面

每日一句 人生只有走出来的美丽&#xff0c; 没有等出来的辉煌。 目录 每日一句 前言 一.核心工具与优势解析 二.操作步骤&#xff1a;从配置到生成广告封面 前期准备&#xff1a;确认环境与工具版本 第一步. 获取配置代码 第二步&#xff1a;在 Trae 中导入 MCP 配置…

Eureka与Nacos的区别-服务注册+配置管理

Eureka与Nacos的区别-服务注册配置管理 以下是 Eureka 和 Nacos 的核心区别对比&#xff0c;帮你清晰理解它们的不同定位和特性&#xff1a; ​1. 核心定位​ ​Eureka&#xff1a;​​ ​纯服务注册与发现中心&#xff0c;源自 Netflix&#xff0c;核心功能是维护服务实例清单…

这才是真正懂C/C++的人,写代码时怎么区分函数指针和指针函数?

1.介绍 很多初中级开发者常常在这两个术语之间感到困惑,分不清它们的定义、语法和应用场景,从而在实际编程中埋下隐患。本文旨在拨开迷雾,从概念定义、语法解析、核心区别及实战应用四个维度,对函数指针与指针函数进行一次全面、深入的辨析,帮助您彻底厘清这两个概念,并…

Go基础(④指针)

简单示例package mainimport "fmt"func main() {var num int 100var p *int &num // 指向int类型的指针fmt.Println(*p) // 解引用&#xff0c;输出 100*p 200 // 通过指针修改原变量fmt.Println(num) // 输出 200 }package mainimport "fmt…

java社交小程序源码支持APP多端springboot部署与功能模块详解

构建一个支持 多端访问、实时互动、商城交易 的综合型应用&#xff0c;已成为众多企业和开发团队的共同目标。由 宠友信息技术有限公司 打造的 友猫社区&#xff0c;正是基于 Spring Boot 技术栈 的全端解决方案&#xff0c;既能支持 微信小程序、APP、PC管理后台&#xff0c;又…

代理连接性能优化:提升网络效率的关键技术与实践

在当今数字化时代&#xff0c;代理连接性能优化已成为网络架构设计中的关键环节。本文将深入探讨如何通过技术手段提升代理服务器的响应速度、稳定性和资源利用率&#xff0c;帮助读者构建高效可靠的代理网络体系。 代理连接性能优化&#xff1a;提升网络效率的关键技术与实践 …

Rust 元组

简介 元组可以由多种类型组成&#xff0c;长度固定。 创建元组 // 固定类型 let tup1: (i32, f64, u8) (500, 8.8, 1);// 不固定类型 let tup2 (500.99, 8.8, 1, 9.99);println!("{}", tup2.0);用模式匹配解构元组 let tup (500.99, 8.8, 1, 9.99); let (x, y…

突破闭集限制:3D-MOOD 实现开集单目 3D 检测新 SOTA

【导读】 单目 3D 目标检测是计算机视觉领域的热门研究方向&#xff0c;但如何在真实复杂场景中识别“未见过”的物体&#xff0c;一直是个难题。本文介绍的 3D-MOOD 框架&#xff0c;首次提出端到端的开集单目 3D 检测方案&#xff0c;并在多个数据集上刷新了 SOTA。 目录 …

Python爬虫数据清洗实战:从杂乱无章到整洁可用

小伙伴们&#xff0c;做爬虫最头疼的不是抓数据&#xff0c;而是抓回来那一堆乱七八糟的内容&#xff01;价格里混着符号、日期格式千奇百怪、还有重复和缺失的值&#xff0c;看着就头大。别慌&#xff0c;咱们用Python几招就能搞定。Pandas处理表格数据是真香&#xff0c;正则…