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

来源:互联网 发布:windows.h 下载 编辑:程序博客网 时间:2024/05/22 03:20
导读:
  前些日,遇到这么个笔试题:
  任选一种语言,写一段程序,将实数转成中文大学金额。如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
  
  
  
  /**////   88
  
  /// 转换小数点左边部分 89
  
  ///
  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
  
  
  
  /**////   164
  
  /// 获取指定位数范围的数字165
  
  ///
  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