Rust 数据结构与算法:1算法分析之乱序字符串检查

Rust 数据结构与算法

一、算法分析

算法是通用的旨在解决某种问题的指令列表。

算法分析是基于算法使用的资源量来进行比较的。之所以说一个算法比另一个算法好,原因就在于前者在使用资源方面更有效率,或者说前者使用了更少的资源。

●算法使用的空间指的是内存消耗。算法所需的内存通常由问题本身的规模和性质决定,但有时部分算法会有一些特殊的空间需求。

●算法使用的时间指的是算法执行所有步骤经过的时间,这种评价方式被称为算法执行时间。

1、大 O 分析法

在时间方面,我们使用函数T表示总的执行次数,T(n) = 1 + n,参数n通常被称为问题的规模,T(n)则是解决规模为n的问题所要花费的时间。

在空间方面,我们使用函数S表示总的内存消耗,S(n) = 2,参数n仍然表示问题的规模,但S(n)已经和n无关了。

但大多数时候,我们主要分析时间复杂度,因为空间往往不好优化。

另外,随着摩尔定律的发展,存储越来越便宜,空间越来越大,这时候时间才是最重要的,因为时间无价。

在这里插入图片描述

一些常见的数量级函数

在这里插入图片描述

复杂度曲线

当n很小时,函数彼此间并不能很好地区分,很难判断哪个是主导函数。但随着n变大,关系就比较明确了,一般情况下(n > 10),O(2n) > O(n3) > O(n2) > O(n log n) > O(n) >O(log n) > O(1)。这对于我们设计算法很有帮助,因为对于每个算法,我们都能计算其复杂度。

假设有这样一个算法,已确定操作步骤的数量是T(n) = 6n2 +37n+996。当n很小时,例如1或2,常数996似乎是函数的主要部分。然而,随着n变大,n2这一项变得越来越重要。事实上,当n很大时,其他两项在最终结果中所起的作用已变得不重要。当n变大时,为了近似T(n),我们可以忽略其他项,只关注6n2。系数6也变得不重要。此时,我们说T(n)具有的复杂度数量级为n2或O(n2)。

T(n) = n + 1。当n变大时,常数1对于最终结果将变得越来越不重要。如果我们要找的是T(n)的近似值,则可以删除1,此时运行时间为O(T(n)) = O(n + 1) = O(n)。注意,1对于T(n)肯定是重要的,但是当n变大时,不管有没有n,O(n)都是准确的。比如,对于T(n) = n3 + 1,当n为1时,T(n) = 2,此时舍掉1就不合理,因为这样相当于丢掉一半的运行时间。但是当n等于10时,T(n) = 1001,此时1已经不重要,即便舍掉,T(n)= 1000也仍然是一个很准确的指标。对于S(n)来说,因为其本身就是常数,所以O(S(n)) = O(2) =O(1)。大O分析法只表示数量级,因此虽然实际上是O(2),但其数量级是常量,可用O(1)代替。

2、乱序字符串检查

一个展示不同数量级复杂度的例子是乱序字符串检查。乱序字符串是指一个字符串s1只是另一个字符串s2的重新排列。例如,“heart”和“earth”是乱序字符串,“rust”和“trus”也是乱序字符串。

为简单起见,假设要讨论的两个字符串具有相同的长度,并且只由26个小写字母组成。我们的目标是写一个函数,它接收两个字符串作为参数并返回它们是不是乱序字符串的判断结果。

1、穷举法

解决乱序字符串问题的最笨方法是穷举法,也就是把每种情况都列举出来。当为字符串s1生成所有可能的乱序字符串时,第1个位置有n种可能,第2个位置有n-1种可能,第3个位置有n-3种可能,以此类推,总共有n×(n−1)×(n−2)×…×3×2×1种可能,即n!

2、检查法

乱序字符串问题的第二种解决方案是检测第一个字符串中的字符是否出现在第二个字符串中。如果检测到每个字符都存在,那么这两个字符串一定是乱序的。

代码:

/** @Description:* @Author: tianyw* @Date: 2024-02-15 10:22:41* @LastEditTime: 2024-02-15 10:35:46* @LastEditors: tianyw*/
// 时间复杂度为 O(n²)
fn anagram_solution2(s1: &str, s2: &str) -> bool {if s1.len() != s2.len() {return false;};// 将 s1 和 s2 的字符分别添加到 vec_a 和 vec_b 中let mut vec_a = Vec::new();let mut vec_b = Vec::new();for c in s1.chars() {vec_a.push(c)}for c in s2.chars() {

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469560.html

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

相关文章

【python之美】减少人工成本之批量拿取文件名保存_4

获取文件名保存 准备工作: 上代码: import ospath "C:\\Users\\Administrator\\Desktop\\text\\" file_names os.listdir(path) print(file_names)i 1 for file_name in file_names:name file_name.split(_)[0]print(name)new_name name "_修改后第&qu…

鸿蒙视频播放器,主要包括视频获取和视频播放功能:

鸿蒙视频播放器,主要包括视频获取和视频播放功能: 1 获取本地视频或者网络视频。 2 通过media.createAVPlayer创建播放器AVPlayer,然后进行视频播放。 3 通过VideoController进行AVPlayerState的状态管理,如开始,停止&…

AI:127-基于卷积神经网络的交通拥堵预测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

Shell 学习笔记(一)-Shell脚本编程简介

一 什么是shell? shell是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内…

FreeRTOS知识点

1>任务调度算法 1.抢占式调度:高优先级的任务优先执行,并且可以打断低优先级的任务执行。 在FreeRTOSConfig.h中开启configUSE_PREEMPTION宏,将宏设置为1,关闭(将宏设置为0) 2.时间片轮转&#xff1a…

OpenGL-ES 学习(2)---- DepthTest

深度测试 OpenGL-ES 深度测试是指在片段着色器执行之后,利用深度缓冲区所保存的深度值决定当前片段是否被丢弃的过程 深度缓冲区通常和颜色缓冲区有着相同的宽度和高度,一般由窗口系统自动创建并将其深度值存储为 16、 24 或 32 位浮点数。(注意只保存…

【MATLAB】PSO_BP神经网络回归预测(多输入多输出)算法原理

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 PSO-BP神经网络回归预测(多输入多输出)算法是一种结合粒子群优化算法(PSO)和反向传播(BP)神经网络的混合算法。该算…

【蓝桥杯单片机入门记录】认识单片机

目录 单片机硬件平台 单片机的发展过程 单片机开发板 单片机基础知识 电平 数字电路中只有两种电平:高和低 二进制(8421码) 十六进制 二进制数的逻辑运算 “与” “或” “异或” 标准C与C51 如何学好单片机 端正学习的态度、培…

Java学习手册——第七篇基础语法

Java学习手册——第七篇基础语法 1. 注释2. 顺序语句3. 条件语句3.1 if语句3.2 switch语句 4. 循环语句4.1 for循环4.2 while 语句4.3 do...while语句 本篇为大家快速入门Java基础语法,了解一个语言的基础语法是必要的, 因为我们后期都是需要用这些基础语…

汽车出租管理系统

文章目录 汽车出租管理系统一、系统演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码(9.9¥带走) 汽车出租管理系统 一、系统演示 汽车租赁系统 二、项目介绍 语言:java 框架:SpringBoot、…

openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存

文章目录 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存217.1 查看内存状况217.2 性能参数分析 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&…

C++类和对象-C++运算符重载->加号运算符重载、左移运算符重载、递增运算符重载、赋值运算符重载、关系运算符重载、函数调用运算符重载

#include<iostream> using namespace std; //加号运算符重载 class Person { public: Person() {}; Person(int a, int b) { this->m_A a; this->m_B b; } //1.成员函数实现 号运算符重载 Person operator(const Per…