您的位置:首页 > 编程语言

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

2007-11-08 12:00 344 查看
导读:
  前些日,遇到这么个笔试题:
  任选一种语言,写一段程序,将实数转成中文大学金额。如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
  


  
  


  /**////
  8
  


  /// 将实数转化为中文大写金额 9
  


  /// 作者:左轮 10
  


  /// 时间:2007-11-4 11
  


  ///
  12
  


  public static class ConvertDoubleToChineseMoney 13
  


  
  


  
  


  { 14
  


  
  


  /**////
  15
  


  /// 数字和中文大写字符对应关系 16
  


  ///
  17
  


  private static Dictionary _numberChinese; 18
  


  
  


  /**////
  19
  


  /// 位数和位名(如个、拾、百等)对应关系 20
  


  ///
  21
  


  private static Dictionary _pointChineseNames; 22
  


  
  


  /**////
  23
  


  /// 最大位名对应的位数 24
  


  ///
  25
  


  private const int _maxPointNameIndex = 8
  26
  


  27
  


  static ConvertDoubleToChineseMoney() 28
  


  
  


  
  


  { 29
  


  _numberChinese = new Dictionary(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(8); 42
  


  _pointChineseNames.Add(_maxPointNameIndex, "亿"); 43
  


  _pointChineseNames.Add(4, "万"); 44
  


  _pointChineseNames.Add(3, "仟"); 45
  


  _pointChineseNames.Add(2, "佰"); 46
  


  _pointChineseNames.Add(1, "拾"); 47
  


  _pointChineseNames.Add(0, string.Empty); 48
  


  _pointChineseNames.Add(-1, "角"); 49
  


  _pointChineseNames.Add(-2, "分"); 50
  


  }
  51
  


  52
  


  
  


  /**////
  53
  


  /// 将实数转化为中文大写金额 54
  


  ///
  55
  


  /// 用双精度浮点数表示的金额,不能大于9.0e+15,否则抛出ArgumentException异常
  56
  


  /// 中文大写金额字符串
  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
  


  
  


  /**////
  90
  


  ///
  91
  


  ///
  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
  


  
  


  /**////
  136
  


  /// 处理小数点右边部分137
  


  ///
  138
  


  ///
  139
  


  ///
  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, 1, 1);150
  


  sbChineseMoney.Append(_numberChinese[number]);151
  


  if (number != 0)152
  


  sbChineseMoney.Append(_pointChineseNames[-1]);153
  


  154
  


  number = (int)GetNumbers(money, 0, 0);155
  


  if (number != 0)156
  


  
  


  
  


  {157
  


  sbChineseMoney.Append(_numberChinese[number]);158
  


  sbChineseMoney.Append(_pointChineseNames[-2]);159
  


  }
  160
  


  161
  


  return sbChineseMoney.ToString();162
  


  }
  163
  


  
  


  /**////
  166
  


  ///
  167
  


  ///
  168
  


  ///
  169
  


  ///
  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
  


  
  


  /**////
  178
  


  /// 获取指定数字索引的位名在_pointChineseNames上的key179
  


  ///
  180
  


  ///
  181
  


  ///
  182
  


  /// 位名在_pointChineseNames上的key
  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
  


  }
  测试结果截屏
  


  
  posted on 2007-11-04 05:09 左轮阅读(2088) 评论(26) 编辑 收藏所属分类: 编程——.net

本文转自
http://www.cnblogs.com/zuolun/archive/2007/11/04/948654.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: