有时候我们需要把数字用汉语读出来,比如1234读成“一千二百三十四”,这里我用C#设计了一个方法,以完成这一目的,思路有点新颖,网上找了很多此类例子,都不是我今天给大家介绍的方法。
用汉语去读一个数,最后的字符串所有元素肯定在以下两个Char[]元素组成的集合里:
digit =new Char[] { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' }; suffix =new Char[] { '十', '百', '千', '万', '亿' };
对应的也有繁体中文版本:
digit = new Char[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; suffix = new Char[] { '拾', '佰', '仟', '萬', '億' };
从总体上,我考虑把一个数转换成一个Char[],然后根据他所在的位置填补上“十”“百”“千”“万”“亿”。
由数学归纳法可以证明得:(K>=0,第0位亦即个位作为特殊位置)
“十”出现在:4k+1的位置上,
“百”出现在:4k+2的位置上,
“千”出现在:4k+3的位置上,
“万”出现在:8k+8的位置上,
“亿”出现在:8k+4的位置上.
可以证明这五个集合互不相交,并且可以证明可以涵盖所有自然数(8k,8k+1=4*2k+1...,再补上0),这里不去探讨证明的详细过程。
至此,这个方法的大题思路已经清晰,并且在理论上也得到了可行性的证明。
剩下的是一些细节:
1.连续出现的0
2."万"和"亿"冲突的问题
这些不便在这里详细说明,代码中已经给出解决方法。
下面给出代码:
/// <summary> /// 把数字转换为汉语读法 /// 2009-03-18 /// Rock /// [email protected] /// </summary> /// <param name="input"></param> /// <param name="isSimplified">是否简体</param> /// <returns></returns> public static String GetChnRead(UInt64 input,Boolean isSimplified) { Char[] digit,suffix; if (isSimplified) { digit =new Char[] { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' }; suffix =new Char[] { '十', '百', '千', '万', '亿' }; } else { digit = new Char[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; suffix = new Char[] { '拾', '佰', '仟', '萬', '億' }; } StringBuilder inputSB = new StringBuilder(input.ToString(),20); for (Byte i = 0; i < 10; i++) inputSB.Replace(i.ToString()[0],digit[i]); Char[] inputCh = inputSB.ToString().ToCharArray(); Boolean preIsZero = false; StringBuilder outputSB = new StringBuilder(null, 40); Byte maxPos =(Byte) (inputCh.Length - 1); for (Int16 i = maxPos; i >= 0; i--) if (inputCh[maxPos - i] == digit[0]) { if (GetSuffix(i, suffix) == suffix[3] && preIsZero == false) outputSB.Append(suffix[3].ToString() + digit[0]); else if (GetSuffix(i, suffix) == suffix[3] && preIsZero == true) { if (outputSB[outputSB.Length - 2] != suffix[4]) { outputSB[outputSB.Length - 1] = suffix[3]; outputSB.Append(digit[0]); } } else if (GetSuffix(i, suffix) == suffix[4] && preIsZero == false) outputSB.Append(suffix[4].ToString() + digit[0]); else if (GetSuffix(i, suffix) == suffix[4] && preIsZero == true) { outputSB[outputSB.Length - 1] = suffix[4]; outputSB.Append(digit[0]); } else if (preIsZero == false) outputSB.Append(digit[0]); preIsZero = true; } else { outputSB.Append(inputCh[maxPos - i].ToString() + GetSuffix(i, suffix)); preIsZero = false; } if (outputSB.Length == 1 && outputSB[0] == digit[0]) return digit[0].ToString(); if (outputSB.Length >= 2) if (outputSB[0] == digit[1] && outputSB[1] == suffix[0]) outputSB.Remove(0, 1); return outputSB.ToString().TrimEnd(digit[0]); } private static Char? GetSuffix(Int16 pos,Char[] suffix) { if (pos == 0) return null; switch (pos % 4) { case 1: return suffix[0]; case 2: return suffix[1]; case 3: return suffix[2]; } switch (pos % 8) { case 4: return suffix[3]; case 0: return suffix[4]; } return null; }
测试代码:
static void Main(string[] args) { //测试程序 UInt64 ui=0; while (ui != 11) { ui = UInt64.Parse(Console.ReadLine()); Console.WriteLine(ui+":" + GetChnRead(ui, true) + "," + GetChnRead(ui, false)); } Console.WriteLine("Press Any Key To Exit"); Console.Read(); }