一道笔试题的代码实现,请多多请教。
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
前些日,遇到这么个笔试题:
任选一种语言,写一段程序,将实数转成中文大学金额。如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
相关文章推荐
- 并查集的简介及其C/C++代码的实现(某公司招聘笔试试题)
- 一道笔试题:给定编码规则,实现decode()方法
- Trie树的应用,一道算法问题求解 代码实现
- C/Python实现的一道笔试题
- 阿里的一道静态方法和静态代码块牛逼笔试题
- 一道微妙的PHP面试题,两行代码,知识多多
- assert宏的实现(一道笔试题)
- 一道Baidu笔试题目的解(+1实现-1)
- C语言字符串库函数的实现也是笔试题常考的题目,以下代码没有严格测试,只是简单的实现:
- RGB转换实现代码,淘宝前端开发工程师笔试题
- 一道 google曾出过的笔试题:编程实现对数学一元多项式的相加和相乘操作(1)
- 两个栈来实现一个队列的C++代码(某公司社会早笔试题)
- 2014年9月14号阿里巴巴校招笔试题 一道题的JAVA实现
- 一道 google曾出过的笔试题:编程实现对数学一元多项式的相加和相乘操作
- 关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题
- 网易的一道CSS笔试题--固定宽高的子元素如何在未知宽高的父元素中实现居中?
- 2017 小米笔试题 编程题 求树的高度 Java代码实现
- 2017 小米笔试题 编程题 求树的高度 Java代码实现
- Quicksort 快速排序—注意点以及代码实现(笔试手写代码)
- java实现堆排序(2016年腾讯内推笔试的一道算法题)