C语言每日一练 —— 第21天:算法的应用

2023-11-04

前言

为什么要学算法 ?
算法能给你带来什么能力提升?
算法在实际生中的应用有哪些?

  带着这些问题,我们开始我们今天的内容。直接来吧!

一、算法简介

在这里插入图片描述

  我曾经在某一个网站上看到一段非常触动我的话。我给大家念一念:

相信大家都听过
“面试造火箭,工作拧螺丝”
没错,
拧螺丝的人
只能一直留在岗位上拧螺丝。
而努力拧螺丝的人
说不定就有机会去造火箭。
而那些有造火箭能力的人
他们终究会造上火箭!

  是的,学习看似枯燥,然而,从中寻找出乐趣,并且偶尔给自己一些正反馈,带着激情,热情奔赴,迟早会有属于你的诗和远方。始终相信,星星之火,可以燎原。
  很多人学算法的初衷很简单,就是面试找工作进大厂,没错,不忘初心,方得始终。当然也有真正热爱算法之人,比如说我,以及正在看视频的你。然而真正踏入社会,进入工作,才是揭开你施展算法才华的序幕。

  生活当中处处是算法,那么就由我来简单介绍一下生活中的一些简单算法应用,然后再来讲讲大厂为什么这么注重算法,以及学好算法能够给你带来哪些方面的提升。
在这里插入图片描述

1、推荐算法

  你能看到我这个 视频,是因为你看了大量的算法、知识、计算机等等相关视频,所以算法将我推荐给了你,他认为你应该会喜欢看我的视频,当然,实际你喜不喜欢,还是要看你的反馈,比如说:是否投币、是否点赞、是否收藏、是否发布评论或者弹幕和我进行互动,根据你的反馈,我的视频可能会被推荐给更多和你一样志同道合之人。如果你觉得我说的有道理,也欢迎在弹幕里告诉我,让我增加一点点信心,以后出更加优质的视频。
在这里插入图片描述

2、最短路算法

  你在乘地铁的时候,如果有很多的换乘站,你就要对各种方案进行抉择选出一条最快的路或者选择一条换乘最少的路,这就是最短路问题。

3、最值算法

  比如说你乘完地铁,去吃自助餐,有牛排、大闸蟹、饮料 等等,你以哪种方式决定先吃什么?是不是你最喜欢吃的先吃?
在这里插入图片描述
那不就对应了在一个数组中找一个最大值吗?只不过把最大变成了最喜欢。
在这里插入图片描述

4、排序算法

  排序算法在现实生活中应该是非常常见的,比如幼儿园的小朋友排成一排,一般都是把最高的排在最后,也就是按照身高单调不降排序,这样才能保证每个同学都能看到老师在讲什么?
在这里插入图片描述

5、压缩算法

  你要上传一些东西到你的百度云网盘,但是内容量太大, 是不是要先压缩一下,压缩就是一种算法,他可以将原本空间占用很大的东西压缩的相对较小。
在这里插入图片描述

6、加密算法

  你有一些奇怪的内容,不想让别人看到,你就把它加密,并且保证只有你能够解密,这里的加密也是一种算法。

在这里插入图片描述

二、为什么要学算法

  为什么现在这么多大厂要求算法能力。
在这里插入图片描述

1、面试时

  其实在我毕业的那一年,也就是2010年的时候,感觉也没有太强调算法的能力。只要学校还行、学习成绩不错、笔试题不要被鄙视、稍微有点项目经历,基本就能轻松进入大厂。
在这里插入图片描述

  原因是因为那个时候,用户体量没有现在这么大,所以数据量也不会太大,自然对算法的要求就没有那么高了。你能把基础功能写出来,会一点简单的设计模式基本也就够用了。
  但是现在不行了,经济飞速发展,越来越多的人开始进入到了互联网行业中来,IT精英比比皆是,长江后浪推前浪。人才如泉涌般袭来,竞争也就越来越激烈。
在这里插入图片描述

  举个例子,如果你实现的功能和人数是呈平方关系的、或者立方关系的、甚至指数关系的,那么随着人数的增多,就会使这个功能消耗大量的CPU,而另一个人能够实现同样的功能,并且它的方法和人数呈线性关系。那么在同样数据量的情况下,他的方法肯定更优,我们也会优先录用他,这里的核心就是算法的时间复杂度。

  同样的,如果你实现的功能需要用到的空间和人数是呈平方甚至立方关系的,那么随着人数的增多,就会消耗大量的内存或者硬盘,而另一个人能够实现同样的功能,并且它的方法和人数呈线性关系,他的方法显然更优,我们就会优先录用他。这里的核心就是算法的空间复杂度。
在这里插入图片描述

  相信你一定听过 “空间换时间” 或者 “时间换空间” 这两个概念,只有学了算法,你才能掌握时间和空间的权衡,时间对应了计算机的CPU,空间对应了计算机的内存和硬盘。有关算法的时间复杂度和空间复杂度,后面我会详细进行介绍。
在这里插入图片描述

  由于算法是一个长期锻炼刷题才能养成的能力,不像八股文,你背下来,面试的时候遇到都能应对自如。算法不是,如果没有深入理解,很可能和面试官不在一个轨道上,所以会算法,至少能说明你是一个刻苦的人,能够为了自己的目标去努力,也肯定不会太笨。试想一下,你工作的时候,要交给你下属一个活,但是怎么说都听不懂,最后累的是你自己,这就是为什么很多大厂招聘的时候会把算法作为一个门槛。

2、工作中

  至于当你到了工作中,如果你没有学过算法,你觉得算法没用,你有工作经验,面试不管算法,哎,就是不学!就是不学!这时候,你发现遇到某个问题的时候,怎么想都没办法做到性能最优,这时候,一个同事缓缓走了过来,告诉你,这不是就是 平衡二叉树 嘛,然后他帮你把代码写了,性能比你快十倍!你觉得,作为你的上级,提拔你还是提拔他呢?
在这里插入图片描述

  很多人进入工作以后,觉得算法用不到,确实是用不到,但是会算法的那批人,工资就是比你高,如果你觉得无所谓,哎,我也无所谓了。
  所以,找到了工作并不意味着算法生涯的结束,恰恰是开始!那么,接下来我们看看算法能给我们带来什么。
  业务都会做,只有掌握了别人没法实现的东西,才是职场的核心竞争力。
在这里插入图片描述

三、算法能给我们带来什么能力的提升

在这里插入图片描述

  如果有人告诉你算法没用,那么只是他为了掩盖自己的平庸而找的借口而已。你可能会听到有写了几年业务的程序员学长说过 “除了面试,我就没用到过算法” 之类的话。
  能说出这样的话,首先肯定没有经过深思熟虑,脱口而出;其次,要么缺乏自信心,觉得自己一辈子都没办法学好算法了,所以就得过且过;要么就是故意误人子弟,不想让你超过他,青出于蓝胜于蓝。所以如果你已经看到这里,我希望你不要传播这样的思想,起码对这个学科保持基本的尊重。相信我,学好算法,一定会给你带来丰厚的回报。

  算法至少可以提升你的以下几个能力:
  1、抽象问题的能力
  2、解决问题的能力
  3、编码能力
  4、调试能力
  5、测试能力

1、抽象问题的能力

  大部分算法的问题不会直接告诉你用到的是什么样的算法,你需要通过你的思维进行抽象才能把它和自己学过的算法联系起来。抽象的过程就是锻炼思维的过程,而实际项目中问题会更加的宽泛,如何抽丝剥茧分解问题,并且和你做过的题联系起来也是一个逐渐实践,循序渐进的过程,切不可操之过急。

2、解决问题的能力

  任何问题都有解决办法,对于算法的题目,一般只有输入和输出,没有任何图形化界面。你不需要关心UI如何展示,只要你的输入按照预期进行输出,这样你就可以专注于解决问题本身,不需要考虑如何将它以什么形式展现出来,可以更加专注。

3、编写代码的能力

  编写代码的能力,我们一般也叫 coding 能力,在练习刷题的过程中,你可以不断提升你程序的时间效率和空间效率,不断优化你代码的质量,也可以看到别人提交的代码。为什么别人的代码跑的比你快,或许自己一个人怎么想都想不出来,但是一旦看到代码或者人家的思路,马上就茅塞顿开,豁然开朗。
  这是一个和世界顶尖程序员一起共事机会,可能在你的学校或者工作中用永远都没有这样的机会。这就是三人行必有吾师的道理,这是一个不断练习、总结、提升的过程。

4、调试能力

  相信很多人在做算法题的时候,都遇到过怎么改都改不出和测试用例一样的输出,特别是遇到指针的问题。二叉树或者链表的指针指来指去,根本不知道现在程序是怎么运作的。我这里有三个方法:
  1)画图
  2)调试
  3)实在不行,就用 print 大法

1)画图

  画图是让你在没有把问题想清楚的情况下,把问题具象化,这是一种艺术能力。熟能生巧,好好培养,有朝一日,必有收获,它能够帮助你更好的理解问题的本质。

2)调试

  调试是程序员的基本素养,能够精确到每一个语句、每一行代码、每一个变量在当前状态下的值,这样你就可以判断出问题出现在哪一行代码,更好的定位问题。

3)print 大法

  如果不会调试,那么就用 print 大法吧。每个变量的值改变以后,都把它打印出来看看,从而确定问题出错在哪一行代码,这是一种最傻瓜式然而也是相对比较常用的方式。初学者推荐用这种方法。

5、测试能力

  相信很多人在做算法题的时候,都遇到过测试用例都过了,但是最后题还是过不了的情况,那是因为测试用例一般会是大量的、并且考虑到大部分的情况,只要有一组数据失败就算不通过。这是一个非常严谨的过程,就好比工作中,测试工程师会用各种测试用例来测试你的代码,如果测试不通过,程序必然会产生BUG,这是需要严格杜绝的。
  所以,通过实现一个个算法,能够让你养成一个更加严谨的测试习惯,多考虑边界条件,多想想哪些地方会出问题,对日后工作有百利而无一害。

四、解决问题的方法

在这里插入图片描述

  面对一个算法问题,有没有一些常用套路,有是有,只不过问题越普适,就会越抽象,就算我说了,可能也不是很容易迅速理解。大方向就是分为以下几步:
  1)读懂题意
  2)查看问题的数据范围
  3)抽象出数据结构
  4)对数据结构执行增删改查

1、读懂题意

  试想一下,如果题目都没有读懂,光看测试数据,怎么可能把算法写出来,所以至少需要把题目先读懂,明白它是在解决什么问题,问题的输入是什么,输出是什么。

2、数据范围

  看数据范围的目的,就是为了让你能够第一时间了解,这是一个暴力算法能够解决的问题,还是需要用到高级数据结构,例如 平衡树、线段树、树状数组 才能解决的问题。
  对于初学者而言,无论数据范围大或者小,都建议先按照暴力思想,也就是普通枚举的方法先把问题思考一下,有了第一步,再去想利用什么数据结构能够优化算法。

3、抽象出数据结构

  一个算法,大概率下都会伴随着数据结构,例如 枚举可以建立在数组、链表、树 或者 图 上,二分枚举是建立在有序数组上的,二叉树遍历是建立在二叉树上的,最短路是建立在图上的 等等。所以,需要思考的是,这个问题需要用哪种数据结构,才能够满足增删改查都能够在题目要求的时间范围内。

4、增删改查

  所有数据结构,无非就是增删改查四种操作,没有其它的了。如何利用给定数据结构的特性,去优化你的算法,就是解题的核心。

五、经典算法易错问题

在这里插入图片描述

  这里列出了一些学习算法的过程中经常会遇到的问题。
在这里插入图片描述

1、内存泄漏

  手动申请的内存,即堆内存,注意在适当的时候进行释放,否则程序在多次运行以后,就可能导致内存泄漏,产生泄漏以后,程序只要不关闭,耗尽操作系统的内存,程序会产生崩溃。所以,内存泄漏一定是要尽量避免的。

2、栈溢出

  一般出现在递归问题中,函数的递归调用,会把一些临时变量存储在栈内存中,栈内存都是实现分配好的,所以递归深度达到一定限度,势必会引起内存溢出,所以我们在递归的时候一定要避免深度过大,或者函数内部的变量占用内存过多。

3、死循环

  递归问题中,如果递归出口没有写好,就有可能出现死递归或者死循环。while 或者 for 语句的循环结束条件如果没有写好,也有可能产生死循环,从而令程序永远执行不下去。

4、数组越界

  申请的数组是有长度大小的,用过访问的下标超过了数组本来有的长度,就会产生数组越界,数组越界是一种未定义的行为,有可能产生问题,也有可能不会产生问题,甚至可能在产生问题后一天以后才暴露出来,所以是一种非常危险的行为,一定要谨慎使用。

5、整型溢出

  整型溢出就是每个整数都是有范围的,如果经过某种运算,超过了给范围,就会和数学上的计算相违背,从而产生非预期的结果,比如等差数列的求和 n ∗ ( n + 1 ) / 2 n*(n+1)/2 n(n+1)/2,如果 n ∗ ( n + 1 ) / 2 n*(n+1)/2 n(n+1)/2 本身是没有溢出的,但是 n ∗ ( n + 1 ) n*(n+1) n(n+1) 溢出了,那么再除2的结果就和最后你期望的结果大相径庭了。
  以及在二分查找的过程中,不要直接用 l e f t left left r i g h t right right 相加除 2,而采用 l e f t + ( r i g h t − l e f t ) / 2 left + (right - left)/2 left+(rightleft)/2 的形式,都是为了避免溢出考虑的。

6、初始化问题

  初始化问题主要是定义一个变量没有给它赋值,后期在进行累加时,就会产生错误,比如你期望它的初始值是0,但是如果没有赋值,可能是一个随机值。这样就会和结果不符。

7、边界问题

  对于一个区间 [ l , r ] [l, r] [l,r],它的长度到底是 r − l r-l rl 还是 r − l + 1 r-l+1 rl+1,这也是一个老生常谈的问题,当然还有二分查找的边界,左区间 是加一还是不加,右区间是减一还是不减。

8、递归出口

  递归出口一般是递归的结束条件,也就是 深度优先搜索树 的最后一层,如果没有考虑周到,递归的作用可能被辜负。

9、变量表义不明晰

  某个变量本来想表示成这个物品是否合法,例如取名为 bCheck,然后后面实现的时候可能会产生疑惑,它到底是表示合法还是不合法?这就是变量名取名不清晰导致的,这个例子中比较好的办法就是改成 bValid。

10、运算符优先级问题

  比较经典的就是 异或 和 等于 的优先级,你觉得哪个高?如果对优先级没有信心,那就老老实实加括号吧,起码加了括号,你能确保优先级一定是对的,不用去管运算符的优先级和结合性。

11、等幂性

  一个函数如果能被多次重入,则说明它是等幂的,如果每次执行结果都不一样,或者说会改变一些函数内部的值,就要考虑它的算法实现了。

  诸如这类的内容量太大了,一句话简单也说不清楚,我打算后面专门开一个视频来讲解,并且把我自己遇到的各种错误进行一个总结。如果想听的小伙伴可以打个1,尽量快速安排上。

六、后记

  如果想听更多算法相关内容,欢迎大家在评论区留言,那么后面的内容我会逐步和大家聊聊:

  如何学好算法?
  如何学好数据结构?
  如何理解时间复杂度和空间复杂度?
  如何系统的刷题?
  如何通过题目信息判断这是一个什么样的算法题?
  如何将学过的算法运用到实际的做题当中?
  如何避免看过解题报告以后会了,下次遇到同样题目还是不会的窘境?
  如何通过报错信息判断到底是什么类型的错误?
  如何对测试用例进行调试?
  如何快速高效的把一个题过掉?
  如何爱上数学,爱上算法,爱上计算机,爱上编程?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言每日一练 —— 第21天:算法的应用 的相关文章

随机推荐

  • ORA-01034: ORACLE not available如何解决

    C Users 10299 gt sqlplus as sysdba SQL Plus Release 11 2 0 1 0 Production on 星期五 3月 24 11 32 56 2023 Copyright c 1982 20
  • 交叉编译grpc

    近期需要使用grpc在目标主机使用 参考了官方示例 大部分网上教程完成了本篇grpc的交叉编译 并对参考的教程做出了引用 文章目录 交叉编译grpc 1 安装交叉编译库 2 Pre requisites 2 1 ubuntu16 04升级g
  • SVN 检出操作

    上一章中 我们创建了版本库runoob01 URL为svn 192 168 0 1 runoob01 svn用户user01有读写权限 我们就可以通过这个URL在客户端对版本库进行检出操作 svn checkout http svn ser
  • 全国职业技能大赛云计算--高职组赛题卷⑤(私有云)

    全国职业技能大赛云计算 高职组赛题卷 私有云 第一场次题目 OpenStack平台部署与运维 任务1 基础运维任务 5分 任务2 OpenStack搭建任务 15分 任务3 OpenStack云平台运维 15分 任务4 OpenStack云
  • flutter 国内镜像https://storage.flutter-io.cn/ 用不了了 502 Bad Gateway trying to find package path at https

    今天 创建一个插件plugin 到pub get的时候爆了一堆超时 502 502 Bad Gateway trying to find package path at https pub flutter io cn 并一直在重试 结果是国
  • springboot3 多环境日志系统配置的问题,无法动态切换dev和prod,以及多环境日志系统的配置,和自动动态切换日志系统,include标签无法获取配置文件的active值

    今天做一个多环境的日志系统 yml文件里面写dev 就使用 dev的日志系统 如果是prod 就指定开发环境的日志系统 结果今天倒好 写是写了 无法解析 老是在后面加一个 is undefined的字符 我不知道这么回事 直到我用if和el
  • 2023.5.15.进度汇报(自用

    一 pyqt小应用 浏览器 1 创建菜单栏及主要分栏 2 创建工具栏 添加主要按钮 3 工具栏中添加地址栏
  • 项目辅助学习 Qt 5

    特点 Qt 5 是一个应用程序开发框架 可提供出色的用户体验并使用 Qt Widgets QML 甚至 Qt 3D 开发全功能应用程序 了解 Qt 框架 以及解决严重问题 例如链接 调试和多线程 所需的工具 内容 Qt 5 入门 项目基本结
  • [论文阅读] (30)李沐老师视频学习——3.研究的艺术·讲好故事和论点

    娜璋带你读论文 系列主要是督促自己阅读优秀论文及听取学术讲座 并分享给大家 希望您喜欢 由于作者的英文水平和学术能力不高 需要不断提升 所以还请大家批评指正 非常欢迎大家给我留言评论 学术路上期待与您前行 加油 前一篇带来李沐老师对论文写作
  • C共享内存读写结构体中的内容

    myshm h ifndef MYSHM H define MYSHM H define N 1 define PAGESIZE 4096 struct mydata int a int b endif shm write c includ
  • 企业微信网页应用开发 - 权限验证

    第一个坑就是权限验证 官方说明见 使用说明 企业微信API 企业微信的js文件非常迷 我找到的就有不同版本 3个 和npm包 2个 选择 但事实是 没有任何官方说明不同版本之间的关系 js文件不对 最常报的错就是XX is not a fu
  • LC-3 汇编语言 Nim游戏

    汇编T T 目录 题目描述 AC代码 思路分析 题目描述 Nim是一个简单的双人游戏 可能起源于中国 游戏中使用的计数器类型有很多种类 如石头 火柴 苹果等 游戏界面被划分为很多行 每行中有数量不等的计数器 行号 计数器数量 1 2 n 本
  • ACE_Message_Block功能和实现浅析

    ACE Message Block实现浅析 1 概述 ACE Message Block是ACE中很重要的一个类 和ACE框架中的重要模式的实现 如ACE Reactor ACE Proactor ACE Stream ACE Task都有
  • 近7成开发者无开源收入、最想操作系统开源、Java最受欢迎

    作者 何苗 责编 屠敏 出品 CSDN ID CSDNnews 2021年是中国开源发展的一座里程碑 这一年 开源被写进十四五规划 被国人熟知 80 90 企业业务都已构建在开源软件 开源项目之上 关于开源的影响力 以数字量化的形式呈现在世
  • 在理构造函数的继承,这次用图说话。

    之前发过一篇关于继承的博客 不过 当时理解的一般 写的也不怎么样 这次重新回头理了一下关于构造函数的继承 因为ES5没有类的概念 所以 才会有构造函数模拟类 首先让我们用一张图来理清楚构造函数 原型 实例三者之间的关系 代码还有关系如下 f
  • LM(Levenberg–Marquardt)算法原理及其python自定义实现

    LM算法原理及其python自定义实现 LM Levenberg Marquardt 算法原理 LM算法python实现 实现步骤 代码 运行结果 LM Levenberg Marquardt 算法原理 LM算法作为非线性优化的 标准 方法
  • 架构修炼-10:高并发设计

    一 如何衡量高并发的系统性能 1 吞吐量Throughput 2 响应延迟Response Delay 二 性能优化目标 1 缩短响应时间 2 提高系统并发数 提升吞吐量 3 系统处理合理状态 机器利用率 随着系统压力增加 X坐标 在线业务
  • unity 3d水的资源包_使用Unity新一代输入系统实现可配置摄像机

    我们已经介绍过Unity新一代的输入系统 本文 我们将使用Unity 2019 2开发可以移动 缩放和旋转的可配置摄像机 这种设计方法适用于不需要额外附带一个第一或第三人称摄像机 而是可以让游戏视角在场景自由移动的游戏 摄像机的配置功能包括
  • Mysql存储过程和函数区别介绍

    存储存储过程 是一段代码 过程 存储在数据库中的SQL组成 一个存储过程通常用于完成一段业务逻辑 例如报名 交班费 订单入库等 而一个函数通常专注与某个功能 视为其他程序服务的 需要在其他语句中调用函数才可以 而存储过程不能被其他调用 是自
  • C语言每日一练 —— 第21天:算法的应用

    文章目录 前言 一 算法简介 1 推荐算法 2 最短路算法 3 最值算法 4 排序算法 5 压缩算法 6 加密算法 二 为什么要学算法 1 面试时 2 工作中 三 算法能给我们带来什么能力的提升 1 抽象问题的能力 2 解决问题的能力 3