專利名稱:一種電子數(shù)據(jù)表的計(jì)算方法和裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及電子數(shù)據(jù)表處理,特別是涉及一種對電子數(shù)據(jù)表進(jìn)行計(jì)算的方法和裝置。
背景技術(shù):
電子數(shù)據(jù)表(Spreadsheet)是以單元形式來組織數(shù)據(jù)及信息的計(jì)算工具軟件,譬如Microsoft Excel,Lotus1-2-3,Borland Quattro Pro,LinuxGnumeric,WPS表格,永中Office等等。
單元為電子數(shù)據(jù)表的最基本組成單元,其中可以包含計(jì)算公式,用以計(jì)算此單元的數(shù)值。電子數(shù)據(jù)表還可以預(yù)先設(shè)定或由二次開發(fā)者提供一些功能函數(shù),這些函數(shù)可用于單元公式中,以方便用戶使用。
傳統(tǒng)的電子數(shù)據(jù)表如Microsoft Excel利用單個計(jì)算鏈處理電子數(shù)據(jù)表中公式的計(jì)算和重算,該計(jì)算鏈在本質(zhì)上是被輸入到Excel當(dāng)前載入的所有工作表中的全部公式的有序列表。在公式被輸入到電子表格時,該公式被添加到全局計(jì)算鏈的開始。當(dāng)通過修改公式所依賴的單元的內(nèi)容或手動請求重算操作觸發(fā)重算(recalc)操作時,Excel將會循環(huán)訪問計(jì)算鏈中,并重新計(jì)算已經(jīng)被標(biāo)記為“臟”(即,等待重算)的任何公式。如對單元C4=A4+B4,代碼從對第一個單元C4求值開始,在嘗試對公式“=A4+B4”求值時,計(jì)算代碼發(fā)現(xiàn),該公式依賴于單元A4,并且單元A4是“臟的”,即是說仍然要計(jì)算。在這一情況中,單元C4的公式“=A4+B4”稱為“依賴”公式,單元C4稱為依賴單元,單元A4、B4稱為支持單元,單元A4中的公式稱為“支持”公式。代碼停止對公式=A4+B4求值,將單元A4的公式壓入計(jì)算鏈,并將其再次插入到緊靠在單元C4的公式之前。然后,計(jì)算代碼從單元A4的公式開始,重新開始其工作。毫無問題,計(jì)算代碼對A4求值,轉(zhuǎn)移到C4。在嘗試對公式=A4+B4求值時(第二次),計(jì)算代碼得知A4現(xiàn)在已經(jīng)被計(jì)算(不再“臟”),但發(fā)現(xiàn)公式也依賴于單元B4,并且B4也是“臟”的。這樣,代碼再次停止對該公式求值,并將B4的公式移到緊靠在C4的公式之前。然后,毫無問題,代碼對B4求值,并轉(zhuǎn)移到C4(現(xiàn)在是第三次)。現(xiàn)在可以對C4求值,完成該過程。
該所述計(jì)算方法會頻繁移動原計(jì)算鏈中的節(jié)點(diǎn),并導(dǎo)致C4公式冗余的兩次計(jì)算。特別的,對于C4=A4+B4+D4+E4+F4+G4+H4+I4,假設(shè)單元A4、B4、D4、E4、F4、G4、H4、I4都是“臟”的,則先把所有的單元節(jié)點(diǎn)移到單元C4前面,然后進(jìn)行計(jì)算,在計(jì)算過程中,每遇到一個“臟”的單元,則把該“臟”單元計(jì)算完成后再重新計(jì)算C4,當(dāng)遇到下一個“臟”單元時,前面的部分C4計(jì)算全部沒用,引用計(jì)算到I4時才發(fā)現(xiàn)I4是“臟的”,前面的累加白費(fèi)了,先算完I4再重來一遍,從而導(dǎo)致8次冗余計(jì)算。如果單元C4依賴更多的單元的話,所述節(jié)點(diǎn)的移動次數(shù)和冗余計(jì)算的次數(shù)則更多。對于極為復(fù)雜的電子數(shù)據(jù)表格,尤其在大型財(cái)務(wù)規(guī)劃方案中,以上述方式完成長鏈?zhǔn)接?jì)算需要大量的處理時間,也會造成計(jì)算機(jī)系統(tǒng)資源的大量浪費(fèi)。
因此,迫切需要一種對電子數(shù)據(jù)表進(jìn)行計(jì)算的方法和裝置,在對電子數(shù)據(jù)表的全部單元或部分單元進(jìn)行計(jì)算時,不需要頻繁的移動單元節(jié)點(diǎn),減少冗余計(jì)算的次數(shù)。
發(fā)明內(nèi)容
本發(fā)明所要解決的技術(shù)問題是提供一種電子數(shù)據(jù)表的計(jì)算方法和裝置,可以大大提高電子數(shù)據(jù)表整體或局部的計(jì)算速度。
為了解決上述問題,本發(fā)明公開了一種電子數(shù)據(jù)表計(jì)算的方法,包括以下步驟a、將待計(jì)算單元壓入堆棧;b、判斷該單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;c、對壓入堆棧的支持單元按步驟b求值,完成后將該支持單元彈出堆棧;d、重復(fù)步驟b、c,完成待計(jì)算單元的計(jì)算,并將該單元彈出堆棧。
依據(jù)另一實(shí)施例,還公開了一種電子數(shù)據(jù)表的計(jì)算方法,具體可以包括a、生成電子數(shù)據(jù)表的計(jì)算鏈;b、按計(jì)算鏈的順序進(jìn)行第一/下一單元的計(jì)算,將該待計(jì)算單元壓入堆棧;c、判斷該單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;d、對壓入堆棧的支持單元按步驟c求值,完成后將支持單元彈出堆棧;
e、重復(fù)步驟c、d,完成待計(jì)算單元的計(jì)算,將該單元彈出堆棧,并返回步驟b,直到該計(jì)算鏈所有單元都計(jì)算完成。
優(yōu)選的,步驟a所述電子數(shù)據(jù)表計(jì)算鏈的生成步驟包括a1、解析電子數(shù)據(jù)表各單元間的依賴關(guān)系;a2、向計(jì)算鏈添加第一單元;a3、根據(jù)依賴關(guān)系查詢該單元的依賴單元,將所述依賴單元添加到計(jì)算鏈的尾部;a4、根據(jù)依賴關(guān)系查詢新添加單元的依賴單元,將所述新添加單元的依賴單元添加到計(jì)算鏈的尾部;a5、重復(fù)步驟a4至計(jì)算鏈的最后一個單元;a6、按照預(yù)置的遍歷順序?qū)⑾乱粏卧砑拥接?jì)算鏈的尾部,對該單元按步驟a3、a4、a5完成計(jì)算鏈操作;a7、重復(fù)步驟a6,得到電子數(shù)據(jù)表的計(jì)算鏈。
進(jìn)一步,當(dāng)計(jì)算鏈中已經(jīng)存在要添加的單元時,不再添加該單元。
優(yōu)選的,所述方法進(jìn)一步可以包括預(yù)設(shè)所述堆棧的容量臨界值,當(dāng)壓入的單元個數(shù)達(dá)到臨界值要發(fā)生堆棧溢出錯誤時,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,按照新的計(jì)算鏈重新計(jì)算。
依據(jù)另一實(shí)施例,本發(fā)明還公開了一種電子數(shù)據(jù)表的計(jì)算裝置,可以包括堆棧,用于緩存電子數(shù)據(jù)表單元;判斷模塊,判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;計(jì)算模塊,對新壓入的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
依據(jù)另一實(shí)施例,本發(fā)明還公開了另一種電子數(shù)據(jù)表的計(jì)算裝置,可以包括堆棧,用于緩存電子數(shù)據(jù)表單元;計(jì)算鏈生成模塊,用于生成電子數(shù)據(jù)表的計(jì)算鏈;判斷模塊,判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;計(jì)算模塊,對新壓入的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
進(jìn)一步,該裝置還可以包括異常處理模塊,當(dāng)壓入堆棧的單元個數(shù)達(dá)到堆棧的預(yù)設(shè)容量臨界值時,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,生成新的計(jì)算鏈。
優(yōu)選的,所述的計(jì)算鏈生成模塊包括解析模塊,用于解析電子數(shù)據(jù)表各單元間的依賴關(guān)系;置入模塊,用于向計(jì)算鏈添加單元;查詢模塊,用于根據(jù)解析模塊查詢電子數(shù)據(jù)表中單元的依賴單元;生成模塊,用于調(diào)用置入模塊添加電子數(shù)據(jù)表第一單元至計(jì)算鏈中,調(diào)用查詢模塊查詢該單元的依賴單元,并再次調(diào)用置入模塊將所述依賴單元添加到計(jì)算鏈的尾部;以及,針對新添加單元的依賴單元重復(fù)調(diào)用查詢模塊和置入模塊,直到計(jì)算鏈的尾部;以及,針對電子數(shù)據(jù)表下一單元再次重復(fù)調(diào)用置入模塊、查詢模塊,得到電子數(shù)據(jù)表的計(jì)算鏈。
優(yōu)選的,對于計(jì)算鏈生成模塊,當(dāng)計(jì)算鏈中已經(jīng)存在要添加的單元時,不調(diào)用置入模塊添加該單元。
與現(xiàn)有技術(shù)相比,本發(fā)明具有以下優(yōu)點(diǎn)本發(fā)明在電子數(shù)據(jù)表的計(jì)算過程中增加了堆棧操作,當(dāng)電子數(shù)據(jù)表單元待計(jì)算時,將其壓入堆棧,如果該單元公式中的某一項(xiàng)具有待計(jì)算支持單元,則中斷該依賴單元的計(jì)算,先完成支持單元的計(jì)算,再根據(jù)支持單元的值完成該待計(jì)算依賴單元的計(jì)算。當(dāng)支持單元又依賴其它支持單元時,再次重復(fù)以上步驟,直至能夠完成待計(jì)算單元的計(jì)算。從而使所涉及的支持單元能夠在依賴單元之前完成計(jì)算,避免了在計(jì)算過程中單元節(jié)點(diǎn)的移動,并能夠避免冗余運(yùn)算,對電子數(shù)據(jù)表計(jì)算效率的提高明顯,節(jié)省了計(jì)算機(jī)系統(tǒng)資源。
進(jìn)一步,在對電子數(shù)據(jù)表進(jìn)行處理前,通過解析電子數(shù)據(jù)表各單元間的依賴關(guān)系,生成計(jì)算鏈,在該生成的計(jì)算鏈中,盡可能使被依賴單元位于依賴單元之前。生成計(jì)算鏈后,結(jié)合計(jì)算鏈和堆棧來完成電子數(shù)據(jù)表的計(jì)算,避免了在計(jì)算過程中單元節(jié)點(diǎn)的反復(fù)移動和冗余計(jì)算,大大提高電子數(shù)據(jù)表的計(jì)算效率,節(jié)省了計(jì)算機(jī)系統(tǒng)資源。
進(jìn)一步,在堆棧操作中,當(dāng)壓入堆棧的單元數(shù)將要超過堆棧的容量時,即將發(fā)生調(diào)用堆棧溢出錯誤時,通過設(shè)定堆棧容量的臨界值,主動拋出異常來拋棄當(dāng)前函數(shù)調(diào)用堆棧,并且將當(dāng)前堆棧中的單元倒序放到第一個求值單元之前,形成先計(jì)算被依賴者的計(jì)算順序,按照新的計(jì)算鏈重新完成待計(jì)算單元的計(jì)算,從而能夠順利的完成電子數(shù)據(jù)表的計(jì)算。
圖1是本發(fā)明實(shí)施例一種電子數(shù)據(jù)表計(jì)算方法的流程圖;圖2是本發(fā)明另一實(shí)施例一種電子數(shù)據(jù)表計(jì)算方法的流程圖;圖3是本發(fā)明實(shí)施例優(yōu)選的一種電子數(shù)據(jù)表計(jì)算鏈生成方法的流程圖;圖4是本發(fā)明實(shí)施例一種電子數(shù)據(jù)表計(jì)算裝置的結(jié)構(gòu)框圖;圖5是本發(fā)明實(shí)施例優(yōu)選的一種電子數(shù)據(jù)表計(jì)算鏈生成系統(tǒng)的結(jié)構(gòu)框圖;圖6是本發(fā)明另一實(shí)施例一種電子數(shù)據(jù)表計(jì)算裝置的結(jié)構(gòu)框圖。
具體實(shí)施例方式
為使本發(fā)明的上述目的、特征和優(yōu)點(diǎn)能夠更加明顯易懂,下面結(jié)合附圖和具體實(shí)施方式
對本發(fā)明作進(jìn)一步詳細(xì)的說明。
本發(fā)明的核心思想是在電子數(shù)據(jù)表的計(jì)算過程中采用堆棧操作,獲取支持單元的內(nèi)容的代碼方法中調(diào)用支持單元的計(jì)算方法。當(dāng)電子數(shù)據(jù)表單元待計(jì)算時,將其壓入堆棧,如果有支持單元待計(jì)算,則中斷該單元的計(jì)算,先完成支持單元的計(jì)算,再根據(jù)支持單元的值完成該待計(jì)算單元的計(jì)算。當(dāng)支持單元依賴其它支持單元時,再次重復(fù)以上步驟,直至能夠完成待計(jì)算單元的計(jì)算。從而使支持單元在依賴單元之前完成計(jì)算,避免了在計(jì)算過程中單元節(jié)點(diǎn)的反復(fù)移動,并能夠避免冗余運(yùn)算,對電子數(shù)據(jù)表計(jì)算效率的提高明顯,節(jié)省了計(jì)算機(jī)系統(tǒng)資源。本發(fā)明進(jìn)一步將電子數(shù)據(jù)表計(jì)算鏈的生成和堆棧操作結(jié)合在一起,即先構(gòu)建電子數(shù)據(jù)表中各單元間的依賴關(guān)系。然后按照一定的遍歷順序向計(jì)算鏈中添加支持單元,查詢該單元的依賴單元,將它們依次添加到計(jì)算鏈的尾部,從計(jì)算鏈中支持單元的第一個依賴單元開始,查詢該單元的依賴單元,將它們依次添加到計(jì)算鏈的尾部;如此循環(huán)直到計(jì)算鏈尾部,從而將直接和間接依賴于支持單元的所有單元都添加進(jìn)了計(jì)算鏈。按遍歷順序完成全部單元的添加,生成電子數(shù)據(jù)表的計(jì)算鏈。此時生成的整個計(jì)算鏈已經(jīng)基本上保持了支持單元先進(jìn)行計(jì)算的順序。生成計(jì)算鏈后,結(jié)合計(jì)算鏈和堆棧來完成電子數(shù)據(jù)表的計(jì)算。
通過本發(fā)明,把邊計(jì)算邊生成計(jì)算鏈的方法,優(yōu)化為先生成計(jì)算鏈,然后再根據(jù)該生成的計(jì)算鏈結(jié)合堆棧操作完成電子數(shù)據(jù)表的計(jì)算,避免在計(jì)算過程中單元節(jié)點(diǎn)的反復(fù)移動,并避免冗余運(yùn)算,大大節(jié)省了計(jì)算機(jī)系統(tǒng)資源,提高了電子數(shù)據(jù)表的計(jì)算速度。
本發(fā)明可用于眾多通用或?qū)S玫挠?jì)算系統(tǒng)環(huán)境或配置中。例如個人計(jì)算機(jī)、服務(wù)器計(jì)算機(jī)、手持設(shè)備或便攜式設(shè)備、平板型設(shè)備、多處理器系統(tǒng)、基于微處理器的系統(tǒng)、置頂盒、可編程的消費(fèi)電子設(shè)備、網(wǎng)絡(luò)PC、小型計(jì)算機(jī)、大型計(jì)算機(jī)、包括以上任何系統(tǒng)或設(shè)備的分布式計(jì)算環(huán)境等等。
本發(fā)明可以在由計(jì)算機(jī)執(zhí)行的計(jì)算機(jī)可執(zhí)行指令的一般上下文中描述,例如程序模塊。一般地,程序模塊包括執(zhí)行特定任務(wù)或?qū)崿F(xiàn)特定抽象數(shù)據(jù)類型的例程、程序、對象、組件、數(shù)據(jù)結(jié)構(gòu)等等。也可以在分布式計(jì)算環(huán)境中實(shí)踐本發(fā)明,在這些分布式計(jì)算環(huán)境中,由通過通信網(wǎng)絡(luò)而被連接的遠(yuǎn)程處理設(shè)備來執(zhí)行任務(wù)。在分布式計(jì)算環(huán)境中,程序模塊可以位于包括存儲設(shè)備在內(nèi)的本地和遠(yuǎn)程計(jì)算機(jī)存儲介質(zhì)中。
本發(fā)明所述的電子數(shù)據(jù)表的計(jì)算方法可以用于完成對電子數(shù)據(jù)表部分區(qū)域單元或單個單元的計(jì)算,還可以用于整張電子數(shù)據(jù)表的計(jì)算。
參照圖1,示出了本發(fā)明一種電子數(shù)據(jù)表計(jì)算方法的流程圖,包括以下步驟步驟101、將待計(jì)算單元壓入堆棧。
許多處理系統(tǒng)具有存儲器模塊,在存儲器模塊中實(shí)現(xiàn)了堆棧。一個堆棧是一個數(shù)據(jù)結(jié)構(gòu)?;凶罱槐4娴囊粋€值被首先檢索出來。有兩個與一個堆棧相關(guān)的基本操作——一個壓入操作,其中一個新的值被添加到堆棧中,和一個彈出操作,其中檢索位于堆棧頂部的值。新的值被保存在堆棧頂部后面的一個存儲器地址中。一般在中斷中使用堆棧操作。在本發(fā)明中,所述值為電子數(shù)據(jù)表單元,通過堆棧實(shí)現(xiàn)待計(jì)算單元的中斷操作。
步驟102、判斷該單元公式的第一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)直接求值。
電子數(shù)據(jù)表通常由多個單元組成,這些單元相互之間有可能存在相互依賴的關(guān)系。如單元公式C4=A4+B4,單元C4依賴于單元A4和單元B4,則所述單元C4為依賴單元,所述單元A4、B4為支持單元,A4+B4是單元C4的單元公式,其中A4是單元公式的第一項(xiàng),B4是單元公式的第二/下一項(xiàng),所述單元公式的項(xiàng)可以包括單元項(xiàng),也可以包括常數(shù)或其他公式,本發(fā)明并不對此限定。單元A4、B4的公式是支持公式,A4+B4是依賴公式。在電子數(shù)據(jù)表中,依賴單元和支持單元并不是固定的,是可以相互轉(zhuǎn)化的,即依賴單元可能是其他單元的支持單元。如D4=C4+E4中,C4則是支持單元,D4是依賴單元。因此,在電子數(shù)據(jù)表中存在這樣一種情況,一個支持單元的依賴單元是另一單元的支持單元。因?yàn)橐蕾噯卧蕾囉谥С謫卧栽陔娮訑?shù)據(jù)表的計(jì)算等處理過程中,應(yīng)該先對支持單元進(jìn)行處理,當(dāng)依賴單元的所有支持單元都處理后才能完成依賴單元的處理。
如果壓入堆棧單元的單元公式的第一項(xiàng)依賴于其他單元,即該單元的值也是待計(jì)算時,則把該單元也壓入堆棧。如果單元公式的第一項(xiàng)不是待計(jì)算單元,即該單元的值不需要計(jì)算即可以得到結(jié)果或者該單元的值是常數(shù)值時,則直接計(jì)算得到該結(jié)果值。
步驟103、判斷步驟102中壓入堆棧的單元是否還具有待計(jì)算支持單元,并按步驟102的步驟對該單元進(jìn)行處理。
對于一個電子數(shù)據(jù)表單元來說,有可能存在這樣的一種情況,單元間引用的嵌套層數(shù)比較多,如A單元引用B單元、B單元引用C單元、C單元引用D單元,在這樣的情況中,單元A、B、C都是待計(jì)算單元。對于這種情況,本發(fā)明先把A壓入堆棧,發(fā)現(xiàn)A單元待計(jì)算,且依賴于B單元,則再把B單元壓入堆棧,又發(fā)現(xiàn)B單元待計(jì)算,且依賴于C單元,則再把C單元壓入堆棧,C單元也待計(jì)算,且依賴于D單元,最后才發(fā)現(xiàn)D單元不是待計(jì)算單元,其值不需要計(jì)算就可直接得到,則通過D單元完成C單元的計(jì)算,并把C單元彈出堆棧,通過C單元完成B單元的計(jì)算,并把B單元彈出堆棧,最后通過B單元完成A單元的計(jì)算,將單元A彈出堆棧,從而通過堆棧完成了待計(jì)算單元A的計(jì)算。一直重復(fù)該步驟,從而對單元公式的項(xiàng)完成求值。
按步驟102、103完成待計(jì)算單元公式第一項(xiàng)的求值后,進(jìn)行待計(jì)算單元公式下一項(xiàng)的求值,所述求值過程與步驟102、103相同,在此不再詳述。
步驟104、完成待計(jì)算單元的計(jì)算,并將該單元彈出堆棧。
在步驟102、103中,待計(jì)算單元公式的各項(xiàng)的值都已經(jīng)計(jì)算完成,根據(jù)各項(xiàng)的值完成該待計(jì)算單元的求值,并在求值完成后將該待計(jì)算單元彈出堆棧。
下面以一個例子對上述方法流程進(jìn)行詳細(xì)描述。
按照C4=A4+B4這個例子第一步、將C4壓入計(jì)算單元堆棧,開始公式計(jì)算;第二步、計(jì)算到引用A4內(nèi)容時發(fā)現(xiàn)A4待計(jì)算,將A4壓入計(jì)算單元堆棧,計(jì)算完成A4,將A4彈出計(jì)算單元堆棧,去除A4“待計(jì)算”標(biāo)志,繼續(xù)C4計(jì)算;第三步、計(jì)算到引用B4內(nèi)容時發(fā)現(xiàn)B4待計(jì)算,將B4壓入計(jì)算單元堆棧,計(jì)算完成B4,將B4彈出計(jì)算單元堆棧,去除B4“待計(jì)算”標(biāo)志,繼續(xù)C4計(jì)算;第四步、C4計(jì)算完成,將C4彈出計(jì)算單元堆棧,去除C4“待計(jì)算”標(biāo)志。
從總體上講,本發(fā)明方法避免了單元節(jié)點(diǎn)在計(jì)算過程中的移動和冗余計(jì)算,提高了計(jì)算效率。本發(fā)明方法在電子數(shù)據(jù)表計(jì)算過程中增加了計(jì)算單元堆棧操作,相對于單元公式冗余計(jì)算的耗用來講,代價(jià)是非常輕微的,電子數(shù)據(jù)表的整體計(jì)算效率有顯著提升。
進(jìn)一步,對于上述利用堆?!矮@取被引用單元的內(nèi)容的代碼方法中調(diào)用被引用單元的計(jì)算方法”完成電子數(shù)據(jù)表單元的計(jì)算,如果引用的嵌套層數(shù)比較多,如A引用B、B引用C、C引用D……到引用N,會發(fā)生函數(shù)調(diào)用堆棧溢出錯誤。對于這種狀況,通過設(shè)定計(jì)算單元堆棧容量臨界值, 主動拋出異常來解決。譬如如果引用嵌套510層會發(fā)生函數(shù)調(diào)用堆棧溢出錯誤,那就設(shè)定計(jì)算單元堆棧容量臨界值為500,當(dāng)堆棧要超出容量時,主動拋出異常,將函數(shù)調(diào)用返回到第一個求值單元A處。在異常處理中將當(dāng)前計(jì)算單元堆棧中的單元倒序放到第一個求值單元A之前,從而形成了先計(jì)算被依賴者的計(jì)算順序,可以繼續(xù)正常計(jì)算。
參照圖2,示出了本發(fā)明一種電子數(shù)據(jù)表計(jì)算方法的流程圖,與圖1所示方法的區(qū)別在于本方法是結(jié)合計(jì)算鏈和堆棧完成電子數(shù)據(jù)表的計(jì)算。包括步驟步驟201、生成電子數(shù)據(jù)表的計(jì)算鏈。
電子數(shù)據(jù)表計(jì)算鏈的生成方法有很多,如按電子數(shù)據(jù)表中各單元的順序生成電子數(shù)據(jù)表的計(jì)算鏈,所述順序可以是先行后列或先列后行;邊計(jì)算邊生成計(jì)算鏈也是電子數(shù)據(jù)表計(jì)算鏈生成方法的一種,至于采用何種方法生成電子數(shù)據(jù)表的計(jì)算鏈,本發(fā)明并不對此進(jìn)行限定。為了提高電子數(shù)據(jù)表的計(jì)算效率,本發(fā)明優(yōu)先采用計(jì)算鏈生成方法的原理是先構(gòu)建電子數(shù)據(jù)表中各單元間的依賴關(guān)系,構(gòu)建各單元間的依賴關(guān)系在不同的電子數(shù)據(jù)表的實(shí)現(xiàn)方式不同,但原理是相似的當(dāng)一個單元內(nèi)容發(fā)生變化時要通知依賴此單元的其他單元,并更新各自的內(nèi)容。然后按照一定的遍歷順序向計(jì)算鏈中添加支持單元,查詢該單元的依賴單元,將它們依次添加到計(jì)算鏈的尾部,從計(jì)算鏈中支持單元的第一個依賴單元開始,查詢該單元的依賴單元,將它們依次添加到計(jì)算鏈的尾部;如此循環(huán)直到計(jì)算鏈尾部,從而將直接和間接依賴于支持單元的所有單元都添加進(jìn)了計(jì)算鏈。按遍歷順序完成全部單元的添加,生成電子數(shù)據(jù)表的計(jì)算鏈。此時生成的整個計(jì)算鏈已經(jīng)基本上保持了支持單元先進(jìn)行計(jì)算的順序。
步驟202、按計(jì)算鏈的順序進(jìn)行第一/下一單元的計(jì)算,將該待計(jì)算單元壓入堆棧。
按生成計(jì)算鏈中的各單元的順序?qū)⒌谝?下一單元壓入堆棧,如果計(jì)算鏈中的第一/下一單元能直接完成計(jì)算,則在完成計(jì)算后彈出該單元,如果計(jì)算鏈中的單元具有支持單元,不能直接完成計(jì)算,則轉(zhuǎn)入步驟203。
步驟203、判斷該單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值。
電子數(shù)據(jù)表通常由多個單元組成,這些單元相互之間有可能存在相互依賴的關(guān)系。
如果壓入堆棧單元的單元公式的第一項(xiàng)依賴于其他單元,即該單元的值也是待計(jì)算時,則把該單元也壓入堆棧。如果單元公式的第一項(xiàng)不是待計(jì)算單元,即該單元的值不需要計(jì)算即可以得到結(jié)果或者該單元的值是常數(shù)值時,則直接計(jì)算得到該結(jié)果值。
步驟204、判斷步驟203中壓入堆棧的單元是否還具有待計(jì)算支持單元,并按步驟203的方法對該單元進(jìn)行處理。
對于一個電子數(shù)據(jù)表單元來說,有可能存在這樣的一種情況,單元間引用的嵌套層數(shù)比較多,如A單元引用B單元、B單元引用C單元、C單元引用D單元,在這樣的情況中,單元A、B、C都是待計(jì)算單元。對于這種情況,本發(fā)明先把A壓入堆棧,發(fā)現(xiàn)A單元待計(jì)算,且依賴于B單元,則再把B單元壓入堆棧,又發(fā)現(xiàn)B單元待計(jì)算,且依賴于C單元,則再把C單元壓入堆棧,C單元也待計(jì)算,且依賴于D單元,最后才發(fā)現(xiàn)D單元不是待計(jì)算單元,其值不需要計(jì)算就可直接得到,則通過D單元完成C單元的計(jì)算,并把C單元彈出堆棧,通過C單元完成B單元的計(jì)算,并把B單元彈出堆棧,最后通過B單元完成A單元的計(jì)算,將單元A彈出堆棧,從而通過堆棧完成了待計(jì)算單元A的計(jì)算。一直重復(fù)該步驟,從而對單元公式的項(xiàng)完成求值。
按步驟203、204完成待計(jì)算單元公式第一項(xiàng)的求值后,進(jìn)行待計(jì)算單元公式下一項(xiàng)的求值,所述求值過程與步驟203、204相同,在此不再詳述。
步驟205、完成待計(jì)算單元的計(jì)算,并將該單元彈出堆棧。
在步驟203、204中,待計(jì)算單元公式的各項(xiàng)的值都已經(jīng)計(jì)算完成,根據(jù)各項(xiàng)的值完成該待計(jì)算單元的求值,并在求值完成后將該待計(jì)算單元彈出堆棧。完成該待計(jì)算單元的計(jì)算后,對下一單元,返回步驟202,開始新一單元的計(jì)算。當(dāng)電子數(shù)據(jù)表中所有單元都計(jì)算完成后,則不再返回步驟202。結(jié)束電子數(shù)據(jù)表的計(jì)算。
進(jìn)一步,根據(jù)完成的電子數(shù)據(jù)表各單元的計(jì)算結(jié)果完成電子數(shù)據(jù)表全部或指定部分的計(jì)算。
進(jìn)一步,對于上述利用堆棧完成電子數(shù)據(jù)表的計(jì)算,如果引用的嵌套層數(shù)比較多而發(fā)生堆棧計(jì)算溢出的情形。通過設(shè)定計(jì)算單元堆棧容量臨界值,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,生成新的計(jì)算鏈的方法來解決堆棧溢出的錯誤。
如a1=a2,a2=a3,a3=a4,……,a1000=a1001,計(jì)算鏈相應(yīng)為{a1,a2,a3,…,a1001}。
如果開始計(jì)算a1的話,會導(dǎo)致壓棧a1(a2(a3(…(a1001)))),這實(shí)際是個函數(shù)壓棧調(diào)用過程,對于現(xiàn)有計(jì)算環(huán)境,函數(shù)調(diào)用棧大小是有限制的,可能會發(fā)生超出調(diào)用棧導(dǎo)致棧溢出異常。
在這種情況下,設(shè)定堆棧容量臨界值,主動捕獲堆棧異常。如計(jì)算在510級時會發(fā)生堆棧溢出,則主動將堆棧容量臨界值設(shè)為500。a1(a2(a3(…(a500))))時到達(dá)限值,這時停止當(dāng)前單元格a1的計(jì)算,將堆棧中的各單元反序插入到計(jì)算鏈的當(dāng)前節(jié)點(diǎn)a1前,從而原計(jì)算鏈變?yōu)閧a500,a499,…,a1,a501,a502,…,a1001},從a500開始計(jì)算又會發(fā)生剛才a1計(jì)算的情形,再次將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,再次調(diào)整計(jì)算鏈為{a1000,a999,…,a1,a1001},從a1000開始計(jì)算,這時整個計(jì)算鏈可以順利完成計(jì)算了。
本方法所述的在對電子數(shù)據(jù)表進(jìn)行處理前,通過解析電子數(shù)據(jù)表各單元間的依賴關(guān)系,生成計(jì)算鏈,在該生成的計(jì)算鏈中,盡可能使被依賴單元位于依賴單元之前。生成計(jì)算鏈后,計(jì)算鏈結(jié)合堆棧來完成電子數(shù)據(jù)表的計(jì)算,避免了在計(jì)算過程中單元節(jié)點(diǎn)的反復(fù)移動和冗余計(jì)算,大大提高電子數(shù)據(jù)表的計(jì)算效率,節(jié)省了計(jì)算機(jī)系統(tǒng)資源。
參照圖3,示出了本發(fā)明優(yōu)選實(shí)施例一種電子數(shù)據(jù)表計(jì)算鏈生成方法的流程圖,包括步驟步驟301、構(gòu)建各單元間的依賴關(guān)系。
電子數(shù)據(jù)表通常由多個單元組成,這些單元相互之間有可能存在相互依賴的關(guān)系。如單元公式C4=A4+B4,單元C4依賴于單元A4和單元B4,則所述單元c4為依賴單元,所述單元A4、B4為支持單元。在電子數(shù)據(jù)表中,依賴單元和支持單元并不是固定的,是可以相互轉(zhuǎn)化的,即依賴單元在其他公式中可能就是支持單元了。如D4=C4+E4中,C4是支持單元,D4是依賴單元。因此,在電子數(shù)據(jù)表中存在這樣一種情況,一個支持單元的依賴單元是另一單元的支持單元。因?yàn)橐蕾噯卧蕾囉谥С謫卧?,所以在電子?shù)據(jù)表的計(jì)算等處理過程中,都是對支持單元先進(jìn)行處理,當(dāng)依賴單元的所有支持單元都處理后才能完成依賴單元的處理。
根據(jù)電子數(shù)據(jù)表各單元的關(guān)系構(gòu)建依賴關(guān)系,所述構(gòu)建的原則是使支持單元在計(jì)算鏈中盡量位于依賴單元之前。對電子數(shù)據(jù)表中的單元構(gòu)建這樣的依賴關(guān)系有多種可實(shí)現(xiàn)的方法,如遍歷所有單元,解析語法樹,生成一個包含依賴關(guān)系的數(shù)據(jù)結(jié)構(gòu)。具體來說,對于C4=A4+B4,首先A4、B4是單元C4的支持單元,C4是依賴單元,解析A4、B4生成語法樹的過程中,公式解析器識別了被依賴者A4和B4,從而建立依賴關(guān)系。
所述依賴關(guān)系數(shù)據(jù)結(jié)構(gòu)的要求是可用電子數(shù)據(jù)表的單元作為“鍵值”來高效查詢,用哈希表或者排序數(shù)組都可實(shí)現(xiàn)。單元的“鍵值”所指向的“值域”是個集合,用來包含依賴單元。
步驟302、向計(jì)算鏈中添加第一單元。
步驟303、查詢該單元的依賴單元,將所述依賴單元添加到計(jì)算鏈的尾部。
在步驟301中已經(jīng)構(gòu)建好電子數(shù)據(jù)表中各單元間的依賴關(guān)系,因此,在本步驟中,以單元的“鍵值”或其他方法在依賴關(guān)系中進(jìn)行查詢即可得到該單元的依賴單元??紤]計(jì)算效率,步驟301中解析生成的單元語法樹和構(gòu)建的依賴關(guān)系需要緩存。一般會在文件打開時構(gòu)建單元語法樹。不一定要構(gòu)建所有單元的語法樹,在特別情況下,只構(gòu)建當(dāng)前活動表頁的,其它表頁的采用懶惰模式構(gòu)建?;蛘邔⒄Z法樹、依賴關(guān)系保存在了文件里,直接加載即可。因此,通過構(gòu)建的所述依賴關(guān)系數(shù)據(jù)結(jié)構(gòu),可以很容易的查詢到各個單元的依賴單元。在電子數(shù)據(jù)表中,一個單元的依賴單元通常有多個,如果是多個依賴單元,則將該多個依賴單元依次添加到計(jì)算鏈該支持單元的后面。
步驟304、查詢該新添加單元的依賴單元、將所述新添加單元的依賴單元添加到計(jì)算鏈的尾部。
該新添加的單元雖然是前一個支持單元的依賴單元,但在電子數(shù)據(jù)表中,它可能是其他單元的支持單元,根據(jù)依賴關(guān)系查詢該新添加單元的依賴單元、將所述新添加單元的依賴單元添加到計(jì)算鏈的尾部。
當(dāng)添加的單元有多個時,對每一個新添加的單元都重復(fù)步驟304,即從計(jì)算鏈緊接支持單元之后的單元開始,查詢依賴于此單元的依賴單元,將它們依次添加到計(jì)算鏈的尾部;如此循環(huán)直到計(jì)算鏈的尾部。這樣就將直接和間接依賴于支持單元的所有單元都添加進(jìn)了計(jì)算鏈。
步驟305、按照預(yù)置的遍歷順序?qū)⑾乱粏卧砑拥接?jì)算鏈的尾部,重復(fù)步驟304、305,將該支持單元的所有直接依賴和間接依賴單元都添加到計(jì)算鏈。
所述遍歷順序是可以是先行后列,也可以是先列后行,采用什么樣的遍歷順序?qū)Ρ痉椒o影響,對此也不加以限制。
進(jìn)一步,當(dāng)要添加的單元已經(jīng)被添加到計(jì)算鏈中時,則不再向計(jì)算鏈中添加該單元。因?yàn)殡娮訑?shù)據(jù)表的單元是一個實(shí)現(xiàn)了“可計(jì)算接口”的小對象,可計(jì)算接口的其中一個方法就是設(shè)置“已添加”標(biāo)記,所以在將單元添加到計(jì)算鏈中時,對該單元做“已添加”標(biāo)記表明此單元已加入計(jì)算鏈,當(dāng)有相同的單元要添加時,通過該“已添加”標(biāo)志就可以實(shí)現(xiàn)不再重復(fù)添加。從而能夠節(jié)省系統(tǒng)資源,也能提高效率。此時整個計(jì)算鏈已經(jīng)基本上保持了被依賴單元先進(jìn)行處理的順序。
進(jìn)一步,對于生成的計(jì)算鏈,可以采用數(shù)組或鏈表的方式進(jìn)行存儲,無論采用哪種方式,在訪問效率、插入操作和內(nèi)存占用成本上都各有千秋。當(dāng)然也可以采用其它的方式對計(jì)算鏈進(jìn)行存儲,并不對此進(jìn)行限定。
下面以一個具體的電子數(shù)據(jù)表詳細(xì)說明現(xiàn)有技術(shù)的計(jì)算方法和本發(fā)明的計(jì)算方法。以及本發(fā)明所述方法與現(xiàn)在技術(shù)計(jì)算方法的有益效果。
所述電子數(shù)據(jù)表為
現(xiàn)有技術(shù)完成該電子數(shù)據(jù)表計(jì)算的方法計(jì)算鏈構(gòu)造與計(jì)算同步進(jìn)行,按照先行后列的順序訪問上列單元第一步、按照行列循環(huán),計(jì)算A1,計(jì)算鏈{A1};A1依賴B3,停止計(jì)算A1,將A1的支持者B3加入計(jì)算鏈A1前,計(jì)算鏈為{B3,A1};第二步、計(jì)算B3;計(jì)算A1;第三步、按照行列循環(huán),計(jì)算B1,計(jì)算鏈{B3,A1,B1};B1依賴C3,停止計(jì)算B1,將B1的支持者C3加入計(jì)算鏈B1前,計(jì)算鏈為{B3,A1,C3,B1};第四步、計(jì)算C3;計(jì)算B1;第五步、按照行列循環(huán),計(jì)算C1,計(jì)算鏈{B3,A1,C3,B1,C1};支持者A1,B1都已計(jì)算完成,C1計(jì)算完成;
第六步、按照行列循環(huán),計(jì)算B2,計(jì)算鏈{B3,A1,C3,B1,C1,B2};支持者B1已計(jì)算完成,B2計(jì)算完成;第七步、按照行列循環(huán),計(jì)算B3,B3剛已計(jì)算過;第八步、按照行列循環(huán),計(jì)算C3,C3剛已計(jì)算過;第九步、計(jì)算全部完成,計(jì)算鏈也構(gòu)造完成{B3,A1,C3,B1,C1,B2}本發(fā)明完成該電子數(shù)據(jù)表計(jì)算的方法先構(gòu)建電子數(shù)據(jù)表的計(jì)算鏈按照先行后列的順序訪問上列單元,組織計(jì)算鏈時考慮當(dāng)前單元的依賴者,[]內(nèi)為當(dāng)前單元第一步、按照行列循環(huán),將A1加入計(jì)算鏈{A1};第二步、[A1]將A1的依賴者[B1,C1,C3]加入計(jì)算鏈{A1,B1,C1,C3};從B1開始,按照計(jì)算鏈順序循環(huán)至計(jì)算鏈結(jié)束;第三步、[B1]試圖將B1的依賴者C1加入計(jì)算鏈,但C1已在計(jì)算鏈中,不再添加;第四步、[B1]將B1的依賴者B2加入計(jì)算鏈{A1,B1,C1,C3,B2};第五步、[C1]C1無依賴者;第六步、[C3]試圖將C3的依賴者B1加入計(jì)算鏈,但B1已在計(jì)算鏈中,不再添加;第七步、[B2]B2無依賴者;第八步、按照行列循環(huán),試圖將B1加入計(jì)算鏈,但B1已在計(jì)算鏈中,不再添加;第九步、按照行列循環(huán),試圖將C1加入計(jì)算鏈,但C1已在計(jì)算鏈中,不再添加;第十步、按照行列循環(huán),試圖將A2加入計(jì)算鏈,但A2是常量無需計(jì)算,不再添加;第十一步、按照行列循環(huán),試圖將B2加入計(jì)算鏈,但B2已在計(jì)算鏈中,不再添加;第十二步、按照行列循環(huán),試圖將C2加入計(jì)算鏈,但C2是常量無需計(jì)算,不再添加;第十三步、按照行列循環(huán),試圖將A3加入計(jì)算鏈,但A3是常量無需計(jì)算,不再添加;第十四步、按照行列循環(huán),將B3加入計(jì)算鏈{A1,B1,C1,C3,B2,B3};第十五步、[B3]試圖將B3的依賴者A1加入計(jì)算鏈,但A1已在計(jì)算鏈中,不再添加;第十六步、按照行列循環(huán),試圖將C3加入計(jì)算鏈,但C3已在計(jì)算鏈中,不再添加;第十七步、行列循環(huán)完成,生成該電子數(shù)據(jù)表的計(jì)算鏈,最終結(jié)果{A1,B1,C1,C3,B2,B3}。
根據(jù)計(jì)算鏈,應(yīng)用堆棧完成電子數(shù)據(jù)表的計(jì)算1、計(jì)算A1A1待計(jì)算,中斷A1的計(jì)算,將A1壓入堆棧;A1依賴于單元B3,且B3待計(jì)算,中斷B3計(jì)算,將B3壓入堆棧;B3依賴于A3,根據(jù)A3的值完成B3的計(jì)算,將B3彈出堆棧,根據(jù)B3的值完成A1的計(jì)算,將A1彈出堆棧。
2、計(jì)算B1B1待計(jì)算,中斷B1的計(jì)算,將B1壓入堆棧;B1依賴于單元A1和C3,A1不需計(jì)算;計(jì)算C3,C3待計(jì)算,中斷C3的計(jì)算,壓入堆棧。C3依賴于A1和A3,A1不需計(jì)算,A3不需計(jì)算,根據(jù)A1、A3完成C3的計(jì)算,彈出堆棧;根據(jù)C3和A1完成B1的計(jì)算,并將B1彈出堆棧。
3、計(jì)算C1C1待計(jì)算,中斷C1的計(jì)算,將C1壓入堆棧;C1依賴于A1和B3,A1不需計(jì)算,B1不需計(jì)算,C2不需計(jì)算,根據(jù)A1、B1、C2完成C1的計(jì)算,并將C1彈出堆棧。
4、計(jì)算C3C3待計(jì)算,中斷C3的計(jì)算,將C3壓入堆棧;C3依賴于A1、A3,A1不需計(jì)算,A3不需計(jì)算,根據(jù)A1、A3完成C3的計(jì)算,并將C3彈出堆棧。
5、計(jì)算B2B2待計(jì)算,中斷B2的計(jì)算,將B2壓入堆棧;B2依賴于B1,B1不需計(jì)算,根據(jù)B1完成B2的計(jì)算,將將B2彈出堆棧;6、計(jì)算B3B3待計(jì)算,中斷B3的計(jì)算,將B3壓入堆棧;B3依賴于A3,A3不需計(jì)算,根據(jù)A3完成B3的計(jì)算,將將B3彈出堆棧。計(jì)算全部完成。
通過上述計(jì)算過程可以很清楚的發(fā)現(xiàn),現(xiàn)有方法進(jìn)行了8次計(jì)算,其中有2次重復(fù)計(jì)算,本發(fā)明只進(jìn)行了6次計(jì)算,沒有重復(fù)計(jì)算。
進(jìn)一步,對于更為復(fù)雜的計(jì)算來說,采用現(xiàn)有技術(shù)所述方法會有更多的重復(fù)計(jì)算,如A1=B1+C1+D1+E1,根據(jù)現(xiàn)有技術(shù)完成計(jì)算第一步、計(jì)算A1,計(jì)算鏈{A1};A1依賴B1,停止計(jì)算A1,將A1的被依賴者B1加入計(jì)算鏈A1前,計(jì)算鏈為{B1,A1};第二步、計(jì)算B1;第三步、計(jì)算A1,A1依賴C1,停止計(jì)算A1,將A1的被依賴者C1加入計(jì)算鏈A1前,計(jì)算鏈為{B1,C1,A1};第四步、計(jì)算C1;第五步、計(jì)算A1,A1依賴D1,停止計(jì)算A1,將A1的被依賴者D1加入計(jì)算鏈A1前,計(jì)算鏈為{B1,C1,D1,A1};第六步、計(jì)算D1;第七步、計(jì)算A1,A1依賴E1,停止計(jì)算A1,將A1的被依賴者E1加入計(jì)算鏈A1前,計(jì)算鏈為{B1,C1,D1,E1,A1};第八步、計(jì)算E1;第九步、計(jì)算A1,完成計(jì)算。
可見A1共計(jì)算了5次,其中重復(fù)計(jì)算了4次。本發(fā)明應(yīng)用堆棧式計(jì)算,沒有重復(fù)計(jì)算。
因?yàn)楸景l(fā)明把邊計(jì)算邊生成計(jì)算鏈的方法,優(yōu)化為先生成計(jì)算鏈,然后再根據(jù)該生成的計(jì)算鏈完成電子數(shù)據(jù)表的計(jì)算,并且進(jìn)一步結(jié)合堆棧,完成電子數(shù)據(jù)表的計(jì)算,這樣避免了在計(jì)算過程中單元節(jié)點(diǎn)的反復(fù)移動,并能夠減少冗余運(yùn)算,利用生成的計(jì)算鏈結(jié)合堆棧對電子數(shù)據(jù)表進(jìn)行計(jì)算時效率有明顯的提高,并大大節(jié)省了計(jì)算機(jī)系統(tǒng)資源。
參照圖4、示出了本發(fā)明一種電子數(shù)據(jù)表計(jì)算裝置的結(jié)構(gòu)框圖,包括堆棧401、用于緩存電子數(shù)據(jù)表單元。
許多處理系統(tǒng)具有存儲器模塊,在存儲器模塊中實(shí)現(xiàn)了堆棧。一個堆棧是一個數(shù)據(jù)結(jié)構(gòu)。基中最近被保存的一個值被首先檢索出來。有兩個與一個堆棧相關(guān)的基本操作——一個壓入操作,其中一個新的值被添加到堆棧中,和一個彈出操作,其中檢索位于堆棧頂部的值。新的值被保存在堆棧頂部后面的一個存儲器地址中。一般在中斷中使用堆棧操作。在本發(fā)明中,所述值為電子數(shù)據(jù)表單元,通過堆棧實(shí)現(xiàn)待計(jì)算單元的中斷操作。
判斷模塊402、用于判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值。
如果壓入堆棧單元的單元公式的第一項(xiàng)/下一項(xiàng)具有待計(jì)算支持單元,即該單元的值也是待計(jì)算時,則把該單元也壓入堆棧。如果單元公式的第一項(xiàng)/下一項(xiàng)不是待計(jì)算單元,即該單元的值不需要計(jì)算即可以得到結(jié)果或者該單元的值是常數(shù)值時,則直接計(jì)算得到該結(jié)果值。
計(jì)算模塊403、用于對新壓入堆棧的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
當(dāng)壓入堆棧的單元還是依賴其它單元時,則對該單元再次重復(fù)調(diào)用判斷模塊,直至所述單元各項(xiàng)的值都完成計(jì)算,根據(jù)各項(xiàng)的值完成待計(jì)算單元的計(jì)算。
參照圖5,示出了本發(fā)明優(yōu)選實(shí)施例一種電子數(shù)據(jù)表計(jì)算鏈生成系統(tǒng)的結(jié)構(gòu)框圖,包括解析模塊501、用于解析電子數(shù)據(jù)表各單元間的依賴關(guān)系。
根據(jù)電子數(shù)據(jù)表各單元的關(guān)系構(gòu)建依賴關(guān)系,所述構(gòu)建的原則是使支持單元在計(jì)算鏈中盡量位于依賴單元之前。對電子數(shù)據(jù)表中的單元構(gòu)建這樣的依賴關(guān)系有多種可實(shí)現(xiàn)的方法,如遍歷所有單元,解析語法樹,生成一個包含依賴關(guān)系的數(shù)據(jù)結(jié)構(gòu)。所述依賴關(guān)系數(shù)據(jù)結(jié)構(gòu)的要求是可用電子數(shù)據(jù)表的單元作為“鍵值”來高效查詢,用哈希表或者排序數(shù)組都可實(shí)現(xiàn)。單元的“鍵值”所指向的“值域”是個集合,用來包含依賴單元。
置入模塊502、用于向計(jì)算鏈添加單元。
查詢模塊503、根據(jù)解析模塊查詢電子數(shù)據(jù)表中單元的依賴單元。
以單元的“鍵值”或其他方法在依賴關(guān)系中進(jìn)行查詢即可得到該單元的依賴單元。
計(jì)算鏈生成模塊504、調(diào)用置入模塊添加第一單元至計(jì)算鏈中,調(diào)用查詢模塊查詢該單元的依賴單元,并再次調(diào)用置入模塊將所述依賴單元添加到計(jì)算鏈的尾部,對新添加的單元,重復(fù)調(diào)用查詢模塊和置入模塊添加該新添加單元的依賴單元,直到計(jì)算鏈的尾部,這樣就將直接和間接依賴于支持單元的所有單元都添加進(jìn)了計(jì)算鏈。對下一單元再次重復(fù)調(diào)用置入模塊、查詢模塊,生成電子數(shù)據(jù)表的計(jì)算鏈。
進(jìn)一步,當(dāng)要添加的單元已經(jīng)被添加到計(jì)算鏈中時,則不再向計(jì)算鏈中添加該單元。因?yàn)殡娮訑?shù)據(jù)表的單元是一個實(shí)現(xiàn)了“可計(jì)算接口”的小對象,可計(jì)算接口的其中一個方法就是設(shè)置“已添加”標(biāo)記,所以在將單元添加到計(jì)算鏈中時,對單元做“已添加”標(biāo)記表明此單元已加入計(jì)算鏈,從而當(dāng)有相同的單元要添加時,通過該“已添加”標(biāo)志就可以實(shí)現(xiàn)不再重復(fù)添加。從而能夠節(jié)省系統(tǒng)資源,也能提高效率。此時整個計(jì)算鏈已經(jīng)基本上保持了被依賴單元先進(jìn)行計(jì)算的順序。
進(jìn)一步,對于生成的計(jì)算鏈,采用數(shù)組或鏈表的方式進(jìn)行存儲,無論采用哪種方式,在訪問效率、插入操作和內(nèi)存占用成本上都各有千秋。當(dāng)然也可以采用其它的方式對計(jì)算鏈進(jìn)行存儲,并不對此進(jìn)行限定。
參照圖6、示出了本發(fā)明一種電子數(shù)據(jù)表計(jì)算裝置的結(jié)構(gòu)框圖,包括堆棧601,用于緩存電子數(shù)據(jù)表單元。
計(jì)算鏈生成模塊602,用于生成電子數(shù)據(jù)表的計(jì)算鏈。
堆棧和計(jì)算鏈生成模塊在圖4、圖5所示的裝置和系統(tǒng)中已有詳細(xì)的描述,在此不再詳述,參照前面即可。
判斷模塊603、用于判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該依賴單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值。
如果壓入堆棧單元的單元公式的第一項(xiàng)/下一項(xiàng)具有待計(jì)算支持單元,即該單元的值也是待計(jì)算時,則把該單元也壓入堆棧。如果單元公式的第一項(xiàng)/下一項(xiàng)不是待計(jì)算單元,即該單元的值不需要計(jì)算即可以得到結(jié)果或者該單元的值是常數(shù)值時,則直接計(jì)算得到該結(jié)果值。
計(jì)算模塊604、對新壓入的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
當(dāng)壓入堆棧的單元還是具有待計(jì)算單元時,則對該單元再次重復(fù)調(diào)用判斷模塊,直至所述單元各項(xiàng)的值都完成計(jì)算,根據(jù)各項(xiàng)的值完成待計(jì)算單元的計(jì)算。
進(jìn)一步,所述電子數(shù)據(jù)表計(jì)算系統(tǒng)還可以包括異常處理模塊605,當(dāng)壓入堆棧的單元個數(shù)達(dá)到堆棧的預(yù)設(shè)容量臨界值時,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,生成新的計(jì)算鏈。
以上對本發(fā)明所提供的一種電子數(shù)據(jù)表的計(jì)算方法和裝置,進(jìn)行了詳細(xì)介紹說明,本文中應(yīng)用了具體個例對本發(fā)明的原理及實(shí)施方式進(jìn)行了闡述,以上實(shí)施例的只是用于幫助理解本發(fā)明的方法及其核心思想;同時,對于本領(lǐng)域的一般技術(shù)人員,依據(jù)本發(fā)明的思想,在具體實(shí)施方式
及應(yīng)用范圍上均會有改變之處,綜上所述,本說明書內(nèi)容不應(yīng)理解為對本發(fā)明的限制。
權(quán)利要求
1.一種電子數(shù)據(jù)表計(jì)算方法,其特征在于,包括a、將待計(jì)算單元壓入堆棧;b、判斷該單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;c、對壓入堆棧的支持單元按步驟b求值,完成后將該支持單元彈出堆棧;d、重復(fù)步驟b、c,完成待計(jì)算單元的計(jì)算,并將該單元彈出堆棧。
2.一種電子數(shù)據(jù)表的計(jì)算方法,其特征在于,包括a、生成電子數(shù)據(jù)表的計(jì)算鏈;b、按計(jì)算鏈的順序進(jìn)行第一/下一單元的計(jì)算,將該待計(jì)算單元壓入堆棧;c、判斷該單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;d、對壓入堆棧的支持單元按步驟c求值,完成后將支持單元彈出堆棧;e、重復(fù)步驟c、d,完成待計(jì)算單元的計(jì)算,將該單元彈出堆棧,并返回步驟b,直到該計(jì)算鏈所有單元都計(jì)算完成。
3.如權(quán)利要求2所述電子數(shù)據(jù)表的計(jì)算方法,其特征在于,步驟a所述電子數(shù)據(jù)表計(jì)算鏈的生成步驟包括a1、解析電子數(shù)據(jù)表各單元間的依賴關(guān)系;a2、向計(jì)算鏈添加第一單元;a3、根據(jù)依賴關(guān)系查詢該單元的依賴單元,將所述依賴單元添加到計(jì)算鏈的尾部;a4、根據(jù)依賴關(guān)系查詢新添加單元的依賴單元,將所述新添加單元的依賴單元添加到計(jì)算鏈的尾部;a5、重復(fù)步驟a4至計(jì)算鏈的最后一個單元;a6、按照預(yù)置的遍歷順序?qū)⑾乱粏卧砑拥接?jì)算鏈的尾部,對該單元按步驟a3、a4、a5完成計(jì)算鏈操作;a7、重復(fù)步驟a6,得到電子數(shù)據(jù)表的計(jì)算鏈。
4.如權(quán)利要求3所述電子數(shù)據(jù)表的計(jì)算方法,其特征在于當(dāng)計(jì)算鏈中已經(jīng)存在要添加的單元時,不再添加該單元。
5.如權(quán)利要求2所述電子數(shù)據(jù)表的計(jì)算方法,其特征在于,進(jìn)一步包括預(yù)設(shè)所述堆棧的容量臨界值,當(dāng)壓入的單元個數(shù)達(dá)到臨界值要發(fā)生堆棧溢出錯誤時,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,按照新的計(jì)算鏈重新計(jì)算。
6.一種電子數(shù)據(jù)表的計(jì)算裝置,其特征在于,包括堆棧,用于緩存電子數(shù)據(jù)表單元;判斷模塊,判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;計(jì)算模塊,對新壓入的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
7.一種電子數(shù)據(jù)表的計(jì)算裝置,其特征在于,包括堆棧,用于緩存電子數(shù)據(jù)表單元;計(jì)算鏈生成模塊,用于生成電子數(shù)據(jù)表的計(jì)算鏈;判斷模塊,判斷壓入堆棧的單元公式的第一項(xiàng)/下一項(xiàng)是否具有待計(jì)算支持單元,是則將該支持單元壓入堆棧;否則對該單元公式的第一項(xiàng)/下一項(xiàng)直接求值;計(jì)算模塊,對新壓入的單元重復(fù)調(diào)用判斷模塊,完成待計(jì)算單元的計(jì)算,并彈出該單元。
8.如權(quán)利要求7所述電子數(shù)據(jù)表的計(jì)算裝置,其特征在于,進(jìn)一步包括異常處理模塊,當(dāng)壓入堆棧的單元個數(shù)達(dá)到堆棧的預(yù)設(shè)容量臨界值時,將壓入堆棧中的各單元反序插入到計(jì)算鏈的待計(jì)算單元節(jié)點(diǎn)前,生成新的計(jì)算鏈。
9.如權(quán)利要求7所述電子數(shù)據(jù)表的計(jì)算裝置,其特征在于,所述的計(jì)算鏈生成模塊包括解析模塊,用于解析電子數(shù)據(jù)表各單元間的依賴關(guān)系;置入模塊,用于向計(jì)算鏈添加單元;查詢模塊,用于根據(jù)解析模塊查詢電子數(shù)據(jù)表中單元的依賴單元;生成模塊,用于調(diào)用置入模塊添加電子數(shù)據(jù)表第一單元至計(jì)算鏈中,調(diào)用查詢模塊查詢該單元的依賴單元,并再次調(diào)用置入模塊將所述依賴單元添加到計(jì)算鏈的尾部;以及,針對新添加單元的依賴單元重復(fù)調(diào)用查詢模塊和置入模塊,直到計(jì)算鏈的尾部;以及,針對電子數(shù)據(jù)表下一單元再次重復(fù)調(diào)用置入模塊、查詢模塊,得到電子數(shù)據(jù)表的計(jì)算鏈。
10.如權(quán)利要求9所述的計(jì)算裝置,其特征在于對于計(jì)算鏈生成模塊,當(dāng)計(jì)算鏈中已經(jīng)存在要添加的單元時,不調(diào)用置入模塊添加該單元。
全文摘要
本發(fā)明提供了一種電子數(shù)據(jù)表計(jì)算方法,創(chuàng)新的在電子數(shù)據(jù)表的計(jì)算過程中增加了堆棧操作,當(dāng)電子數(shù)據(jù)表單元待計(jì)算時,將其壓入堆棧,如果該單元公式中的某一項(xiàng)具有待計(jì)算支持單元,則中斷該依賴單元的計(jì)算,先完成支持單元的計(jì)算,再根據(jù)支持單元的值完成該待計(jì)算依賴單元的計(jì)算。當(dāng)支持單元又依賴其它支持單元時,再次重復(fù)以上步驟,直至能夠完成待計(jì)算單元的計(jì)算。從而使所涉及的支持單元能夠在依賴單元之前完成計(jì)算,避免了在計(jì)算過程中單元節(jié)點(diǎn)的移動,并能夠避免冗余運(yùn)算,對電子數(shù)據(jù)表計(jì)算效率的提高明顯,節(jié)省了計(jì)算機(jī)系統(tǒng)資源。
文檔編號G06F7/78GK101055568SQ200710105710
公開日2007年10月17日 申請日期2007年5月25日 優(yōu)先權(quán)日2007年5月25日
發(fā)明者喬昕明 申請人:金蝶軟件(中國)有限公司