数据结构与算法python版本一

没有学习过数据结构算法之类专业毕业的,因为特地学习了下,收货挺多,记录下~
我们编写计算机程序的目的是解决我们实际的应用问题
首先
计算机科学研究的是什么

  • 计算机科学不仅仅是对计算机的研究

  • 计算机科学主要研究的是问题、问题解决过程以及问题的解决方案
    为了更好地处理机器相关性或独立性,引入了抽象的概念
    那么什么是抽象呢,我们举个例子

  • 比如说汽车,从司机观点来看,汽车是一台可以带人去往目的地的代步工具

  • 从抽象角度说,司机看到汽车的逻辑层次

  • 这些操作机构(方向盘、油门、挡位)就称为“接口Interface”
    抽象我们可以通过编程实现
    而编程是通过一种程序设计语言,将抽象的算法实现为计算机可以执行的代码的过程,没有算法,编程无从谈起
    图灵奖获得者Niklaus Wirth的著名公式:算法+数据结构=程序

  • 程序设计语言需要为算法的实现提供实现过程和数据的机制,具体表现为控制结构和数据类型

  • 程序设计语言均有语句对应控制结构,比如说顺序处理、分支选择、循环迭代

  • 程序设计语言也提供最基本的数据类型来表示数据,比如整数、字符等等,对于复杂问题而言,直接使用这些基本数据类型不利于算法的表达

因此我们引发出来一种抽象数据类型ADT(Abstract Data Type),ADT是对数据进行处理的一种逻辑描述,并不涉及如何实现这些处理;并且它建立了一种对数据的封装,封装技术将可能的处理实现细节隐蔽起来,能有效的控制算法的复杂度

  • 同一个ADT可以采用不同的数据结构来实现
  • 采用程序设计语言的控制结构和基本数据类型来实现ADT所提供的逻辑接口
  • 对数据实现“逻辑”层次和“物理”层次的分离,可以定义复杂的数据模型来解决问题,而不需要立即考虑次模型如何实现

刚提到了接口,我们也可以理解为接口的两端就是抽象与实现

  • 由于对抽象数据类型可以有多种实现方案
  • 独立于实现的数据模型
  • 通过层层抽象,降低问题解决过程的复杂度~

我们为什么要学习和研究算法呢

  • 首先,我们就是在学习各种不同问题的解决方案
  • 其次,各种算法通常有较大的差异
  • 在某些情况下,当我们遇到棘手的难题
  • 某些问题解决需要一些折中的处理方式

什么是算法分析

  • 算法是对问题解决的分步描述
  • 程序则是采用某种编程语言实现的算法,同一个算法通过不同的程序员采用不同的编程语言,能产生很多程序
  • 比较程序的好坏,有很多的因素,比如说代码风格、可读性等等,而我们主要感兴趣的是算法本身的特性
    算法分析主要就是从计算资源消耗的角度来评判和比较算法——更高效利用计算资源,或者更少占用计算资源的算法就是好算法。

何为计算资源?

  • 一种是算法解决问题过程中需要的存储空间或内存;但是存储空间受到问题自身数据规模的变化影响,要区分那些存储空间是问题本身描述所需,哪些是算法占用,不容易
  • 另一种是算法的执行时间,我们可以对程序进行实际运行测试,获得真实的运行时间,在python中,我们可以通过time来打印出程序运行的开始结束时间
    但是关于运行时间的检测实际上这样是不全面的,同一个算法,采用不同的编程语言编写,放在不同的机器上运行,得到的运行时间也会不一样,有时候会大不一样,因此我们需要更好的方法来衡量算法运行时间。

大O表示法

一个算法所实施的操作数量或步骤数可作为独立于具体程序/机器的度量指标
赋值语句是一个合适的选择
问题规模影响算法执行时间

  • 问题规模:影响算法执行时间的主要因素
  • 在前n个整数累计求和的算法中,需要累计的整数个数合适作为问题规模的指标
  • 算法分析的目标是找出问题规模会怎么影响一个算法的执行时间
    数量级函数 Order of Magnitude
  • 基本操作数量函数T(n)的精确值并不是特别重要,重要的是T(n)中起决定性因素的主导部分
    - 数量级函数描述了T(n)中随着n增加而增加速度最快的主导部分,称作”大O“表示法,记作O(f(n)),其中f(n)表示T(n)中的主导部分
    例如

T(n) = 1+n
当n增大时,常数1在最终结果中显得越来越无足轻重,所以可以去掉1,保留n作为主要部分,运行时间的数量级就是O(n)

再比如 T(n)=5n^2+27n+1005
当n很小时,常熟1005起决定性作用
但当n越来越大,n^2项就越来越重要了,其他两项对结果的影响越来越小
同样,n^2项中的系数5,对于其增长速度来说也影响不大
所以可以在数量级中去掉27n+1005,以及系数5的部分,确定为O(n^2)

影响算法运行时间的其他因素:

  • 有时决定运行时间的不仅是问题规模
  • 某些具体数据也会影响算法运行时间,分为最好、最差和平均情况,平均状况体现了算法的主流性能,对算法的分析要看主流,而不被某种特定的运行状况所迷惑

常见的大O数量级函数
通常当n很小的时候,难以确定其数量级
当n增长到较大时,容易看出其主要变化量级,比如说对数、常数、线性、平方、立方、指数

其他算法复杂度表示法
大O表示法,表示了所有上限中最小的那个上限

大Ω表示法,表示了所有下限中最大的那个下限

大𝚹表示法,如果上下限相同,那么就可以用大𝚹

变位词的判断问题

所谓”变位词“是指两个词之间存在组成字母的重新排列关系
如:heart和earth,python和typhon
为了简单起见,假设参与判断的两个词仅由小写字母构成,而且长度相等
解题目标:写一个bool函数,以两个词作为参数,返回这两个词是否变位词
解法一:逐字检查
问题规模:包含字符个数是n
且主要部分在于两重循环
所以总的执行次数是1+2+3+4+5…+n,所以数量级是0(n^2)

def anagramSolution1(s1, s2):alist = list(s2)pos1 = 0stilloK = Truewhile pos1 < len(s1) and stilloK:pos2 =0found = Falsewhile pos2 < len(alist) and not found:if s1[pos1] == alist[pos2]:found = Trueelse:pos2=pos2+1if found:alist[pos2] = Noneelse:stilloK = Falsepos1= pos1+1return stilloK
print(anagramSolution1('python','typhon'))

解法二
排序比较:将两个字符串都按照字母顺序排好序,再逐个字符对比是否相同,如果相同则是变位词,有任何的不同就不是变位词

def anagramSolution2(s1, s2):alist1 = list(s1)alist2 = list(s2)#转为列表alist1.sort()alist2.sort()pos = 0#分别排序matches = Truewhile pos < len(s1) and matches:if alist1[pos] == alist2[pos]:pos = pos+1else:matches = Falsereturn matchesprint(anagramSolution2('python','typhon'))

解法三
暴力法:穷尽一个所有可能的组合,将S1出现的字符进行全排列,再查看S2是否出现在全排列列表中,这里最大的困难是产生S1所有字符的全排列,对于越长的字符串,所需的时间和复杂度也越来越大,因此,暴力法恐怕不算是一个好的算法

解法四
计数比较:对比两个词中每个字符出现的次数,如果26个字母出现的次数都相同的话,这两个字符串就一定是变位词;
具体做法:为每个词设定一个26位的计数器,先检查每个词,在计数器中设定好每个字母出现的次数;计数完成后,进入比较阶段,看两个字符串的计数器是否相同,如果相同,则两个字符串是变位词
计数比较中有3个循环迭代,但不像解法1那样存在嵌套循环
前两个循环用于对字符串进行计数,操作次数等于字符长度n
第3个循环用于计数器比较,操作总次数是26次
所以总的操作次数T(n) = 2n+26,其数量级为O(n),这是一个线性数量级的算法,是4个变位词判断中性能最优的

def anagramSolution4(s1, s2):C1= [0]* 26C2= [0]* 26for i in range(len(s1)):pos = ord(s1[i])- ord('a')C1[pos] = C1[pos] +1for i in range(len(s2)):pos = ord(s2[i]) - ord('a')C2[pos] = C2[pos] + 1stilloK = Truej = 0while j < 26 and stilloK:if C1[j] == C2[j]:j = j+1else:stilloK = Falsereturn stilloKprint(anagramSolution4('apple','pleap'))

值得注意的是,本算法依赖于两个长度为26的计数器列表,来保存字符计数,这相比前3个算法需要更多的存储空间,牺牲存储空间换取运行时间,或者相反,这种在时空之间的取舍和权衡,在选择问题解法的过程中经常会出现。

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

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

相关文章

Linux虚拟化的模式

三种虚拟化方式&#xff1a;完全虚拟化&#xff08;Full virtualization&#xff09;、硬件辅助虚拟化&#xff08;Hardware-Assisted Virtualization&#xff09;、半虚拟化&#xff08;Paravirtualization&#xff09;。 服务器上的虚拟化软件&#xff0c;多使用 qemu&#…

蚁剑低版本反制

蚁剑低版本反制 漏洞概述 中国蚁剑是一款开源的跨平台网站管理工具&#xff0c;它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。影响范围 AntSword <2.0.7 蚁剑实验版本&#xff1a;2.0.7 环境搭建&#xff1a; 172.16.1.233&#xff08;蓝队服…

idea打开.class文件没有反编译

1 问题描述 新安装的idea开发工具&#xff0c;打开.class文件查看内容时发现没有将文件进行反编译&#xff0c;所以具体的代码实现看不到。如图所示&#xff1a; 尝试了各种办法解决&#xff0c;最终都没有解决我的问题&#xff0c;其他同事的idea开发工具都可以打开.class文件…

js闭包的必要条件及创建和消失(生命周期)

>创建闭包的必要条件&#xff1a; 1.函数嵌套 2.内部函数引用外部函数的变量 3.将内部函数作为返回值返回 >闭包是什么&#xff1f; 就是可以访问外部函数&#xff08;作用域&#xff09;中变量的内部函数 > 闭包是什么时候产生的&#xff1f; - 当调用外部函数…

HIT_OS_LAB4 系统调用

实验内容 编写iam.c和whoami.c iam.c #define __LIBRARY__ #include <unistd.h>// 定义系统调用 iam&#xff0c;参数为字符串 name _syscall1(int, iam, const char*, name);int main(int argc, char **argv) {int wlen 0;// 检查命令行参数数量if (argc < 2) {pri…

ELK+Filebeat

Filebeat概述 1.Filebeat简介 Filebeat是一款轻量级的日志收集工具&#xff0c;可以在非JAVA环境下运行。 因此&#xff0c;Filebeat常被用在非JAVAf的服务器上用于替代Logstash&#xff0c;收集日志信息。实际上&#xff0c;Filebeat几乎可以起到与Logstash相同的作用&…

VMware 系列:您当前正在评估模式下使用ESXi。此许可证将在60 天后过期

您当前正在评估模式下使用ESXi。此许可证将在60 天后过期 本人的ESXI版本为6.7。点击下方的分配许可证:一些序列号仅供参考:6.7VMware vSphere ESXi 7.0 Enterprise PlusVMware vSphere 7 Enterprise Plus with Add-on for KubernetesVMware vCenter 7.0 StandardVMware vSph…

使用C++编写代码实现字符串的拼接操作

C中有多种方法实现字符串拼接&#xff0c;以下是两种常见的方法&#xff1a; 方法一&#xff1a;使用加号“” #include <iostream> #include <string>using namespace std;int main() {string str1 "Hello";string str2 "World";string s…

Android11编译第八弹:root用户密码设置

问题&#xff1a;user版本增加su 指令以后&#xff0c;允许切换root用户&#xff0c;但是&#xff0c;root用户默认没有设置密码&#xff0c;这样访问不安全。 需要增加root用户密码。 一、Linux账户管理 1.1 文件和权限 Linux一切皆文件。文件和目录都有相应的权限&#x…

【Python】(自定义函数)模块的相对路径导入

是我以前写的老文章的升级版&#xff0c;本质上使用exec和sys.path实现相对路径导入。 RelativeImport&#xff1a; __version__1.1.0 __author__Ls_Janimport os import sys import inspectdef RelativeImport(module,*args):#模块导入module为模块所在路径(模块名不需要.py后…

函数式编程:简洁与效率的完美结合

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

还在担心发抖音没素材跟文案?[腾讯云HAI] AIGC带你蹭热度“今年你失去了什么?”

目录 &#x1f433;前言&#xff1a; &#x1f680;了解高性能应用服务 HAI &#x1f47b;即插即用 轻松上手 &#x1f47b;横向对比 青出于蓝 &#x1f424;应用场景-AI作画 &#x1f424;应用场景-AI对话 &#x1f424;应用场景-算法研发 &#x1f680;使用HAI进行…

蓝桥杯day01——根据给定数字划分数组

题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 pivot 。请你将 nums 重新排列&#xff0c;使得以下条件均成立&#xff1a; 所有小于 pivot 的元素都出现在所有大于 pivot 的元素 之前 。所有等于 pivot 的元素都出现在小于和大于 pivot 的元素 中间 。小于 piv…

orcad模块化绘制电路

当我们的板子上需要绘制大量的重复电路的时候&#xff0c;手动去绘制就很浪费时间。 orcad 的软件可以进行模块化绘制&#xff0c;将几个原理图包装成一个模块&#xff0c;然后直接去复制模块就可以。 相对来说大大的简化了原理图的设计麻烦程度 下面就是整个的操作流程 最后做…

Router跳转打开新窗口

this.$router.push()无效时&#xff0c;首先要检查路由列表是否正确。 console.log(this.$router.options.routes);跳转 /*本窗口*/// this.$router.push({ path: /filePreview, query: { path: row.path } })/*新打开窗口*/let routeData this.$router.resolve({ path: /fi…

一天之内“三个离职群都满了”;飞行出租车的时代就此开启?丨 RTE 开发者日报 Vol.94

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

每日一练 | 华为认证真题练习Day138

1、IPv6地址FE80::2EO:FCFF:FE6F:4F36属于哪一类&#xff1f; A. 组播地址 B. 任播地址 C. 链路本地地址 D. 全球单播地址 2、如果IPv6的主机希望发出的报文最多经过10台路由器转发&#xff0c;则应该修改IPv6报文头中的哪个参数&#xff1f; A. Next Header B. Version …

【考研or就业】关键的时间节点,暑期实习/秋招/春招大揭秘(文末附时间线图)

【考研or就业】关键的时间节点&#xff0c;暑期实习/秋招/春招大揭秘 一些引言考研初复试暑期实习秋招春招 【考研or就业】关键的时间节点&#xff0c;暑期实习/秋招/春招大揭秘&#xff08;视频版&#xff09; 一些引言 ● 之前我个人的选择是比较离谱的那种&#xff0c;考研…

【实验】配置用户通过IPv6方式上网

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等https://xmws-it.blog.csdn.net/article/details/117297837?spm1001.2014.3001.5502【微/信/公/众/号&#xff1a;厦门微思网络】 组网需求 运营商为企业分配了WAN侧的IPv6地址11…

SageMath安装

Sagemath工具是免费开源的&#xff0c;针对数学计算的一个工具。 网页版免安装&#xff1a;https://sagecell.sagemath.org/ Sagemath是根据Linux系统编写的&#xff0c;所以Windows上使用的话&#xff0c;会创建一个Linux系统运行。 1. 安装 Windows本地安装参考&#xff1…