一道笔试题的代码实现,请多多请教。

    前些日,遇到这么个笔试题:
    任选一种语言,写一段程序,将实数转成中文大学金额。如1234.12转成壹仟贰佰叁拾肆元壹角贰分。
    大家觉得这题目是简单还难?是否有把握在一个小时内正确编码实现?我当时刚拿题目,觉得有几个难点。当场没实现完整。回到家好好用c#写了一遍,大家评说一下这代码实现如何?请多多请教。

    转化的时候我遇到个郁闷,就是一兆等于多少亿,姑且按一兆等于亿亿来算吧,也就是百度的一个结果里说的“上法”:10^4=万, 10^8=亿,10^16=兆,10^32=京 。 http://zhidao.baidu.com/question/19742157.html?si=1

    我觉得难点有:(1)零的处理,例如不能出现两个或多个零相邻,万、亿位上的数字是零的话不一定没有万、亿字出现。(2)精度的处理。
    总觉得现在的代码好像还是过于冗长,哪位仁兄能提供一个更简洁、运行效率更高的代码,不胜感激。不过要主意测试。
    如果从代码风格、算法设计方面看,大家给这份代码一个怎样的评定呢?
    
  1 using  System;
  2 using  System.Collections.Generic;
  3 using  System.Text;
  4
  5 namespace  CSharp大写金额
  6 {
  7    /**//// <summary>
  8    /// 将实数转化为中文大写金额
  9    /// 作者:左轮
 10    /// 时间:2007-11-4
 11    /// </summary>

 12    public static class ConvertDoubleToChineseMoney
 13    {
 14        /**//// <summary>
 15        /// 数字和中文大写字符对应关系
 16        /// </summary>

 17        private static Dictionary<intstring> _numberChinese;
 18        /**//// <summary>
 19        /// 位数和位名(如个、拾、百等)对应关系
 20        /// </summary>

 21        private static Dictionary<intstring> _pointChineseNames;
 22        /**//// <summary>
 23        /// 最大位名对应的位数
 24        /// </summary>

 25        private const int _maxPointNameIndex = 8;
 26
 27        static ConvertDoubleToChineseMoney()
 28        {
 29            _numberChinese = new Dictionary<intstring>(10);
 30            _numberChinese.Add(0"");
 31            _numberChinese.Add(1"");
 32            _numberChinese.Add(2"");
 33            _numberChinese.Add(3"");
 34            _numberChinese.Add(4"");
 35            _numberChinese.Add(5"");
 36            _numberChinese.Add(6"");
 37            _numberChinese.Add(7"");
 38            _numberChinese.Add(8"");
 39            _numberChinese.Add(9"");
 40
 41            _pointChineseNames = new Dictionary<intstring>(8);
 42            _pointChineseNames.Add(_maxPointNameIndex, "亿");
 43            _pointChineseNames.Add(4"");
 44            _pointChineseNames.Add(3"");
 45            _pointChineseNames.Add(2"");
 46            _pointChineseNames.Add(1"");
 47            _pointChineseNames.Add(0string.Empty);
 48            _pointChineseNames.Add(-1"");
 49            _pointChineseNames.Add(-2"");
 50        }

 51
 52        /**//// <summary>
 53        /// 将实数转化为中文大写金额
 54        /// </summary>
 55        /// <param name="money">用双精度浮点数表示的金额,不能大于9.0e+15,否则抛出ArgumentException异常</param>
 56        /// <returns>中文大写金额字符串</returns>

 57        public static string Convert(double money)
 58        {
 59            if (money > 9.0e+15)
 60                throw new ArgumentException("不能转换大于9.0e+15的数");
 61
 62            if (money < 0.01)
 63                return "零元";
 64
 65            //分开小数点左边和右边两部分分别转换,然后再合并
 66            double rightPart = money % 1D;
 67            double leftPart = money - rightPart;
 68
 69            string strLeftPart = ConvertLeftPart(leftPart);
 70            string strRightPart = ConvertRightPart(rightPart);
 71
 72            StringBuilder sbChineseMoney = new StringBuilder(strLeftPart.Length + strRightPart.Length + 2);
 73            if (string.IsNullOrEmpty(strLeftPart))
 74            {
 75                strRightPart = strRightPart.TrimStart('');
 76            }

 77            else
 78            {
 79                sbChineseMoney.Append(strLeftPart);
 80                sbChineseMoney.Append('');
 81            }

 82            sbChineseMoney.Append(strRightPart);
 83
 84            return sbChineseMoney.ToString();
 85        }

 86
 87        /**//// <summary>
 88        /// 转换小数点左边部分
 89        /// </summary>
 90        /// <param name="money"></param>
 91        /// <returns></returns>

 92        private static string ConvertLeftPart(double money)
 93        {
 94            //中文大写金额,结果字符串
 95            StringBuilder sbChineseMoney = new StringBuilder(_maxPointNameIndex * 2);
 96            bool isBegin = false;
 97            //从左到右逐个将字翻译成中文大写金额
 98            for (int numberIndex = _maxPointNameIndex * 2 - 1; numberIndex >= 0; numberIndex--)
 99            {
100                //获取一位上的数字
101                double number = GetNumbers(money, numberIndex, numberIndex);
102
103                if (number > 0)
104                    isBegin = true;
105
106                if (number == 0 && !isBegin)
107                    continue;
108                //获取位名的key
109                int pointNameIndex = GetLeftPartPointNameIndex(numberIndex);
110                //将当前数字的中文字符和位名插入结果字符串
111                if (number != 0)
112                {
113                    //当前数字不为零,将数字和位名直接加入结果字符串尾部
114                    sbChineseMoney.Append(_numberChinese[(int)number]);
115                    sbChineseMoney.Append(_pointChineseNames[pointNameIndex]);
116                }

117                else
118                {
119                    //当前数字为零
120                    //如果结果字符串最后一个字符不是零,才将零加入结果字符串,避免多个相邻的零出现在结果字符串
121                    if (sbChineseMoney[sbChineseMoney.Length - 1!= '')
122                        sbChineseMoney.Append('');
123                    //如果位名是个、拾、百、千,不出现在零后面
124                    //处理位名是万、亿的情况
125                    if (pointNameIndex >= 4 && GetNumbers(money, numberIndex + pointNameIndex - 1, numberIndex) > 0D)
126                        sbChineseMoney = sbChineseMoney.Insert(sbChineseMoney.Length - 1, _pointChineseNames[pointNameIndex]);
127                }

128
129            }

130            string strChineseMoney = sbChineseMoney.ToString();
131            strChineseMoney = strChineseMoney.TrimEnd('');
132            return strChineseMoney;
133        }

134
135        /**//// <summary>
136        /// 处理小数点右边部分
137        /// </summary>
138        /// <param name="money"></param>
139        /// <returns></returns>

140        private static string ConvertRightPart(double money)
141        {
142            if( money < 0.01 )
143                return string.Empty;
144
145            money *= 100;
146
147            StringBuilder sbChineseMoney = new StringBuilder(4);
148
149            int number = (int)GetNumbers(money, 11);
150            sbChineseMoney.Append(_numberChinese[number]);
151            if (number != 0)
152                sbChineseMoney.Append(_pointChineseNames[-1]);
153
154            number = (int)GetNumbers(money, 00);
155            if (number != 0)
156            {
157                sbChineseMoney.Append(_numberChinese[number]);
158                sbChineseMoney.Append(_pointChineseNames[-2]);
159            }

160
161            return sbChineseMoney.ToString();
162        }

163        /**//// <summary>
164        /// 获取指定位数范围的数字
165        /// </summary>
166        /// <param name="money"></param>
167        /// <param name="leftIndex"></param>
168        /// <param name="rightIndex"></param>
169        /// <returns></returns>

170        private static double GetNumbers(double money, int leftIndex, int rightIndex)
171        {
172            double pow1 = Math.Pow(10D, (double)(leftIndex + 1));
173            double pow2 =  Math.Pow(10D, (double)rightIndex);
174            return (money % pow1 - money % pow2) / pow2;
175        }

176
177        /**//// <summary>
178        /// 获取指定数字索引的位名在_pointChineseNames上的key
179        /// </summary>
180        /// <param name="numberIndex"></param>
181        /// <param name="name"></param>
182        /// <returns>位名在_pointChineseNames上的key</returns>

183        private static int GetLeftPartPointNameIndex(int numberIndex)
184        {
185            int pointNameIndex = 0;
186            int remainder = numberIndex % 4;
187            if (remainder == 0)
188            {
189                if (numberIndex == 0)
190                {
191                    pointNameIndex = 0;
192                }

193                else
194                {
195                    for (int cast = _maxPointNameIndex; cast >= 4; cast /= 2)
196                    {
197                        if (numberIndex % cast == 0)
198                        {
199                            pointNameIndex = cast;
200                            break;
201                        }

202                    }

203                }

204            }

205            else
206            {
207                pointNameIndex = remainder;
208            }

209
210            return pointNameIndex;
211        }

212    }

213}
测试结果截屏

转载于:https://www.cnblogs.com/zuolun/archive/2007/11/04/948654.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值