通過本文,您的收獲可能有:了解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考試心得以及參考解析,各位,晚安!