![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
编程算法同步学
零基础轻松入门,拿到进入程序世界的金钥匙!
优惠券已抵扣
余额抵扣
还需支付
¥69.90
¥99.00
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
叶锦鲤
微信公众号:yuesiyuedu,微信个人号:julia_li_2013
展开
-
开篇词 | 为什么我们要学习编程?
为什么需要学习编程?如今,学习编程的人分为两类,一类是程序员,另一类是期望成为程序员的人。编程这个事儿,在大多数人眼中还是一种特定领域的、专门的技能,认为学的人都是需要以此谋生的。其实,作为一个“码龄”超过20年的老程序员,我是这样认为的:在不久的将来(也许三五年,也许十来年之后),编程将从一个职业技能逐步蜕变为职场通用技能。对此,我们可以类比“识字”这个技能来看—— 百十年前,大多...原创 2020-09-22 12:03:36 · 363 阅读 · 0 评论 -
1-1课:又回到最初的起点:软件和程序
软件和程序每每提到“编程”这个词,大家都会觉得这是件高端、神秘的事,或者会皱皱眉头,觉得这肯定是个挺难的事儿吧?基本所有与编程没有打过交道的人,都认为编程似乎被一群秃头的程序员垄断了,是一种旁人无法介入的专属行为。而就在这一两年里,“少儿编程”的概念又伴随着素质教育、stem 教育迅速崛起。好像一时之间,连小学生、幼儿园小朋友都开始学编程了。而且还有不少幼儿型选手拿了不少编程大奖!所以,编...原创 2020-09-22 12:03:34 · 605 阅读 · 0 评论 -
1-2课:安静的程序,淘气的程序和编写程序
静态程序——程序的源代码上一章我们讲到了程序的源代码,你是不是很好奇它和程序到底是不是一回事儿啊?严格来讲,“程序”和“程序的源代码”并不是一回事情噢。程序的源代码是指用编程语言编写出来的程序的逻辑,是静态的文本,我们暂且可以叫 TA 安静的程序,一般被存储为以特定字符串为后缀的文件。比如下面就是一个 Python 程序(程序员世界中最著名的打印“Hello World”的程序),被保存为...原创 2020-09-22 12:03:33 · 507 阅读 · 0 评论 -
1-3课:算法究竟是个啥东西?
算法,究竟是什么呢?(令人抓耳挠腮,想不明白)广义算法广义而言,做一件事情/解决一个问题的方法,就是算法。比如: Case1:烙饼得把面粉加水和成团,擀成片,加油盐后卷成卷切成大面剂子,面剂子封口后擀成圆形,上锅烙,反几次直到两面焦黄,出锅乃成——这是烙饼的“算法“。是不是瞬间Get! Case2:做条裙子要先量尺寸,再裁布,然后缝纫镶边装拉锁——这是裙子制作的“算法“。 ……...原创 2020-09-22 12:03:31 · 555 阅读 · 0 评论 -
1-4课:程序、编程和算法之间到底有什么三角关系?
算法与程序在之前我们给大家科普过了,算法 = 控制流程 + 数据结构。数据结构是数据的组织形式。在描述算法的时候,我们并不知道实际要用这个算法来处理的数据是什么(其实也本没有必要知道),我们只需要知道将来要处理的数据是如何组织的就可以了。基于数据的组织形式,定义一个运算/操作的历程,这就是算法的实现。算法实现的结果,就是程序。当我们有了具体的数据要处理的时候,就要:1)运行已经编写好的,...原创 2020-09-22 12:03:29 · 2728 阅读 · 0 评论 -
1-5课:妈妈告诉我学编程到底有啥用啊?
学习算法和编程的用处学习算法和编程,到底有什么用?就目前而言,大致有如下几种用处:【1】是入行程序员的基本技能这一点不用说了,程序员的日常工作就是编程,程序员面试考的就是算法。要想成为程序员,编程+算法是最最基础要学习的东西。【2】了解计算机技术和程序员思维的捷径在互联网公司,有些岗位,虽然自己不需要编程,却总是难免要和程序员打交道,最典型的例如:产品经理。这样的角色,如果对计算机技术...原创 2020-09-22 12:03:28 · 1103 阅读 · 0 评论 -
2-1课:万事的抽象:控制流程
在我们计算机领域,控制流程的定义就是程序中陈述、指令或函数调用的执行历程。听起来是不是有点抽象?其实,我们可以从一个更广域的角度去理解,控制流程——控制流程就是步骤和过程,在我们的日常生活中处处都有控制流程,看了你就能秒懂了!顺序逐步完成一件事我们要烤一个蛋糕。于是上网搜索到下面这个配方—— 原料:鸡蛋,糖,面粉,黄油,牛奶 步骤: 1.称量出4个鸡蛋,60g糖,90g面粉...原创 2020-09-22 12:03:27 · 299 阅读 · 0 评论 -
2-2课:用最最简单的结构表达复杂的过程:控制结构的排列和嵌套
什么是流程图?流程图(Flow Chart)是一种表示算法或工作流的框图。它用不同类型的框代表不同种类的步骤,每两个步骤之间则以箭头连接。我们正在讲的控制流程,就可以用流程图来表示噢。流程图有一套相对复杂的符号系统,比如下图这样: 不同机构或组织对于流程图符号系统的定义也有所不同,有些流程图元素相当复杂,比如下例:极简版流程图符号表鉴于本门课所需要描述的算法过程十分简单基础,流程图只...原创 2020-09-22 12:03:25 · 334 阅读 · 0 评论 -
2-3课:万物的抽象:数据结构
数字化现实世界由万事万物构成,而计算机能够处理,只有数据。说得更直接一点,计算机能够处理的其实都是数字。因此,当我们用计算机来协助处理日常事物的时候,首先要做的一件事就是数字化。虽然在实践中,通常存储在计算机存储设备上的数字化数据是二进制形式的。但严格来说,任何把模拟源转换为任意类型数字格式的过程,都可以叫做数字化。数字化指将信息转换成数字格式的过程。具体而言,就是把一个物体,图像,声音,文...原创 2020-09-22 12:03:24 · 325 阅读 · 0 评论 -
2-4课:从最最最最简单的数据结构开始:数组和链表
在实际运用中,不同编程语言对于同一理论性数据结构的实现可能有所不同。在我们后面具体编程的过程中,用到的实践性数据结构和理论性数据结构也有可能不同。本章里讲的数组和链表,是理论上的数据结构,我们关注的是逻辑层面的数据组织方式和其上操作的运行方式。数据结构的定义我们先来看看数组和链表的定义。数组在计算机科学中,数组是一种由若干元素组成的集合,每一个元素被至少一个索引(index)或者关键字(...原创 2020-09-22 12:03:22 · 231 阅读 · 0 评论 -
2-5课:计算机是咋运行的:冯诺依曼结构
数组、链表这些结构限制条件的根本原因来自于 计算机硬件的体系结构。在现今的计算机教育体系中,编程语言、数据结构(含算法)、计算机原理及体系结构几门课是计算机专业的本科生都要学习的。实际上这几门课之间,也包括其他一些课程(例如编译原理、自动机、数电、模电、操作系统等等 ),有不少overlap的知识点和相互引用的地方,要从一个方向讲清楚某个知识点,就不得不涉及其他几个领域的知识。但是因为内容实在...原创 2020-09-22 12:03:20 · 460 阅读 · 0 评论 -
2-6课:预留给货物的固定货架:内存中的数组
存储空间上一章我们讲了冯诺依曼结构,其中很关键的一点是:存储空间分成若干存储单元,每个单元都有序号,单元内放置存储内容。无论指令还是数据,物理上都存储在存储器里面,逻辑上都在存储空间之中。存储单元和存储在里面的信息,可以类比成编号的货架和放置在其上的货物(见下图):前些章反复说过,所谓数据结构就是数据的组织方式。现在我们已经把数据类比成了货物,那么对于数据的组织方式,自然就是存放这些货...原创 2020-09-22 12:03:19 · 233 阅读 · 0 评论 -
2-7课:见缝插针地摆放货物:内存中的链表
链表虽然链表和数组是两种不同的数据结构,但它们都是被存储在连续的存储空间上的。如果将两种数据结构中的数据比作“货物”,那么放置它们的“仓库”都是一样的,里面都有一排排标好了固定编号的货架(见下图)。不过和数组那样一下预定一系列连续的货架,就算不放货物也要占着不给别人用的数据组织方式不同,链表是按需分配的——有货物要存储了,才临时申请正好放这些货物的货架,随时加减。单向链表最简单的一种链...原创 2020-09-22 12:03:17 · 360 阅读 · 0 评论 -
2-8课:复杂些的数据结构:树和图
抽象数据模型我们介绍了两个序列数据结构,数组和链表。关于数组和链表除了理论上的操作和约束,我们还讲了它们是如何对应到计算机内存的存储空间上去的。之所以要讲到这个程度,是因为我们后面所有的代码都要用到这两个数据结构,而对代码中某些细节的理解要借助于对相应数据结构实现的认知,因此不得不讲到如此层面。这一章我们要介绍两种相对复杂的数据结构:树和图。鉴于本门课内并不会在代码层面涉及到这两种结构,...原创 2020-09-22 12:03:15 · 458 阅读 · 0 评论 -
2-9课:树和图的现实意义、区别与联系
二叉树树的遍历树的遍历和图的遍历在计算机科学里,树的遍历指按照某种规则,不重复地访问树的所有节点的过程。具体的访问操作可能是检查节点的值、更新节点的值等。不同的遍历方式,其访问节点的顺序是不一样的。因为树是图的一个子集,因此,树的遍历,也属于图遍历的子集。图遍历的原则主要有深度优先和广度优先两种。这两大遍历原则对于树也同样适用。又因为有根树是树的一种,二叉树是有根树的一种,二叉树的遍历也分...原创 2020-09-22 12:03:14 · 1726 阅读 · 0 评论 -
3-1课:从最简单的算法开始学:顺序查找
前面从软件、程序讲到算法,概括讲述了算法的两大要素:控制流程和数据结构。其中还穿插了冯诺依曼结构以及数组和链表在存储层的实现。终于,我们迎来了第一个算法——顺序查找!查找算法(Search Algorithm)查找算法,又名搜索算法,它的定义就是字面意思:解决查找问题的算法。这个定义还可以换两种说法:i)检索存储在某种数据结构中的信息的算法;或者 ii)在问题域的搜索空间进行计算的算法。...原创 2020-09-22 12:03:12 · 236 阅读 · 0 评论 -
3-2课:为啥有的算法好?有的算法坏?
上一节课讲了顺序查找的原理、数据结构和控制流程,按说接下来就该讲编程实现了。不过在第一次讲算法落实到程序之前,我们先要讲明一个问题:如何衡量一个算法的性能。性能指标每个算法都有一个目标任务,能够完成这个任务,是算法功能的体现。但同样是完成这个任务,有的算法快有的算法慢,有的几乎不需要额外的存储空间,有的则非要占一大块……这就是算法的性能不同了。我们看机械设备的性能会考虑耗油/耗电量,使用寿命...原创 2020-09-22 12:03:11 · 314 阅读 · 0 评论 -
3-3课:跟你的计算机聊会儿天:编程语言
知道了怎么衡量算法的性能,我们该写程序实现算法了吧?别急,在开始写程序之前,我们需要先从整体上了解一下编程语言。语言、自然语言和编程语言的定义及性质编程语言首先是一种语言。语言语言是什么呢?语言是信息的载体。人们借用语言这一载体来记忆、加工信息。因此,语言也是思维的工具。所有语言都具备下列这些性质:媒介性:通过声音或文字符号传播;规范性:有一组约定的基本元素(语素),元素组合规则...原创 2020-09-22 12:03:10 · 236 阅读 · 0 评论 -
3-4课:各种花式编程语言大放送
编程范型(programming paradigms)我们来学习一个新概念:编程范型。定义和分类范型(Paradigm)这个词来源于希腊语 “paradeigma”,有“模式,例子,样例”的意思。听着有点悬。其实,编程范型就是程序组织和实现计算的模式,也可以简单理解成一种编程的风格。编程范型可以大致分为两大类:命令式(imperative):程序一句句地告诉机器该去干什么。这类范...原创 2020-09-22 12:03:08 · 352 阅读 · 0 评论 -
3-5课:一条可爱的小蟒蛇:Python语言
多姿多彩的编程语言有人类比着化学元素周期表制作了一张“编程语言周期表” 表中每一行表示一个年代。第一行是前1950年代,第二行是1950年代,之后分别是1960,1970……2000年代。不同的颜色则表示不同的编程范型。全表第一个语言(左上角)是1837年由Charles Baggage和Ada Lovelace创造的分析机代码——说是代码,其实就是后者用前者发明的机械式分析机计算伯努利数...原创 2020-09-22 12:03:07 · 414 阅读 · 0 评论 -
3-6课:让 Python小蟒蛇动起来
你好世界打印 “hello world”上一章我们写了第一个Python程序:是的,整个程序只有一行:print(“hello world“)这里的print()是一个内置函数——函数概念会在后面解释,这里暂且理解成一个命令。print()函数的功能就是打印出(在默认输出设备上输出)它后面括号中的内容。本程序中,print后面括号里是一个字符串“hello world“。整个程序的...原创 2020-09-22 12:03:05 · 567 阅读 · 0 评论 -
3-7课:彰显地位的缩进和作为限制的类型
Python的缩进(indent)结构特征现在我们来了解一下Python的结构特性:划分代码块——Python使用空格缩进(indent)划分代码块,而不是像其他高级语言那样,用大括号或者关键词来划分。这一点非常重要,一方面它使得Python看起来更像自然语言,增加了Python的可读性。但另一方面,这样做等于放弃了显性地划分代码块,而是采用了一种半隐性的形式,使得初学者有时容易混淆代码块...原创 2020-09-22 12:03:04 · 226 阅读 · 0 评论 -
3-8课:数字为什么长这样儿:说说进位制
在讲什么是溢出之前,我们需要先了解一个基础知识:进位制。进位制(简称进制)进位制(简称进制,又叫做进位计数法,或数制)是一种记数方法:一种进位制首先会设定一组有限的数字符号。 目前通用的数字符号系统无疑是阿拉伯数字:{0,1,2,3,4,5,6,7,8,9}一种进位制中可以使用的数字符号的个数叫做这种进位制的基数。 十六进制的基数是十六;十进制的基数是十;八进制的基数是八;...原创 2020-09-22 12:03:02 · 408 阅读 · 0 评论 -
3-9课:货物不能乱堆放:数据的占位和溢出
溢出讲过了进制,我们回头来讲溢出。限定位数的数值表达在位数不受限制的情况下,利用进位制,我们可以使用有限种数字符号来表示所有的数值。但如果限制数位会如何?还是用我们熟悉的十进制举例子: 假设我们规定,某一个整数是十进制数,但是它最多总共只能占两位——只能有两个数位,也就是最低的两位:个位和十位。 那么它最小能表达的是 0, 最大能表达的是99。 当我们给99加上1的时候,它...原创 2020-09-22 12:03:00 · 247 阅读 · 0 评论 -
3-11课:Python中的类型系统和“数组”
编程语言的类型系统变量的数据类型和声明程序中的每一个变量都有它的数据类型。在大多数编程语言里,一个变量是什么数据类型,是需要被声明的。在Java里,我们要用一个变量来存储整型值,那么我们需要在第一次写出这个变量的时候,写上它的数据类型。比如下面这个Java语句:int age = 20;上面这行代码其实同时做了两件事情:1. 声明我们创建了一个变量:age,它的类型是整型(int...原创 2020-09-22 12:02:59 · 218 阅读 · 0 评论 -
3-10课:迈出看似简单的一步:字面量、常量、变量和赋值
本节课,我们要介绍几个高级编程语言中和操作数据相关的基础概念。编程语言表述的每一个数据都有一个名字,这样,当我们才能在程序中操作它。数据的名字也分为好几种类型:字面量、常量和变量。我们先来分别了解一下:字面量字面量(也叫直接量):它是某些数据的名字,同时也是这些数据本身。换言之,字面量的表示(名字)就是它的值,并且直接暴露它所属于的数据类型。它们在程序里面直接就写成这个样子,本身就是一...原创 2020-09-22 12:02:57 · 320 阅读 · 0 评论 -
4-1课:即使罹患阿尔茨海默病,程序员也不该忘记的算法:二分查找
猜数游戏我们先一起来玩一个小游戏:猜数字。这个游戏需要两个人玩,一个攻方,一个守方——很像1v1的篮球赛,只不过互相攻防的不是篮球,而是数字!游戏规则具体游戏规则如下:【游戏双方】:防守者,攻击者 【游戏准备】:防守者在1到1000之间任选一个自然数作为神秘数,暗自记住,然后开始游戏。【游戏过程】:每一轮:攻击者猜一个数,问防守者:这个数是神秘数吗?防守者要根据事实...原创 2020-09-22 12:02:56 · 241 阅读 · 0 评论 -
4-2课:二分查找:从原理到形式化描述
本章我们来讲二分查找的原理和流程图。在此,因为我们讲的是通用算法的原理,因此,我们的算法要查找的序列虽然是有序的,但未必是等差数列,其中数字范围也不一定就是从1到1000——千万不要把自己局限在前面那个猜数游戏里。因此,在本章中,我们还是将所有的待查数字都放在一个整型List中,让其中的每个元素保存一个待查数字。二分查找原理二分查找(binary search)是一种在有序数列中查找某一特...原创 2020-09-22 12:02:54 · 232 阅读 · 0 评论 -
3-12课:从流程图到程序:用Python编写顺序查找算法
前面学了一大堆变量啊,赋值啊,到底有什么用呢?马上用处就来了——修改顺序查找流程图——用变量和赋值替换其中的自然语言以前的流程图还记得我们之前已经学习了顺序查找算法吧(还记得吗)?当时我们是画了一张流程图。先来回顾一下:流程图-1在这种图里,我们其实已经使用了数组(列表)变量arr,和整型变量i,只不过当时我们还不知道它们是变量,而仅仅将其当作数组和数组下标的形式化写法而已。重画...原创 2020-09-22 12:02:52 · 2161 阅读 · 0 评论 -
4-3课:二分查找的编程实现
流程控制再看流程图我们首先来回顾一下二分查找的流程图:上一章我们已经用变量形式化了其中涉及到的所有的实体,现在我们来看算法中的条件判断和查找区域调整部分,也就是上图中橘色和红色圈内的部分。比较查找区域中心元素和目标数将当前查找区域的中心元素和目标数进行比较,就是将arr[m]和tn进行比较,我们说过,在程序中比较两个变量是否相等要用==,所以此处代码为:arr[m] == tn如...原创 2020-09-22 12:02:51 · 291 阅读 · 0 评论 -
4-4课:用Python小蟒蛇编写一个小游戏
猜数游戏与二分查找还记得猜数游戏吗?之前的问题是:如果你是攻击者,你能保证在10次(含)之内猜出对方的数字吗?因为$2^{10} = 1024 > 1000$, 所以如果运用二分查找的话,我们作为攻击者是肯定可以赢得比赛的。实现1-1000数列的二分查找既然二分查找适用于猜数游戏,那让我们先套用一下上节课学习的二分查找算法实现代码,来实现以下1-1000数列的二分查找。代码如下:...原创 2020-09-22 12:02:50 · 359 阅读 · 0 评论 -
4-5课:为什么每个程序员都要拜四阿哥?要解决bug(八阿哥)
猜数小游戏为什么输了?改写小助手有位小A同学,学习了前一章的猜数游戏程序之后,决定自己把攻击者小助手重新实现一遍。不过小A想:程序写出来是我自己用嘛,何必搞那么麻烦呢?于是去掉了一些限制。另外,最好每一轮都打印出当前是第几轮,这样不是看得更清楚吗?于是,程序变成了下面这样:low = 1high = 1000loopNum = 0while low <= high: ...原创 2020-09-22 12:02:48 · 789 阅读 · 0 评论 -
4-6课:和 bug 的斗智斗勇
bug 的严重性小 bug 怡情,大 bug 伤身猜数游戏中的 bug,最多是让使用者输掉一个小游戏,实在是无足轻重。但是,如果是那些和我们的生活确实相关的软件中的 bug,后果就不那么轻松了。比如,银行计算利息的程序出了 bug,导致利息计算错误,少算了给储户的利息;通讯软件经常丢一些用户之间互发的消息等……如果发生,都会对我们的日常生活造成影响。巨大的 bug 导致灾难性结果如果 b...原创 2020-09-22 12:02:46 · 236 阅读 · 0 评论 -
4-7课:听起来很高深的“软件工程”是做什么?
软件工程概念在软件开发过程中预防、发现 bug,从而提高软件质量的具体方法有很多。每种方法自然各有其作用,但是,如果只用一种,效果还是很有限的。其实,早在几十年前,有识之士就发现了 bug 危害的严重性和软件质量的重要性。自上世纪六十年代,人们就开始研究系统性地提高软件质量的方法。1968 年秋季,北约科技委员会召集了近 50 名一流的程序员、计算机科学家和工业界巨头,讨论研究如何应用系统...原创 2020-09-22 12:02:45 · 388 阅读 · 0 评论 -
4-8课:计算机程序里的函数
现在让我们回到二分查找算法。变的和不变的代码前面我们讲了二分查找的流程及代码实现。我们实现二分查找的目的是为了用它来在任意数列中查找任意的数字,查找过程是不变的。而待查数列和目标数,却是时时要变的。可惜,在前面的实现代码里,存储待查数列的列表arr和目标数tn这两个变量在程序中被直接赋值。如果要改变他们的值,就要改写代码,给它们做重新的赋值。当然,这样做运行是没有问题。但是有的时候,经常...原创 2020-09-22 12:02:44 · 292 阅读 · 0 评论 -
4-9课:二分查找变形记:重复数列二分查找
包含重复元素数列的二分查找在前面的二分查找代码示例里,待查数列中的每个数字都只出现了一次。如果数列中可以包含重复的元素,那能不能得出正确结果呢?比如,我们把待查数列改成:arr = [ 3, 5, 5, 5, 5, 9, 7, 12, 15, 18, 32, 66, 78, 94, 103, 269]其中的5重复了4次,然后运行代码:from searchAlgorithms import...原创 2020-09-22 12:02:42 · 284 阅读 · 0 评论 -
4-10课:让变形更高效:与经典二分查找相同的时间复杂度
重复元素数列二分查找的时间复杂度代码修改影响了时间复杂度上一章,我们已经写出了新的处理含有重复数字数列的二分查找的repeatingSequenceBinarySearch()函数。那么,是不是重复元素查找的问题就解决了啊?从功能上说是这样。但是请注意,这个repeatingSequenceBinarySearch()函数(上一章代码-7)的时间复杂度是多少?二分查找的时间复杂度不是之前...原创 2020-09-22 12:02:40 · 226 阅读 · 0 评论 -
4-11课:二分查找算法再变形:旋转数列二分查找
有序数列的旋转现在待查数组不再是一个单纯的有序数列了,而是先把它在某个位置截为两段,然后交换前后两段的顺序,形成新的数列。之后,再在这个新数列中进行查找。比如:我们有一个原本的数列 [3, 5, 9, 7, 12, 15, 18, 32, 66, 78, 94, 103, 269],先把它截为两段:[3, 5, 9, 7, 12, 15, 18, 32]和[66, 78, 94, 103, 2...原创 2020-09-22 12:02:39 · 326 阅读 · 0 评论 -
4-12课:怎么才算学会了一个算法?
以二分查找为例,看看“掌握算法的几个层次”掌握算法的几个层次在前面,我们讲过学习一个算法的几个层次:理论联系实际现在我们就以刚刚学习过的经典二分查找算法为例,来讲解一下这几个层次对应到实际中是什么样子的。Level - 1:听说知道有个算法叫做“二分查找”,知道这个算法的目的是在一个有序的序列里找到目标数所在的位置,或者确认其不存在该序列中!Level -2:了解了解二分查找的基...原创 2020-09-22 12:02:37 · 392 阅读 · 0 评论 -
5-1课:人生处处排行榜:认识排序算法
从本章开始,我们要接触到一类新的算法:排序!什么是排序(Sorting)排序完全可以按照字面意义来理解,也就是:排列顺序。排序算法做得事情,其实就是将一串数据按照某种特定的方式进行排列。排序算法接受的输入是一个数据列表(此处的列表并不是Python中的list数据类型,而是指一系列虽然“连在一起“,但前后之间并没有顺序关系的元素);输出是一个序列,与输入对应的元素集合是一样的,不过经历了排...原创 2020-09-22 12:02:36 · 273 阅读 · 0 评论