婁七明,楊志金,孫建洪,張紅偉
(紅河學(xué)院工學(xué)院,云南蒙自 661100)
隨著信息化建設(shè)的不斷推進(jìn),辦公自動(dòng)化程度的不斷提高,很多票據(jù)和經(jīng)濟(jì)合同等都需要打印。在這些票據(jù)和經(jīng)濟(jì)合同中通常需要打印大寫金額,這就需要將用阿拉伯?dāng)?shù)字書寫的金額轉(zhuǎn)換成人民幣大寫形式。在財(cái)務(wù)管理中大寫金額不能隨意書寫,[3]必須遵循一定的規(guī)則。目前有使用各種語(yǔ)言實(shí)現(xiàn)的大寫金額轉(zhuǎn)換函數(shù),但這些函數(shù)都是采用面向過程的設(shè)計(jì)思想實(shí)現(xiàn)的,且算法比較復(fù)雜,可讀性較差。因此,本文采用面向?qū)ο蟮某绦蛟O(shè)計(jì)思想來實(shí)現(xiàn)大寫金額轉(zhuǎn)換,并用C#實(shí)現(xiàn)該算法。該算法把待轉(zhuǎn)換的數(shù)字和轉(zhuǎn)換方法封裝為一個(gè)整體,具有可重用性強(qiáng)、可擴(kuò)充性好、算法簡(jiǎn)單易懂等特點(diǎn)。
用阿拉伯?dāng)?shù)字書寫的金額轉(zhuǎn)換成大寫金額應(yīng)遵循以下規(guī)則:
(1)阿拉伯?dāng)?shù)字轉(zhuǎn)換為大寫金額后,如果沒有角分位,應(yīng)在“元”后寫“整”(或“正”),否則“角”和“分”后面不寫“整”(或“正”)字。
(2)把非0的阿拉伯?dāng)?shù)字轉(zhuǎn)換成對(duì)應(yīng)的大寫數(shù)字,并加上相應(yīng)數(shù)位對(duì)應(yīng)的漢字,如10轉(zhuǎn)換為“壹拾元”。
(3)在億級(jí)以上有不為零的數(shù)字時(shí),億位要加“億”;在萬和千萬之間有不為零的數(shù)字時(shí),萬位要加“萬”;金額大于一元時(shí),個(gè)位要加“元”,如1010000100,轉(zhuǎn)換為“壹拾億零壹仟萬零壹佰元”。
(4)如果非0的阿拉伯?dāng)?shù)字之間有一個(gè)0或者多個(gè)0時(shí),大寫金額中間對(duì)應(yīng)處要加一個(gè)“零”;如果非0的阿拉伯?dāng)?shù)字之后所有數(shù)字都為0,則大寫金額中這個(gè)數(shù)字后面不加“零”,如10100,轉(zhuǎn)換為“壹萬零壹佰元”。
要將一個(gè)阿拉伯?dāng)?shù)字轉(zhuǎn)換為大寫金額,如100202001023.35??梢园慈缦虏襟E實(shí)現(xiàn)。
第一步:把該數(shù)字分成整數(shù)部分和小數(shù)部分,整數(shù)部分是100202001023,小數(shù)部分是35。
第二步:分別將小數(shù)部分和整數(shù)部分進(jìn)行轉(zhuǎn)換,小數(shù)部分取出角位的數(shù)字和分位的數(shù)字分別轉(zhuǎn)換,本例中角位轉(zhuǎn)換為“叁角”,分位轉(zhuǎn)換為“伍分”。整數(shù)部分也取出各位對(duì)應(yīng)的值分別轉(zhuǎn)換成對(duì)應(yīng)的字符串,本例中從千億位到個(gè)位分別轉(zhuǎn)換為“壹仟”“零”“零”“貳億”“零”“貳佰”“零”“萬”“壹仟”“零”“貳拾”“叁元”。
第三步:把前面的轉(zhuǎn)換結(jié)果合并成一個(gè)字符串,即“壹仟零零貳億零貳佰零萬壹仟零貳拾叁元叁角伍分”。
第四步:消除合并后所得字符串中多余的字符,如連續(xù)的多個(gè)“零”,只保留一個(gè)“零”,把字符串中的“零億”“零萬”“零元”等分別替換成“億”“萬”“元”,刪除字符串最前面的“億”“元”“零”以及字符串最后面的“零”。本例處理完成后結(jié)果,即“壹仟零貳億零貳佰萬壹仟零貳拾叁元叁角伍分”。
第五步:判斷是否在字符串的最后面加上“正”字,整個(gè)轉(zhuǎn)換過程即完成。
綜上,大寫金額轉(zhuǎn)換算法可以用如圖1所示的N-S流程圖表示。
圖1 大寫金額轉(zhuǎn)換算法N-S流程圖
定義類ArabToChinese實(shí)現(xiàn)用阿拉伯?dāng)?shù)字書寫的金額到大寫金額的轉(zhuǎn)換,類的成員數(shù)據(jù)和成員方法如下:
3.2.1 構(gòu)造函數(shù)的實(shí)現(xiàn)
構(gòu)造函數(shù)ArabToChinese的功能是將待轉(zhuǎn)換的金額s轉(zhuǎn)換為double類型,并取出各位對(duì)應(yīng)的數(shù)字賦值給相應(yīng)的成員數(shù)據(jù),實(shí)現(xiàn)代碼如下:
3.2.2 方法DtoC的實(shí)現(xiàn)
方法DtoC的功能是將非零的數(shù)字轉(zhuǎn)換成對(duì)應(yīng)的漢字,對(duì)應(yīng)的代碼如下:
3.2.3 將各位數(shù)字轉(zhuǎn)換成對(duì)應(yīng)字符串
分別定義方法將各位數(shù)字轉(zhuǎn)換為對(duì)應(yīng)的字符串,因篇幅所限,且這些方法的實(shí)現(xiàn)代碼類似,這里以方法FentoS、JiaotoS、GeweitoS的實(shí)現(xiàn)為例進(jìn)行介紹,這三個(gè)方法對(duì)應(yīng)的代碼如下:
3.2.4 GetResult方法的實(shí)現(xiàn)
GetResult方法的功能是合并各部分的轉(zhuǎn)換結(jié)果,并刪除多余的字符,得到最終的轉(zhuǎn)換結(jié)果,實(shí)現(xiàn)該方法的代碼如下:
下面通過實(shí)例說明轉(zhuǎn)換方法的使用。如要把101012000100.00轉(zhuǎn)換為大寫金額,則以字符串“101012000100.00”為參數(shù)創(chuàng)建對(duì)象,然后通過對(duì)象調(diào)用成員方法GetResult獲得轉(zhuǎn)換結(jié)果。在C#控制臺(tái)應(yīng)用程序中的實(shí)現(xiàn)代碼如下:
程序的輸出結(jié)果是“壹仟零壹拾億壹仟貳佰萬零壹佰元正”。
本文運(yùn)用面向?qū)ο蟮某绦蛟O(shè)計(jì)思想,把要轉(zhuǎn)換的金額和轉(zhuǎn)換算法封裝為一個(gè)整體,并用C#實(shí)現(xiàn)了該算法。文中定義的類ArabToChinese能實(shí)現(xiàn)整數(shù)部分12位(即千億位)和小數(shù)部分2位的數(shù)字大寫金額轉(zhuǎn)換,能滿足大多數(shù)情況下金額轉(zhuǎn)換的需求。文中基于類實(shí)現(xiàn)的金額轉(zhuǎn)換方法具有良好的可擴(kuò)充性,若需要轉(zhuǎn)換更大范圍的金額,可以從類ArabToChinese派生出新的類,并在新的類中增加相應(yīng)的成員數(shù)據(jù)及相應(yīng)位的轉(zhuǎn)換方法即可實(shí)現(xiàn)。