数字转人民币大写算法一则
一个数字转人民币大写的例子。其中主要的难点是“0”在不同位置,处理的方式有所不同。
这里考虑的是整数位为最多12位,小数位2位的通用数字。也就是最小值0.00,最大值为999999999999.99。
从左往右看,首先数字在整数部第4位,第8位与第12位为“0”时,不应转化为大写“零”。而在小数部的第2位也不应为零。
再者,若是某处数字为“0”,那么如果其前一位也是“0”的话,则同样不应转化为“零”,否则会出现“零零”这样的结果。
但是这有例外,比如100100.00这样的数字,第三位是“0”,第二位也是“0”,而按照习惯,是应该转成“壹拾万零壹佰元整”的。
所以要考虑将12位整数分为三个部分。若不足12位的话,前面加“0”补足。
当某一部分的某一数字不满足前一位不为“0”这一条件时,先要从当前部分查看是否之前有过非“0”的数字,若有则不需要加“零”。
如要当前部分还是不满足条件的话,则要继续向前查找,在前一部分寻找是否有非“0”的数字。找到的话则加“零”。
小数部分有个地方需要注意:当整数部分为0,小数部分第一位也是“0”时,不要将其转为“零”。
using
System;
using
System.Collections.Generic;
using
System.Globalization;
using
System.Text;
using
System.Text.RegularExpressions;
using
System.Threading;
namespace
Demo
{
internal
class
Program
{
private
static
Dictionary<
char
,
string
> _dic =
new
Dictionary<
char
,
string
>();
public
static
void
Main(
string
[] args)
{
_dic[
'1'
] =
"壹"
;
_dic[
'2'
] =
"贰"
;
_dic[
'3'
] =
"叁"
;
_dic[
'4'
] =
"肆"
;
_dic[
'5'
] =
"伍"
;
_dic[
'6'
] =
"陆"
;
_dic[
'7'
] =
"柒"
;
_dic[
'8'
] =
"捌"
;
_dic[
'9'
] =
"玖"
;
_dic[
'0'
] =
"零"
;
while
(
true
)
{
Test();
Thread.Sleep(1000);
}
}
private
static
void
Test()
{
Random r =
new
Random();
int
count = r.Next(0, 13);
int
i = 0;
StringBuilder sb =
new
StringBuilder();
while
(i++ < count)
{
sb.Append(r.Next(0, 10));
}
sb.Append(
"."
);
i = 0;
while
(i++ < 2)
{
sb.Append(r.Next(0, 10));
}
Console.WriteLine(ConverToRMB(Convert.ToDecimal(sb.ToString(), CultureInfo.InvariantCulture)));
}
private
static
string
ConverToRMB(
decimal
num)
{
string
data = Convert.ToString(num, CultureInfo.InvariantCulture);
bool
isNum = ValidateData(data);
if
(!isNum)
{
return
"无效的数字"
;
}
string
[] parts = data.Split(
'.'
);
string
intPart = parts[0];
string
decPart = parts[1];
string
intResult = ParseIntPart(intPart);
bool
isZero = String.IsNullOrEmpty(intResult);
string
decResult = ParseDecPart(decPart, isZero);
string
result =
string
.Empty;
if
(String.IsNullOrEmpty(intResult))
{
if
(String.IsNullOrEmpty(decResult))
{
result =
"零元整"
;
}
else
{
result = decResult;
}
}
else
{
if
(String.IsNullOrEmpty(decResult))
{
result = intResult +
"元整"
;
}
else
{
result = intResult +
"元"
+ decResult;
}
}
return
result;
}
private
static
bool
ValidateData(
string
data)
{
Regex r =
new
Regex(
@"^\d{0,12}\.\d{2}$"
);
return
r.IsMatch(data);
}
private
static
string
ParseIntPart(
string
intPart)
{
char
[] arr = intPart.ToCharArray();
char
[] temp = {
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
};
arr.CopyTo(temp, 12 - arr.Length);
StringBuilder sb =
new
StringBuilder();
for
(
int
i = 0; i < 3; i++)
{
StringBuilder s =
new
StringBuilder();
bool
flag =
false
;
for
(
int
j = 0; j < 4; j++)
{
char
c = temp[j + i * 4];
if
(c !=
'0'
)
{
s.Append(_dic[c]);
switch
(j)
{
case
0: s.Append(
'仟'
);
break
;
case
1: s.Append(
'佰'
);
break
;
case
2: s.Append(
'拾'
);
break
;
}
}
else
{
if
(j != 3)
{
if
(j != 0 && temp[j + i * 4 - 1] !=
'0'
)
{
for
(
int
k = j; k < 4; k++)
{
if
(temp[k + i * 4] !=
'0'
)
{
s.Append(
"零"
);
break
;
}
}
}
else
{
if
(i > 0)
{
for
(
int
k = j; k >= 0; k--)
{
if
(temp[k + i * 4] !=
'0'
)
{
flag =
true
;
break
;
}
}
if
(!flag)
{
bool
flag2 =
false
;
for
(
int
k = i-1; k >= 0; k--)
{
if
(!flag2)
{
for
(
int
m = 0; m < 4; m++)
{
if
(temp[m + k * 4] !=
'0'
)
{
s.Append(
"零"
);
flag2 =
true
;
flag =
true
;
break
;
}
}
}
}
}
}
}
}
}
}
if
(s.Length > 0)
{
switch
(i)
{
case
0: s.Append(
'亿'
);
break
;
case
1: s.Append(
'万'
);
break
;
}
sb.Append(s);
}
}
return
sb.ToString();
}
private
static
string
ParseDecPart(
string
decPart,
bool
isZero)
{
char
[] arr = decPart.ToCharArray();
char
c1 = arr[0];
char
c2 = arr[1];
if
(c1 ==
'0'
&& c2 ==
'0'
)
{
return
string
.Empty;
}
StringBuilder sb =
new
StringBuilder();
if
(c1 !=
'0'
)
{
sb.Append(_dic[c1]);
sb.Append(
'角'
);
}
else
{
if
(!isZero)
{
sb.Append(
"零"
);
}
}
if
(c2 !=
'0'
)
{
sb.Append(_dic[c2]);
sb.Append(
'分'
);
}
return
sb.ToString();
}
}
}