00:00
好同学们,我们现在呢,就根据前面的这样一个分析的流程,我们把这个代码呢,给大家实现一下,好同学们注意听哈,那首先呢,我在这边先建一个类。对吧,我们就叫开了q later是吧,计算器嘛,把主控把勾上。把主方法勾上。首先我们是不是需要一个站呢?对,我们先先创建一个站,这个站呢,我们就直接使用,直接使用使用前面啊,前面创建好的创建好的。那前面我们这已经创建好了一个基于数组的一个站,那我把这个拿过来。对不对,我把这个拿过来。把它放在这边,那为了跟前面这个有区别呢,我们把这个改成二,好吧,改成二。改成二,这边呢,构造器也改成二,其他的不用变,其他不用变,但是同学们有没有发现。
01:06
目前我们这个站呢,就是奥这个二这个站呢,需要再再扩展一下功能。啊,需要扩展。扩展功能,说老师为什么要需要扩展功能呢?大家想一想,是不是原先我们我们在分析过程中,是不是这里面有几个功能是原先这个站没有的,比如说我们判断他是他谁的优先级高,谁的优先级低,是不是需要一个方法呀。是不是需要一个方法,第二个我们判断它是一个数还是一个符号,比如说你这发现是一个数字。发现发现是扫描到是一个符号,同学们,这些你总得有一个方法来判断,你不能每次都专门写一段代码是不是,所以说呢,我们需要增加一些功能来,那我现在呢,给他扩展一些功能写进去,首先我先扩展第一个功能干什么呢?就是。
02:07
就是返回,返回运算符的优先级,优先级注意啊,这个优先级呢,是程序员来定的来确定的。来确定的,就是你认为这个优先级是什么就是什么,那么现在呢,我们假定数字越大。就是这个优,优先级越高,就是返回的数字越大呢,优先级就越高。我们这样写啊,优先级使用数字表示。使用数字表示,那么这个数字越大。越大则优先级,优先级就怎么样越高,能理解我的意思吧,好,那现在呢,老师就开始来写这段代码,Public public in in priority啊,Priority这个单词啊,我们这样写parity parity,然后呢,你给我传一个操作符过来。
03:10
你给我传一个操作符过来,我就进行一个判断,好吧,那我这样写,如果。如果oper。Oper。它等于一个。这样的符号,因为我们知道在Java里面呢,这个int和char它是可以混用的,当它比较的时候呢,Char的本质底层也是一个数字,是不是,所以这样比没有问题,如果它是等于一个乘或者。跟上老师思路啊,或者它等于一个除,那么这时。我们认为它的优先级为一。啊,这是我确定的,我认为优先级,那么as if,如果这个操作符它等于一个加,或者注意听op,它等于一个减。
04:05
那么我们认为它的优先级稍微低一点是多少呢?一个零。啊,我认为乘法和除法优先级高,加法和减法优先级低,然后呢,如果对不对,它不是乘法,或者是不是这四个符号,我们认为它这个是有问题的,我们直接返回一个负一。啊,假设我们我们假定啊,我们假定目前的这个计算式里面呢,计算式表达式啊,表达式只含有。只有什么呢?只有这个加减乘除这四种运算法。连小括号我们都没有加进去,如果是小括号的话呢,优先级就更高了,好,第一个方法我们就写完了,我们再来写第二个方法就是判断,判断是不是一个什么呢?操作符或者叫运算符。
05:01
运算符,那么现在呢?我们来写一个方法,不一日offer。就看它是不是一个运算符号,我接收一个接收一个char这样的一个值,当然也可以写成一个整整数啊,我这按char来比较也是可以的,那return什么呢?Return。如果这个Y6。Value,它等于这个。或者value,它等于什么呢?减或者value等于什么呢?一个乘法。对吧,或者value。Value这个值它等于一个除的一个。符号,那在这样几个情况下呢,我们认为它就是一个运算符。他就是应该说,那如果不是运算符,反过来就是一个数字了嘛,对不对?好,因为我们这个表达式里面要么是运算符,要么是要么是数字,所以说我写一个is offer就可以了,那现在呢,我们还要有一个方法,什么方法大家看一下是不是我们这要不停的进行这个运算呢。
06:14
你弹出来两个数要进行运算,那我专门写一个方法进行运算,写个计算方法没问题吧,计算方法呢,我就直接写了,返回一个int开了,那我接收两个。值啊,两个数int number1和NUMBER2,然后呢,再接收一个操作符。Oper。好,我说了啊,Char和int可以混庸的,所以说我这呢写的是一个int,当然你也可以写个差。他说我我得到一串也行啊也行,对它是混用的,好,现在呢,我们就来开始进行一个操作啊,进行一个操作,假定返回的结果是result,这个result呢,是用于存放什么,存放反计算的结果,计算的结果没问题吧,那现在呢,我们用十位取语句来处理。
07:06
Switch语句来处理好。如果我拿到这个offer。你给我传了一个oper。你传一个offer,如果说它是一个什么呢?是一个加法。好,我就把这个result计算出来,等于多少呢?Number。一加NUMBER2没问题吧。好,如果。我复制一份,我复制一份,如果我发现你给我传的这个操作符是一个减法,我就应该什么呢?NUMBER2减NUMBER1,注意一个顺序。注意这个顺序啊,刚才我们是不是分析了,要把后弹出来这个数。作为这个减速啊,注意这个减速好,然后呢,这个地方呢,我们这写个注意顺序,注意顺序。好,那减做完了过后,是不是还有可能有乘法,乘法的顺序呢?无所谓,所以说NUMBER1乘以NUMBER2,那还有一个什么呢?除法,除法是不是也有个除数和被除数的问题,应该把NUMBER2写前面,把NUMBER1写后面才对。
08:13
好,最后呢,这个运算完毕,运算完毕过后,我们把这个结果返回。代码就写完了,就说这个关于计算这个方法呢,我们就写完了。对吧,好,写完以后我们。这一个站的相关的三个方法就写完了,写完了然后下面我们就开始按照刚才的这个流程,一步一步的把代码进行一个实现好的来这段这个地方呢,有一点小小的难度啊,同学们跟上我的思路,就说你哪个地方想不明白,你就跟上老师思路来,我们开始来做这个工作。好,根据前面前面老师的。的思路啊思路。
09:00
思路完成。完成什么呢?完成这个这个表达式的。表达表达式的一个运算。啊,大家想首先是不是我们有一个扫描的,被扫描的这个表达式啊,好表达式,那么就写到这来,我们写一个,比如说这个expression。表达式,那么我们先写一个最简单的,我们刚才是不是用这个表达式来玩的,我们就用它好吧,待会呢也来验证结果对不对?好表达式是不是我们要第一个,呃,先创建创建两个站。一个是速战。速战。是不是一个是什么站符号站能理解吧,那现在呢,我们开始来写了啊六一个二。大克,那大小呢,我们给它稍微大一点,十就是占的大小呢,我们放十,就说至少它这个地方也可以有十个运算符,那现在呢,我们生成一下。
10:06
第一个名字,我们取个名字叫做number。Number没问题吧?那紧接着呢,我们再创建一个站,这个站呢,我们取子叫oper。就说运算符这么一个站。好,这两个站有了过后呢,我们现在开始定义这么几个东西啊,定义需要的相关变量,能看到我的思路吧,首先是不是应该有个扫描的,用于扫描的索引初始化为零。出出这个就是这个index用于扫描的,就是刚才我们扫描的时候不是需要有一个有一个索引帮助我们来取得这个表达式里面的每一个数字,或者是运算,呃或或者是它的操作符吗?对不对,这个是用于扫描的,用于。用于上扬。好的,那现在呢,我们还需要几个字,NUMBER1。
11:02
因为大家知道我们将来在弹数的时候需要NUMBER1和NUMBER2,所以说我定两个啊,这就快速写了NUMBER1NUMBER2定一个。当然我们还需要接收操作符的这么一个东西,这个地方我用的是int。当然也可以写成差,好写成零。我们还需要什么?同学们是不是运算过后还有一个结果要保存,我们用这个result来保存。对吧,还需要一个什么,还需要什么,是不是我们每次扫描会扫描的一个券。就是我们这样子啊,将每次写到这里。将每次扫描得到的这个char保存到哪里去C中。好,现在呢,我们现在是不是开始循环的,就是就是用开始用while语句循环的扫描,扫描这个expression。
12:00
那大家想什么时候这个Y2循环结束呢?是不是扫描到最后这个。就要退出,因此我们现在呢,写个外语句,我先写个出没问题吧。好,第一步先干什么呢?先得到啊,先就是扫描啊,依次依次得到这个expression里面的每一个字符。因为你扫描肯定是一个扫的嘛,一次得到的每一个。的每一个字符跟上我的思路C是等于。那么同学们想,我们怎么能够得到的每个字符呢?是不是要用相关的字符串的方法?字符串里面是不是有个方法叫sub string?能理解吧,Begin,它的初始的位置是,它取几个呢?我们就取一个,因为你要一个个的取index加一。好。那么取出来过后,这个是不是一个字符串呢?
13:00
那么我要取出它第一个差二零。因为我要把它转成一个字符吗?这个其实是取返回了一个字符串,但是这个字符串呢,只有一个字符,所以说我用char艾零把它取出来,能理解我的意思吧,好把这个全屏一下,全屏一下好拿到这个过后是不是就开始要判断了。判断什么,大家看是不是根据刚才老师我们扫描完了之后发现是数字怎么处理,发现是符号怎么处理符号里面呢,又分这些情况能理解吧。是不是有点麻烦,但是不要紧啊,这么一会儿就写完了,那根据判断这个C是什么,然后做什么相应的处理。相应的处理就按这个逻辑来走,首先呢,我们先判断如果,如果它是一个什么呢?符号,我们先看看它是什么东西啊,我用一个符号站。他有个方法叫isoper。我把什么放进去呢?把这个CH放进去。
14:02
好,如果它是一个符号。这好,如果是运算符。运算符跟上我的思路,那如果它是一个运算符的话,是不是我们又要继续判断。看当前这个站是空还是是不是为空,判断当前的这个符号站,符号站是否为空。好,如果为空,我们直接入账,好,写上啊,如果op。点is什么呀,Is empty。啊,如果为空怎么办?如果不为空怎么办?那么假定现在它不为空。我们做处理。如果它为空怎么办呢?如果为空是不是我们直接把它加进去就可以了?对不对,如果它为空,我们是不是直接入账,这是啊,如果为空直接入账,待会儿我们把这个写进去,现在呢,这个地方判断不为空,不为空是不是里面又要有两个逻辑。
15:11
是不是有两个逻辑,看我们这写的有吗?看啊,如果不为空,就是里面有东西,有东西的话呢,就要判断这个动作了,来,我把这个写进去。稍微有点麻烦啊,就是说如果符号站有操作符,就是部位空,那么进行比较,如果当前的操作符的优先级小于等于占中的优先级就怎么样,就。就进行下面的这几个操作。是不是我把这个一起写过来啊,这个稍微的有点长,然后呢,我们把它粘过来。不然待会这个代码有可能是要出问题的。好,那老师开始开始写这个逻辑了啊,判断。如果如果说我现在这个oper,我们写一写。
16:00
就是占中的,我们先这样写啊,走它的优先级。谁的优先级呢?就是现在我们这个CH的优先级,就是我当前这个优先级,如果它小于等于。如果它小于等于我们当前这个op sta占顶的这个符号的优先级,我们就开始运算,是这意思吧?那小于等于谁呢?把这个写进去,还是用这个来进行算op stack。点它有一个优先级,取出占顶的,占顶的那个占顶的我们应该怎么取呢?这样取,注意它不是真正的取出来,只是看一眼啊,所以说我们在取的时候应该是这样取的。Oper operator,然后呢,我们这样写暂停。赞。里边有一个sta。好,注意这个大克呢,呃,我们干脆这样写一个,我们这样写一个方法,就是能够能够看一眼,就是能够看到这个站顶的这个符号,这个占顶,占顶的这个值是什么,但是呢,呃,不把它真正的弹出站。
17:17
叫pick啊,我这边需要一个方法。我要增加一个方法,刚才没有的方法,我要增加一个。好,因为这呢,我们需要一个方法这样子的啊,就是增加。增加一个方法干什么呢?可以返回当前占顶。占顶啊,占顶的这个指。但是不是真正出战啊,但是不是真正的真正真正的这个泡泡。不是pop出来,那现在我写一个方法,这个呢,我们返回一个值,我们叫做pick pick就是偷看一眼的意思,是这意思吧,那么我们首先看一下,这我就直接简单写一下啊,叫return。
18:03
什么呢,Sta?拉克。这个里面的占顶的一个字。大家看到这看到这个意思没有,就是我返回当前占领的值,但是不是真正的power,只是把占顶的这个值返回来而已,好现在有了这个东西呢,我这就比较简单了。是不是这个前面是当前准备扫,呃,当前扫描到这个这个符号的优先级,那么跟当前这个站的站点的这个符号优先级进行比较,那这也简单了,就直接点pick。是这个意思吧,好,如果说这个条件满足。对,如果这个条件满足,是不是就意味着我们要把从数这个满,满足过后应该怎么办?就从数站抛不出两个数进行运算是意思吧,那我就直接写了啊,那就开始抛东西了,NUMBER1,因为前面我已经定义了NUMBER1等于从速站。
19:07
你放心,这个树上里面肯定有东西,肯定有东西,先泡泡第一个树。NUMBER2POP第二个数。泡泡第二个数是不是?Pop第二个数过后呢,我们再pop一个运算符,运算符就是把当前这个符号站的。这个数,这个占顶的符号先抛不出来。泡泡出来过后,是不是我们要进行一个运算。运算,我们用什么来运算呢?我们用做速战。速站它不是有个运算方法吗?放进去就可以了。这就是他的一个运算结果,运算结果完了过后把什么呢?把运算的结果,把运算的结果注意听啊,结果入什么战入数战。这个是不是很简单,那就是number。
20:01
点push,谁push我们的res?不要忘了还有一件事情。干什么?入完数站以后,还要把当前这个操作符入符号站,不然的话就少了一个符号啊,注意,然后把当前的操作符入符号站,是不是刚才我们已经分析过了,如果没有分析,大家可能就不知道老师在说什么了,现在应该还稍微好一点,对吧?我把哪个放进去,把CH放进去就完事。好,这个是指的,呃不为空,并且它的优先级,呃就是当前这个符号的优先级呢,小于占里面的符号优先级这样子的,那反过来还有一个逻辑。S是什么?就是说如如果是不是我们这还有一个这样的逻辑,后面这个如果。当前的。当前的操作符的优先级大于,因为你这个是小于等于,那反过来就是我大于,你就直接入符号三,这个比较简单,那就直接offer。
21:05
点push,谁push我们这个CH完事。是不是,但是你这边还有一个动作不要忘了哟,不要忘了,就是如果说。如果他他是为空的,是不是直接入入站啊,入哪个站符号站,是不是把这句话要写进去。就是如果为空,那么直接入入哪个站呢?入符号站。因为是第一个嘛,符号站,那这个也很简单,一句话的事就搞定了。点push所。把这个CH扔进去就可以了。就好像你扫描到,比如说我们刚才是比如说一加三,当我们扫描第一个第一个第一个加的时候,是不是符号站里面一个都没有,是不是把三把这个加号直接放进去啊。是这个意思吧,好了,这个呢,我们就把它放进去了,好这是我们是运算符的情况,我们就做完了,但是是不是还有一种情况,如果是竖又怎么办呢。
22:07
是不是应该现在要处理?处理这个逻辑了。当我们。发现。啊,这个是扫描是当面前面是发,发现是数字的话,是不是就直接直接入账了。是不是这样分析的好。如果是数。如果是数则则什么呢?则直接直接入数站,是不是刚才这么分析的,那现在我们。把它放进去哦,大家看我这样写,呃,对不对,Number。Number stuck.push这个CH我这样写对不对?大家先想一想,我这样写对不对?我这样写是错的,大家想因为你扫描到,比如说你扫描这个一加三,你扫描到这个一,其实它是。
23:00
这个一是字符一,而不是真正的这个一。为什么打开我们的阿斯克玛表,我们来看一下。打开我们的阿斯克码表,你们搂一搂。看这里。看这里,我们这儿有一个。资料打开阿表,我们来看一下。同学们看哦,同学们看。是不是你们有发现?当我们。当我们得到这个字符一的时候,其实它真正的值是49。当我们得到字符三的时候,其实它的真正的这个十进制的值是51,它们刚好相差多少?48。能看懂吗?所以说如果你真的这样去存放到实验这个结果是错的,应该怎么存呢?应该是让CH减去一个48就对了。哦,这地方千万别忘了啊,一定要减。
24:01
一定要减掉48,为什么?刚才我已经说过了。好,当这个做完了以后,当我们把这个做完以后,下一步是不是要去,呃,你看这个while循环什么时候退出,是不是还没有逻辑啊,是不是下一步应该看看让让这个index加一。并判断是否扫描到。扫诶扫描这写啊。扫描。扫描到这个expression的最后了。因为你如果到最后是不是应该退出了呀,那么现在这样写啊index。所以这稍微有点麻烦,Index,呃,我们就来个加加吧。再加加加过,你要做一个判断,是不是已经到了最后了,那我写一句话啊,Index如果大于。大于等于expression的这个长度了。大家说明说明什么问题,就是假如我们扫描过后,我在因为下一个我要index要要自真嘛,因为你在扫的时候,这个index不是先扫第一个,再扫第二,再扫第三,他扫扫到最后这个如果再往下面挪一下,是不是它就等于整个字符串的长度了,因为index是从零开始的。
25:17
是不是,所以说当它大于等于的时候,其实等于的时候,七乘等于也可以,但是呢,我这写大于等于也没错,这个条件一旦满足,其实就已经到最后了,那这个时候应该怎么办呢?Break。Break,也就是说当我做到这一步的时候,整个扫描就结束了,那扫描结束以后,我们是不是要做下面的逻辑,什么逻辑看这里。当整个表达式扫描完毕以后,就顺序的从数站和符号当中泡相应的数和符号并运算,最后留在数站的数字就是表达式的结果。是不是好,那现在呢,我们把这句话给同学们写一下就可以了,非常简单来看啊,现在这一段逻辑就应该是。
26:07
这块。能理解这个意思吧,好,现在呢,老师开始写代码了,While语句处。Y余数,那呃,什么时候表示后面只有一个数呢?咱们可以这样来做啊。符号站如果为空,你看。其实到最后留,最后留了一个13的时候,符号站其实也是为空了,其实也可以通过符号站是否为空,来判断我们这个工作循环的工作是否结束,是这意思吧,所以说我这样写啊。这样写。如果,如果符号占。为空,则,则计算结束了。计算到。到什么呢?最后的结果。也就是说,当符号站为空的计算到最后结果呢?那么速战速战只能速战中只有。
27:03
只有一个数字了,这个就是结果。能理解我的意思吧,这个就是结果好,那现在呢,老师把这个代码写一下,如果。如果什么样,我们的sta。点is empty。能跟上我的思路吗?是不是在这个条件成立的话就玩完了,否则是不是把刚才这段逻辑反复的走。是不是这样逻,是不是这个逻辑就从数站谈一个,再谈一个,再计算,再弹一个符号再计算,计算完了过后,是不是要把这个result再重新放回到数站里面去。是不是numbers。点什么呀,Push。谁而已?这个就是入战吗?入战好,等到整个这个Y循环结束以后,各位同学,如果你这个没有错,那么数战里面只有一个数字就是结果。
28:00
那么把这个结果打出来就可以了。走一个来走一段走一下,那现在呢,我们写表达式。是多少,我们把它输出来,这样把这个结果也输出。表达式等于结果。好,格式化一下。格式化一下。来,那表达式是什么呢?就是expression。结果是什么呢?各位同学是不是从速站里面把它泡泡出来就可以了?是不是,那这个就就是最后的一个结果嘛,当然你这样算一下也也可以,也可以写一下啊,就是。将最后将速战。的最后这个数。树怎么了?泡不出来,泡不出。就是结果好,这样子呢,我们也可以这样写啊,就是分两步写也可以RESULT2等于。把这句话。粘过来。这样呢,看得更清晰一点,然后把这个结果呢,直接放这。
29:02
也可以,好,同学们,现在代码就写完了。代码就写完了,能不能。通过我们这个验证呢,不知道,因为这个代码毕竟有这么多话,而且呢,逻辑上还是有点复杂的,所以说你们有没有看到,当我们以这个中缀表达式,其实这个就是中缀表达式来进行运算的时候,它的步骤还是比较麻烦的,是不是因为它并不是后缀表达式,后缀如果是后缀表达式会简单,现在我们直接把这个中缀表达式进行计算,你看思路还是比较。八分之,那我们来运行一下,看看结果对不对,来走一个。走一个啊,大胆的走一把,我们看这个结果呢,跟我们想的完全一样,是13,我改一个值,比方说我把这个呢改成七,把这个改成四,好,这个结果我们算一下应该等于多少呢?是七加12等于19 19减去一个四等于。
30:02
15。好,结果呢,也是正确的。也是正确的。好,那么我们通过这一段代码呢,按照我们这个逻辑就实现了,但是有没有问题,大家想一想。有同学能思考出来我这个逻辑有什么问题吗?就说如果仅仅是从这个运算的顺序来讲,是没有任何问题的,但是有细节问题,比如说同学们看,假如我把这个改成按照我这写的,把它改成一个30。那这个地方我改成70,你们看,按理说这个70加上一个12等于。八十二八十二减去一个四等于多少呢?78,但是你等于78吗?我发现了。等于八,这是不对的,那么同学们想一想,这是为什么?好,这个为什么呢,待会儿我们在下一节课为大家讲解,这节课呢,咱们讲的时间也比较多了,大家去消化,然后呢,我这留了一个问题,就是如何如何。
31:05
如何处理。多为?多位多位数的问题。对不对?好,同学们先想一想啊,代码也很简单,思路呢,呃,要一定要按照这个思路严格的走。这里大家应该体会到,这个站确实在这里起了大的作用,如果没有这个站,我们写起来更麻烦,对不对?好,那关于我们这个。一位数的这个加减乘除运算呢,我们就使用占给大家实现了。截取一段视频。
我来说两句