陳凱
計(jì)算思維和算法思維,這是兩個(gè)不同且又有關(guān)系的概念,從已有文獻(xiàn)資料看,對(duì)兩者概念的辨析并不多見。有教師認(rèn)為,算法思維是計(jì)算思維的一個(gè)方面,算法思維的培養(yǎng)是計(jì)算思維發(fā)展的重要路徑[1];也有教師認(rèn)為,算法本身就蘊(yùn)含計(jì)算思維的思想和方法[2];甚至有教師斷言,在算法思維的培養(yǎng)中,其實(shí)已經(jīng)培養(yǎng)了大部分的計(jì)算思維。[3]讓筆者感興趣的問題是,如何將算法思維和計(jì)算思維兩者區(qū)別開來?或者換成更通俗的問法,如何說服他人,某一部分的教學(xué)內(nèi)容意在培養(yǎng)計(jì)算思維,其中可能也同時(shí)包括了算法思維的培養(yǎng),但又不僅僅是算法思維的培養(yǎng)?
算法一般指求解某一問題所能描述的有限的步驟,從計(jì)算機(jī)科學(xué)的角度看,算法這個(gè)概念通過圖靈機(jī)的行為和能力得到了精確的定義。但若問算法思維是什么,卻不能簡單地將其等同于設(shè)計(jì)規(guī)則使圖靈機(jī)解決某問題的思維,這是因?yàn)殡m然算法可運(yùn)行于圖靈機(jī)這種計(jì)算模型上,但實(shí)際問題的解決步驟卻往往借助圖靈等價(jià)的計(jì)算模型(最常用的是各種高級(jí)程序語言)來實(shí)現(xiàn),并不會(huì)特意去關(guān)注圖靈機(jī)規(guī)則設(shè)定中必然涉及的讀寫頭轉(zhuǎn)移和數(shù)據(jù)存儲(chǔ)的方式。也就是說,在實(shí)際用算法解決問題的過程中,圖靈機(jī)底層的行為往往被封裝起來了。雖然對(duì)算法思維進(jìn)行定義相當(dāng)困難,但能得到共識(shí)的是,算法思維具有以機(jī)械化方式進(jìn)行計(jì)算的特征。本文試圖通過幾項(xiàng)教學(xué)活動(dòng),對(duì)計(jì)算行為中的思維過程本身進(jìn)行分析,來說明算法思維是如何在解決問題的過程中發(fā)揮作用的,算法思維又是在什么時(shí)候趨近計(jì)算思維的。
● 十進(jìn)制和二進(jìn)制轉(zhuǎn)換中算法思維向計(jì)算思維的趨近
常用的將十進(jìn)制數(shù)轉(zhuǎn)為二進(jìn)制數(shù)的方法稱為除二取余法(所謂除二其實(shí)是用二來除),如圖1所示就是對(duì)十進(jìn)制數(shù)35按除二取余法計(jì)算出二進(jìn)制編碼。計(jì)算過程的實(shí)施者并不需要知道何以如此計(jì)算,他只要嚴(yán)格遵照預(yù)先設(shè)定的規(guī)則進(jìn)行除二取余的工作,并記得從下至上倒序讀數(shù),就能得出正確的結(jié)果。此過程具有十分顯明的機(jī)械化的特征。
請(qǐng)考慮以下與除二取余法略不同的將十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的方法:首先,在紙張左側(cè)寫下某十進(jìn)制數(shù)字,如35,判斷其奇偶,如果是奇數(shù),在其右側(cè)寫1,否則寫0。其次,將35整除以2,得到結(jié)果置放在下一行,并重復(fù)先前動(dòng)作(如圖2)。由于0整除0總是為0,所以對(duì)人來說,自然而然就可以獲知重復(fù)動(dòng)作終止的時(shí)刻。
實(shí)驗(yàn)表明,在兩種方法都花費(fèi)大致同樣時(shí)間講授的情況下,在允許學(xué)生自由選擇十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制編碼的方法時(shí),大部分學(xué)生都選擇了第二種方法,選用第一種方法的學(xué)生數(shù)量僅僅約為總數(shù)的三分之一。這是為什么呢?筆者認(rèn)為,第二種方法將除以2的動(dòng)作在計(jì)算步驟中抽離了出來,完全交由頭腦來處理,將數(shù)據(jù)的變化通過更簡單的空間上的轉(zhuǎn)移存儲(chǔ)在紙張上。圖3顯示了兩種計(jì)算方法在存儲(chǔ)變化了的數(shù)據(jù)時(shí),紙張上記錄空間發(fā)生變化的狀況。可以看出,在新的方法中,數(shù)字的變化情況能夠更簡潔而整齊地記錄在二維的紙張平面上。
考慮一下,假如不用紙筆,完全在頭腦中實(shí)現(xiàn)十進(jìn)制數(shù)的二進(jìn)制編碼轉(zhuǎn)換,可以進(jìn)一步將二維空間上的數(shù)據(jù)記錄方式轉(zhuǎn)變?yōu)橐痪S空間上的數(shù)據(jù)記錄方式。其過程按時(shí)間序列可以簡單記錄為如圖4所示的樣子。
按這樣的方法,可以將數(shù)據(jù)的變化情況在一維的空間中進(jìn)行記錄,這使得人能夠更容易通過心算將十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制編碼。
類似地,也可以將二進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)的數(shù)據(jù)變化情況,都存儲(chǔ)在一維的空間中,方法是從數(shù)碼最左側(cè)開始,將每個(gè)數(shù)碼乘以2后右移一個(gè)數(shù)位并與該數(shù)位上的數(shù)字疊加,反復(fù)此操作。以二進(jìn)制數(shù)100011舉例演示如圖5所示,空出的位用下畫線表示。
以上事例說明,同樣具有機(jī)械性特征的算法,用紙筆計(jì)算,與用心腦計(jì)算相比,其行為特征是不同的。從這個(gè)結(jié)論可以得到一個(gè)新的研究點(diǎn)的提示,用機(jī)械來實(shí)施具有機(jī)械性特征的算法,與用紙筆、用心腦來實(shí)施具有機(jī)械性特征的算法,一定是有不同之處的。
傅海倫指出,中國古代數(shù)學(xué)的算法機(jī)械化是與籌算體系下的位置思維協(xié)調(diào)一致的[4],此文給予筆者很大的啟發(fā)是,計(jì)算過程中固定的數(shù)據(jù)存儲(chǔ)位置強(qiáng)化了數(shù)學(xué)算法中的“機(jī)械性”,使得人工實(shí)現(xiàn)的重復(fù)運(yùn)作更便于計(jì)算機(jī)的實(shí)現(xiàn)。如果說十進(jìn)制數(shù)轉(zhuǎn)二進(jìn)制編碼的除二取余法體現(xiàn)了算法思維的運(yùn)用,那么本文給出的簡化方法以及心算方法,則有著向計(jì)算思維趨近的特征,之所以說“趨近”而不說“體現(xiàn)”,是因?yàn)檫€缺乏一種構(gòu)造性的方案,讓整個(gè)運(yùn)算過程真正自動(dòng)化地運(yùn)行起來。
● 循環(huán)結(jié)構(gòu)實(shí)現(xiàn)累加中算法思維向計(jì)算思維的趨近
在人的頭腦中計(jì)算自然數(shù)的累加,似乎是件容易的事情,但為什么用循環(huán)結(jié)構(gòu)實(shí)現(xiàn)自然數(shù)累加的程序代碼會(huì)讓許多初學(xué)者感覺疑惑呢?筆者首先考察的是自己頭腦中的累加過程:首先,有一橫列的自然數(shù)1、2、3、4……,然后取出1和2相加得3,頭腦中的景象變?yōu)?、3、4、5……,然后取出3和3相加得6,頭腦中的景象變?yōu)?、4、5、6……。在整個(gè)過程中,加法的結(jié)果和數(shù)列都在某個(gè)一維的數(shù)據(jù)空間中,而隨著加法的繼續(xù),數(shù)列會(huì)在尾部自動(dòng)增長。然而這樣的思維,是很難和循環(huán)結(jié)構(gòu)的累加程序代碼相契合的,在對(duì)學(xué)生的調(diào)查中發(fā)現(xiàn),有相當(dāng)多的學(xué)生,在實(shí)施自然數(shù)累加的過程中的思維模式是和以上方法類似的(這里不考慮使用數(shù)列求和公式的方法)。
有興趣的教師也可以自己開展相關(guān)調(diào)查,調(diào)查的一個(gè)訣竅是,當(dāng)學(xué)生說用1加上2得3,用3加上3得6,用6加上4得10的時(shí)候,重點(diǎn)詢問那個(gè)“4”是從何而來的。例如,他可能回答,這個(gè)“4”一直在某個(gè)列表中,既然“3”已經(jīng)被使用了,接下來自然是要加上“4”;或者他也可能回答,這個(gè)“4”是由原來的自然數(shù)“3”加上1得到的……調(diào)查的另一個(gè)注意事項(xiàng)是,被調(diào)查學(xué)生不能是已學(xué)習(xí)過用循環(huán)結(jié)構(gòu)語句實(shí)現(xiàn)自然數(shù)累加的方法的。筆者調(diào)查發(fā)現(xiàn),采用前者方法的學(xué)生人數(shù)要多于后者。
有少數(shù)學(xué)生給出的思維方法是這樣的,在頭腦中有兩個(gè)位置存放數(shù)字,分別是累加的數(shù)和自然數(shù),初始時(shí)是“0,1”,意味著累加值為0,自然數(shù)為1。其后進(jìn)入到將兩個(gè)數(shù)字的相加并存入左側(cè)位置,而右側(cè)位置的數(shù)字自增1的重復(fù)模式,存儲(chǔ)空間變化模式如圖6所示。
在頭腦的整個(gè)想象過程中,有如動(dòng)畫般的變換效果會(huì)使得問題更容易理解,如右側(cè)位的“1”發(fā)生了分解,變換出新的“1”,與左側(cè)空間的“0”相加得到“1”,然后右側(cè)位的“1”自增變成“2”,然后就是重復(fù)以上過程。
以上實(shí)驗(yàn)可以說明,即便是在人的頭腦中進(jìn)行計(jì)算,也往往需要借助固定的數(shù)據(jù)存儲(chǔ)位置,來實(shí)現(xiàn)計(jì)算過程的機(jī)械化。但數(shù)據(jù)存儲(chǔ)和調(diào)用的具體方式,不總是和計(jì)算機(jī)處理數(shù)據(jù)的方式相類似。
● 排序算法中算法思維向計(jì)算思維的趨近
將頭腦的排序方法和計(jì)算機(jī)算法的排序方法進(jìn)行比較,也可以通過“位置”使用方式看出算法思維與計(jì)算思維的不同。
假設(shè)一列數(shù)據(jù)存放在某個(gè)一維的空間中,空間最前面和末尾可以任意添加新的空間,這些數(shù)據(jù)是亂序的,現(xiàn)在要對(duì)它們從小到大進(jìn)行排序,存在兩種情況:①數(shù)據(jù)量超出了頭腦能同時(shí)把握的程度;
②允許隨意閱覽這些數(shù)據(jù)中相鄰的部分?jǐn)?shù)據(jù)。那么,應(yīng)該如何對(duì)數(shù)據(jù)進(jìn)行排序呢?大部分人使用的方法是,通過分段閱覽找到其中最小的數(shù)字,將這個(gè)數(shù)字移到這列數(shù)據(jù)最前面,然后對(duì)剩余的數(shù)據(jù)做同樣的操作。這個(gè)方法體現(xiàn)了具有機(jī)械化特征的算法思維的運(yùn)用,但卻較難交由一個(gè)真正的機(jī)械來實(shí)現(xiàn)。對(duì)于一個(gè)機(jī)械來說,每個(gè)數(shù)據(jù)在某一時(shí)刻都必須停留在某個(gè)位置上,這與人的頭腦處理數(shù)據(jù)的方式有明顯的不同。為了能讓機(jī)械處理數(shù)據(jù)成為可能,在應(yīng)用以上排序方法時(shí),就需要在整個(gè)數(shù)據(jù)列的最前面,新開辟出一個(gè)存儲(chǔ)數(shù)據(jù)的位置,然后尋找得到最小的數(shù)字,將這個(gè)數(shù)字移動(dòng)到這個(gè)新開辟的位置,接著還要為后續(xù)重復(fù)操作做好準(zhǔn)備。例如,一個(gè)容易想到但效率比較低的方案:將移走數(shù)字后留出的空檔,用后續(xù)數(shù)字逐個(gè)移過來填滿(每次移動(dòng)都會(huì)出現(xiàn)新的空檔,然后再用更后的數(shù)字填滿),接下來,是要在處于數(shù)據(jù)列首位的最小數(shù)的后面,插入一個(gè)新的空檔,以存放第二小的數(shù)字,但為了做到這一點(diǎn),就需要首先在處于首位的最小數(shù)字前開辟一個(gè)新空間,然后將最小數(shù)移動(dòng)到新的位置,騰出第二個(gè)位置。當(dāng)然,為了使以上操作能夠順利實(shí)施,還需要記錄已經(jīng)移動(dòng)了幾個(gè)數(shù)字過來,這樣才能確定將新找到的數(shù)字填充到哪里,這個(gè)記錄可以存放到空間末尾某個(gè)地方,不過這就產(chǎn)生了一個(gè)新的麻煩,怎樣避免這個(gè)記錄本身不被當(dāng)成要排序的數(shù)據(jù)……可以看出,頭腦容易解決的問題,換做用固定位置轉(zhuǎn)移和填充的機(jī)械方法來實(shí)現(xiàn),就相當(dāng)煩瑣。那么,為了簡化以上煩瑣過程,就需要從算法思維向計(jì)算思維趨近。
對(duì)比以上煩瑣的機(jī)械化的排序過程,才能更好地體現(xiàn)出一些經(jīng)典排序算法的精妙,以冒泡排序算法為例,可以在數(shù)據(jù)空間末尾添加四個(gè)新的空間,一個(gè)用來充當(dāng)交換數(shù)據(jù)的臨時(shí)變量,一個(gè)用來記錄需要排序數(shù)據(jù)的數(shù)量,另外兩個(gè)用來記錄冒泡的輪次和比較的位置,程序代碼中除了數(shù)據(jù)空間自身以外,并沒有其他變量,這樣就在一個(gè)固定位置的數(shù)據(jù)空間中實(shí)現(xiàn)了排序,如圖7所示。
對(duì)比傳統(tǒng)的冒泡排序算法的程序?qū)崿F(xiàn),將程序代碼中所有的變量操作都以列表或數(shù)組中數(shù)據(jù)的變化來加以替代,就使得整個(gè)算法更具有機(jī)械自動(dòng)化的直觀性。這就實(shí)現(xiàn)了從算法本身的學(xué)習(xí)向算法之所以能使機(jī)械自動(dòng)化工作有效的探索過程的還原,從而領(lǐng)悟到機(jī)械自動(dòng)化直觀和人類頭腦中所想象和容易理解的自動(dòng)化兩者間的差別,以及在思考如何在兩者間建立轉(zhuǎn)換關(guān)系的時(shí)候,其所需要的思維方式就不能僅用算法思維來涵蓋了。
通過本文的例子回顧“算法本身就蘊(yùn)含計(jì)算思維的思想和方法”這句話,也許能有更深的理解,那就是,可以將計(jì)算機(jī)的算法看成是算法思維和計(jì)算思維的共同成果。在教學(xué)中,計(jì)算機(jī)算法不是現(xiàn)成的等待了解的某物,而是從機(jī)械性的思維方法出發(fā),經(jīng)由研究分析如何讓機(jī)械可以真正且有效運(yùn)作此算法過程而得到的成果,而這種研究分析和實(shí)現(xiàn)的路徑,則體現(xiàn)了計(jì)算思維的應(yīng)用。
參考文獻(xiàn):
[1]周世杰.從計(jì)算思維的視角辨析算法中的遞歸與迭代[J].中國信息技術(shù)教育,2020(09):53-55.
[2]劉梅彥,徐英慧.大學(xué)計(jì)算機(jī)基礎(chǔ)教學(xué)中算法思維的培養(yǎng)[J].軟件導(dǎo)刊,2016(04):199-201.
[3]馬波.從算法思維到計(jì)算思維[J].軟件導(dǎo)刊·教育技術(shù),2019(05):71-73.
[4]傅海倫.位置思維方式與數(shù)學(xué)機(jī)械化[J].科學(xué)技術(shù)與辯證法,2000(01):36.
3808500589294