计组Pre考试部分题目分析
通过本文,您的收获可能有:了解pre考试的难度以及pre的测试内容,本篇文章存在的最大意义可能就是如此。
logisim部分:考了简单的组合逻辑电路,告诉你一年中有1,4,5,6,9,10月份有假期,下面输入月份(4位2进制),判断有无假期。懒人做法是真值表暴力analyse circuit,本题提示中提到的卡诺图+无关项做法是在此题的特殊条件下的一种做法:本题说非法输入(不是1到12月份)don't care,也就是说输出什么都无所谓,不妨让他们输出1,画出卡诺图可以消去相当多的项,这样电路就很简单了。
verilog部分:字符自动机。由于本人不确定学校让不让把题目放出来,所以我暂时先不把题面传上来,过一段时间一定补上。
本题要求较为复杂,所以建模过程多花时间是值得的(编程只是工具,工具先进但方法不对也白费)。考场上我旁边一位同学很快写出了程序,但一直到最后都没有AC,而我建模虽然花了一些时间,但是由于考虑全面,第一次提交仅仅是因为输出结果部分忘了赋值有bug,很快便意识到并改过来A掉此题。我考虑了 haven't started yet(#之前),none(开始某个单词但没读到非空白符),b(读到b),bu(读到bu),bua……(读到bua以及一系列a),hopeless(剪枝,一定不行的情况,比如读到bua之外的字符,比如格式不对),finish(?之后)这七种状态。状态转移时注意任何时候都有可能读到?以及“space”,所以状态跳转很多。下面是我在考场画出的状态转移图,其中省略了每个状态读到“?”时的情景(画不开了,字丑勿怪)
至于代码,由于本人的ISE有些问题,没法打开原来的文件,所以只能先拖着了,以后找到解决方法一定补上!
经验教训:1.状态转移图要找一张大一点的纸画
2.赋值的时候不用考虑进制,不要像图中左边一样手算二进制了,忘了语法就承认忘了,自己试着写一句话然后语法检查一下就知道对不对了
3.别着急,能写多少写多少。
mips:字符串扩展。题目中给的C代码写得比较简单,至少比我当年写得简单。本题考场上没写完,原因竟是:不知道怎么读一个字节!!!!用lb可以读一个字节,而lw是读一个字!!!
考完之后第二天,也就是周日深夜,用了一个多小时的时间,终于把这道题补上了。如果不看提示的C代码的话, 可能会非常难写(还是我弱,硬想会想乱)。有了C代码,基本上就是翻译了。下面说几个我的教训:一是我不知道有lb这个可以读取一个字节的指令,知道之后才能入手去做这个题。第二是在知道有lb之后,我没有意识到还有sb的存在,以至于自己写了一串sw,运行时出错,卡了十几分钟才推理出可能存在这个函数。三是我使用错了sb指令,sb指令的格式是:sb $t1,delta($t2),要在括号里写基地址,在括号外写偏移量,所以需要把基地址存在一个地方,然后放在括号里,然后刷新计数变量去移动存储下标存储数据,,否则,就会和我一样,眼睁睁看着字符串构造出来了,但是却输出不出来。
下面附上能够通过两个样例的代码:
注意,北航计组严查代码,抄袭将会取消成绩,各位想必也见过大一DS代码抄袭作业成绩取消的情况,所以各位不要铤而走险!!!
.macro done li $v0,10 syscall .end_macro .data raw_string: .space 200 ans_string: .space 200 enter: .asciiz "\n" .text li $v0,8 la $a0,raw_string #get the address li $a1,200 #max numbers of char syscall #read the string and save in raw_string li $t0,0 #t0 is i li $t1,0 #t1 is j la $s0,raw_string #s0 is the base_address of raw la $s1,ans_string #s1 is the base_adderss of ans add $t3,$s1,$t1 #base+delta,ans for_i_start: add $t2,$s0,$t0 #base+delta,raw lb $s2,raw_string($t2) #read s[i] beq $s2,10,for_i_end #if s2='\n',break sb $s2,ans_string($t3) #save this char in ans addi $t3,$t3,1 #t3=t3+1 lb $s3,1($t2) #read s[i+1] lb $s4,2($t2) #read s[i+2] bne $s3,45,add_i #if(s[i+1]!=‘-’),i++ slt $t4,$s2,$s4 #t4=s[i]<s[i+2]?1:0 bne $t4,1,add_i #if(s[i]>=s[i+2]),i++ addi $t5,$s2,1 #t5=s[i]+1 for_extend_start: beq $t5,$s4,add_double_i #if c>=s[i+2],i=i+2 sb $t5,ans_string($t3) #s2[m]=c addi $t3,$t3,1 #m++ addi $t5,$t5,1 #c++ j for_extend_start add_double_i: addi $t0,$t0,2 #i+=2 j for_i_start add_i: addi $t0,$t0,1 #i++ j for_i_start for_i_end: li $t5,0 #c='\0' sb $t5,ans_string($t3) #s[m]='\0' la $a0,ans_string addi $a0,$a0,200 li $v0,4 syscall done
以上便是计组Pre考试心得以及参考解析,各位,晚安!