C#人民币金额大写
摘自《31天學會CRM項目開發<C#編程入門級項目實戰>》
這是一項經典編程題,筆者也曾將此題作為面試題。
1.?? ?業務要求
人民幣大寫金額用到的漢字主要包括零、壹、貳、叁、肆、伍、陸、柒、捌、玖、拾、佰、仟、萬、億等。人民幣大寫金額有如下注意事項:
??? 中文大寫金額數字到“元”為止的,在“元”之后、應寫“整”(或“正”)字;在“角”之后,可以不寫“整”(或“正”)字;大寫金額數字有“分”的,“分”后面不寫“整”(或“正”)字。
??? 阿拉伯數字中間有“0”時,中文大寫要寫“零”字,如¥1308.6應寫成壹仟叁佰零捌元陸角;
??? 阿拉伯數字中間連續有幾個“0”時、中文大寫金額中間可以只寫一個“零”字,如¥9006.24應寫成玖仟零陸元貳角肆分。
??? 阿拉伯金額數字中間連續有幾個“0”時,中文大寫金額僅寫一個零,如¥10001,應寫成一萬零一。
??? 阿拉伯金額數字角位是“0”而分位不是“0”時,中文大寫金額“元”后面應寫“零”字。
2.?? ?實現方法
(1)?? ?方法一
如片段9-20所示,主要步驟如下:
1)?? ?取得整數和小數部分
2)?? ?對整數部分進行反轉,依次從個位數起添加數量單位
3)?? ?將阿拉伯數字替換成大寫數字
4)?? ?替換不符合漢語規律的詞匯,例如仟佰、零佰、零拾等
代碼片段9-20
(2)?? ?方法二
使用正則表達式,如片段9-21所示,來源于網絡,相比常規方法,顯得非常簡潔,足以展示正則表達式的強大,也體現了程序設計者深厚技術功底。由于無法查證這段代碼的原作者,此處無法標注原作者姓名和出處。
代碼片段9-21 string s = dou.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A"); string d = Regex.Replace(s, @"((?<=-|^)[^\-1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\.]|$))))", "${b}${z}"); string RMB= "負元空零壹貳叁肆伍陸柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"; string r = Regex.Replace(d, ".", m => RMB[m.Value[0] - '-'].ToString()); if (r.EndsWith("元"))r = r + "整";
行6,“m.Value[0] - '-'”是兩個char字符相減,char字符相減會升級為int型,相當于“(int)m.Value[0] – (int)'-'”,即使用char字符所對應的ASCII碼值相減。
行6,符號“=>” 稱作Lambda 表達式,是一種可用于創建委托或表達式目錄樹類型的匿名函數。通過使用 lambda 表達式,可以寫入可作為參數傳遞或作為函數調用值返回的本地函數。若要創建 Lambda 表達式,需要在 Lambda 運算符 => 左側指定輸入參數(如果有),然后在另一側輸入表達式或語句塊。 例如,lambda 表達式 x => x * x 指定名為 x 的參數并返回 x 的平方值。
行6可改寫成如片段9-22形式。
代碼片段9-22
string value = Regex.Replace(d, ".", delegate(Match m){ return RMB[m.Value[0] - '-'].ToString(); });片段9-22還可寫成片段9-23、9-24形式,這樣更容易理解。
代碼片段9-23
string r = Regex.Replace(d, ".", new MatchEvaluator(GetChinese));
代碼片段9-24 private string GetChinese(Match m) {string RMB = "負元空零壹貳叁肆伍陸柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰";return RMB[m.Value[0] - '-'].ToString(); } 方法一屬于常規思路,一般人都會這么考慮,方法二,打破常規,非正則不“娶”,充分體現了程序設計者對代碼簡潔苛刻的追求。方法一雖然代碼比較長,但也有優點,它還適用于 Java 、 JavaScript 、 PHP 等其他編程語言。
總結
- 上一篇: npm的命令参数 --save-dev和
- 下一篇: C#关于Xmp元数据获取的坑