这是个经典问题,已为无数人所作过,网上可找到一大堆。但大都冗长晦涩,杂乱难读,算法也是五花八门各显神通。下面这段程序综合各家高招,自以为算法速度可读性等都还过得去。请高手指点赐教。/* 人民币大小写转换
* 可处理小于一亿亿亿元的金额(24位整数、2位小数)
* @author fangxq([email protected])
* @Version 0.1 2008.12.10
*/
public class RMBtoCHINESE { // 负数、四舍五入等参数规范问题不在这里处理
String sNum= "零壹贰叁肆伍陆柒捌玖负";
String sUni= "整分角元拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿拾佰仟万拾佰仟";
private String R2C(String n0){
int L=n0.length();
if (L>27) return "数值溢出"; //包括小数点和2位小数
StringBuffer sN= new StringBuffer(); //转换前的字符串
sN.append(n0);
sN.deleteCharAt(L-3); //去除小数点
--L;
StringBuffer sT= new StringBuffer(); //转换后的字符串
if(sN.charAt(L-1) =='0')
sT.insert(0,'整'); //分位为零则尾部加'整'
boolean Ziro=false, a=false, b=false;
int n=0;
for(int i=1; i<=L; i=i+1) { //从低到高逐位转换
n= sN.charAt(L-i)-'0'; //数值
if(i==7 || i==15)
b= n==0; //万位、万亿位是零
if((i>7)&(i<11)||(i>15)&(i<19))
b=(n==0)& b; //万-亿位、或亿-亿位之间全是零
a=(i==1||i==3||i==7||i==11||i==15||i==19||i==23); //万亿、亿、万、元、分位为0时不写'零'
if( n>0 || (i>1 & a )){
if((i==11||i==19)& b)
sT.setCharAt(0, '亿'); //用'亿'覆盖'万'
else
sT.insert(0, sUni.charAt(i)); //插入单位
}
if( !(n==0 & (Ziro||a) ))
sT.insert(0, sNum.charAt(n)); //插入数值
Ziro= n==0;
}
if(n==0) sT.insert(0, '零'); //小于1元
return sT.toString();
}
public static void main(String[] args){
RMBtoCHINESE cm = new RMBtoCHINESE();
String n;
n="0.01"; System.out.println(n+": "+cm.R2C(n));
n="101000.78"; System.out.println(n+": "+cm.R2C(n));
n="100010100.09"; System.out.println(n+": "+cm.R2C(n));
n="10000000000001.90"; System.out.println(n+": "+cm.R2C(n));
n="900000000000000000000000.00"; System.out.print(n+": "+cm.R2C(n));
}
}运行结果:
0.01: 零元零壹分
101000.78: 壹拾万壹仟元柒角捌分
100010100.09: 壹亿零壹万零壹佰元零玖分
10000000000001.90: 壹拾万亿零壹元玖角整
900000000000000000000000.00: 玖仟万亿亿元整
* 可处理小于一亿亿亿元的金额(24位整数、2位小数)
* @author fangxq([email protected])
* @Version 0.1 2008.12.10
*/
public class RMBtoCHINESE { // 负数、四舍五入等参数规范问题不在这里处理
String sNum= "零壹贰叁肆伍陆柒捌玖负";
String sUni= "整分角元拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿拾佰仟万拾佰仟";
private String R2C(String n0){
int L=n0.length();
if (L>27) return "数值溢出"; //包括小数点和2位小数
StringBuffer sN= new StringBuffer(); //转换前的字符串
sN.append(n0);
sN.deleteCharAt(L-3); //去除小数点
--L;
StringBuffer sT= new StringBuffer(); //转换后的字符串
if(sN.charAt(L-1) =='0')
sT.insert(0,'整'); //分位为零则尾部加'整'
boolean Ziro=false, a=false, b=false;
int n=0;
for(int i=1; i<=L; i=i+1) { //从低到高逐位转换
n= sN.charAt(L-i)-'0'; //数值
if(i==7 || i==15)
b= n==0; //万位、万亿位是零
if((i>7)&(i<11)||(i>15)&(i<19))
b=(n==0)& b; //万-亿位、或亿-亿位之间全是零
a=(i==1||i==3||i==7||i==11||i==15||i==19||i==23); //万亿、亿、万、元、分位为0时不写'零'
if( n>0 || (i>1 & a )){
if((i==11||i==19)& b)
sT.setCharAt(0, '亿'); //用'亿'覆盖'万'
else
sT.insert(0, sUni.charAt(i)); //插入单位
}
if( !(n==0 & (Ziro||a) ))
sT.insert(0, sNum.charAt(n)); //插入数值
Ziro= n==0;
}
if(n==0) sT.insert(0, '零'); //小于1元
return sT.toString();
}
public static void main(String[] args){
RMBtoCHINESE cm = new RMBtoCHINESE();
String n;
n="0.01"; System.out.println(n+": "+cm.R2C(n));
n="101000.78"; System.out.println(n+": "+cm.R2C(n));
n="100010100.09"; System.out.println(n+": "+cm.R2C(n));
n="10000000000001.90"; System.out.println(n+": "+cm.R2C(n));
n="900000000000000000000000.00"; System.out.print(n+": "+cm.R2C(n));
}
}运行结果:
0.01: 零元零壹分
101000.78: 壹拾万壹仟元柒角捌分
100010100.09: 壹亿零壹万零壹佰元零玖分
10000000000001.90: 壹拾万亿零壹元玖角整
900000000000000000000000.00: 玖仟万亿亿元整
package lihan; public class MoneyUtil { /** 大写数字 */
private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
"柒", "捌", "玖" };
/** 整数部分的单位 */
private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰",
"仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" };
/** 小数部分的单位 */
private static final String[] DUNIT = { "角", "分", "厘" }; /**
* 得到大写金额。
*/
public static String toChinese(String str) {
str = str.replaceAll(",", "");// 去掉","
String integerStr;// 整数部分数字
String decimalStr;// 小数部分数字 // 初始化:分离整数部分和小数部分
if (str.indexOf(".") > 0) {
integerStr = str.substring(0, str.indexOf("."));
decimalStr = str.substring(str.indexOf(".") + 1);
} else if (str.indexOf(".") == 0) {
integerStr = "";
decimalStr = str.substring(1);
} else {
integerStr = str;
decimalStr = "";
}
// integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去)
if (!integerStr.equals("")) {
integerStr = Long.toString(Long.parseLong(integerStr));
if (integerStr.equals("0")) {
integerStr = "";
}
}
// overflow超出处理能力,直接返回
if (integerStr.length() > IUNIT.length) {
System.out.println(str + ":超出处理能力");
return str;
} int[] integers = toArray(integerStr);// 整数部分数字
boolean isMust5 = isMust5(integerStr);// 设置万单位
int[] decimals = toArray(decimalStr);// 小数部分数字
return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals);
} /**
* 整数部分和小数部分转换为数组,从高位至低位
*/
private static int[] toArray(String number) {
int[] array = new int[number.length()];
for (int i = 0; i < number.length(); i++) {
array[i] = Integer.parseInt(number.substring(i, i + 1));
}
return array;
} /**
* 得到中文金额的整数部分。
*/
private static String getChineseInteger(int[] integers, boolean isMust5) {
StringBuffer chineseInteger = new StringBuffer("");
int length = integers.length;
for (int i = 0; i < length; i++) {
// 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元)
// 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元)
String key = "";
if (integers[i] == 0) {
if ((length - i) == 13)// 万(亿)(必填)
key = IUNIT[4];
else if ((length - i) == 9)// 亿(必填)
key = IUNIT[8];
else if ((length - i) == 5 && isMust5)// 万(不必填)
key = IUNIT[4];
else if ((length - i) == 1)// 元(必填)
key = IUNIT[0];
// 0遇非0时补零,不包含最后一位
if ((length - i) > 1 && integers[i + 1] != 0)
key += NUMBERS[0];
}
chineseInteger.append(integers[i] == 0 ? key
: (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
}
return chineseInteger.toString();
} /**
* 得到中文金额的小数部分。
*/
private static String getChineseDecimal(int[] decimals) {
StringBuffer chineseDecimal = new StringBuffer("");
for (int i = 0; i < decimals.length; i++) {
// 舍去3位小数之后的
if (i == 3)
break;
chineseDecimal.append(decimals[i] == 0 ? ""
: (NUMBERS[decimals[i]] + DUNIT[i]));
}
return chineseDecimal.toString();
} /**
* 判断第5位数字的单位"万"是否应加。
*/
private static boolean isMust5(String integerStr) {
int length = integerStr.length();
if (length > 4) {
String subInteger = "";
if (length > 8) {
// 取得从低位数,第5到第8位的字串
subInteger = integerStr.substring(length - 8, length - 4);
} else {
subInteger = integerStr.substring(0, length - 4);
}
return Integer.parseInt(subInteger) > 0;
} else {
return false;
}
} public static void main(String[] args) {
String number = "54452";
System.out.println(number + " " + MoneyUtil.toChinese(number));
number = "30200";
System.out.println(number + " " + MoneyUtil.toChinese(number));
number = "30000.05";
System.out.println(number + " " + MoneyUtil.toChinese(number));
number = "30000.00";
System.out.println(number + " " + MoneyUtil.toChinese(number));
} }
http://topic.csdn.net/u/20080125/16/e525de9d-e92f-44b9-8a8c-ea86a08f084b.html?seed=1677933837
package PrintOperate;import java.text.NumberFormat;
import java.util.HashMap;public class SimpleMoneyFormat
{ public static final String EMPTY = "";
public static final String ZERO = "零";
public static final String ONE = "壹";
public static final String TWO = "贰";
public static final String THREE = "叁";
public static final String FOUR = "肆";
public static final String FIVE = "伍";
public static final String SIX = "陆";
public static final String SEVEN = "柒";
public static final String EIGHT = "捌";
public static final String NINE = "玖";
public static final String TEN = "拾";
public static final String HUNDRED = "佰";
public static final String THOUSAND = "仟";
public static final String TEN_THOUSAND = "万";
public static final String HUNDRED_MILLION = "亿";
public static final String YUAN = "元";
public static final String JIAO = "角";
public static final String FEN = "分";
public static final String DOT = ".";
private static SimpleMoneyFormat formatter = null;
private HashMap chineseNumberMap = new HashMap();
private HashMap chineseMoneyPattern = new HashMap();
private NumberFormat numberFormat = NumberFormat.getInstance(); private SimpleMoneyFormat()
{
numberFormat.setMaximumFractionDigits(4);
numberFormat.setMinimumFractionDigits(2);
numberFormat.setGroupingUsed(false); chineseNumberMap.put("0", ZERO);
chineseNumberMap.put("1", ONE);
chineseNumberMap.put("2", TWO);
chineseNumberMap.put("3", THREE);
chineseNumberMap.put("4", FOUR);
chineseNumberMap.put("5", FIVE);
chineseNumberMap.put("6", SIX);
chineseNumberMap.put("7", SEVEN);
chineseNumberMap.put("8", EIGHT);
chineseNumberMap.put("9", NINE);
chineseNumberMap.put(DOT, DOT); chineseMoneyPattern.put("1", TEN);
chineseMoneyPattern.put("2", HUNDRED);
chineseMoneyPattern.put("3", THOUSAND);
chineseMoneyPattern.put("4", TEN_THOUSAND);
chineseMoneyPattern.put("5", TEN);
chineseMoneyPattern.put("6", HUNDRED);
chineseMoneyPattern.put("7", THOUSAND);
chineseMoneyPattern.put("8", HUNDRED_MILLION);
} public static SimpleMoneyFormat getInstance()
{
if (formatter == null)
{
formatter = new SimpleMoneyFormat();
}
return formatter;
} public String format(String moneyStr)
{
checkPrecision(moneyStr);
String result;
result = convertToChineseNumber(moneyStr);
result = addUnitsToChineseMoneyString(result);
return result;
} public String format(double moneyDouble)
{
return format(numberFormat.format(moneyDouble));
} public String format(int moneyInt)
{
return format(numberFormat.format(moneyInt));
} public String format(long moneyLong)
{
return format(numberFormat.format(moneyLong));
} public String format(Number moneyNum)
{
return format(numberFormat.format(moneyNum));
} private String convertToChineseNumber(String moneyStr)
{
String result;
StringBuffer cMoneyStringBuffer = new StringBuffer();
for (int i = 0; i < moneyStr.length(); i++)
{
cMoneyStringBuffer.append(chineseNumberMap.get(moneyStr.substring(i, i + 1)));
}
//拾佰仟万亿等都是汉字里面才有的单位,加上它们
int indexOfDot = cMoneyStringBuffer.indexOf(DOT);
int moneyPatternCursor = 1;
for (int i = indexOfDot - 1; i > 0; i--)
{
cMoneyStringBuffer.insert(i, chineseMoneyPattern.get(EMPTY + moneyPatternCursor));
moneyPatternCursor = moneyPatternCursor == 8 ? 1 : moneyPatternCursor + 1;
} String fractionPart = cMoneyStringBuffer.substring(cMoneyStringBuffer.indexOf("."));
cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf("."), cMoneyStringBuffer.length());
while (cMoneyStringBuffer.indexOf("零拾") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零拾"), cMoneyStringBuffer.indexOf("零拾") + 2, ZERO);
}
while (cMoneyStringBuffer.indexOf("零佰") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零佰"), cMoneyStringBuffer.indexOf("零佰") + 2, ZERO);
}
while (cMoneyStringBuffer.indexOf("零仟") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零仟"), cMoneyStringBuffer.indexOf("零仟") + 2, ZERO);
}
while (cMoneyStringBuffer.indexOf("零万") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零万"), cMoneyStringBuffer.indexOf("零万") + 2, TEN_THOUSAND);
}
while (cMoneyStringBuffer.indexOf("零亿") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零亿"), cMoneyStringBuffer.indexOf("零亿") + 2, HUNDRED_MILLION);
}
while (cMoneyStringBuffer.indexOf("零零") != -1)
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零零"), cMoneyStringBuffer.indexOf("零零") + 2, ZERO);
}
if (cMoneyStringBuffer.lastIndexOf(ZERO) == cMoneyStringBuffer.length() - 1)
{
cMoneyStringBuffer.delete(cMoneyStringBuffer.length() - 1, cMoneyStringBuffer.length());
}
cMoneyStringBuffer.append(fractionPart); result = cMoneyStringBuffer.toString();
return result;
} private String addUnitsToChineseMoneyString(String moneyStr)
{
String result;
StringBuffer cMoneyStringBuffer = new StringBuffer(moneyStr);
int indexOfDot = cMoneyStringBuffer.indexOf(DOT);
cMoneyStringBuffer.replace(indexOfDot, indexOfDot + 1, YUAN);
cMoneyStringBuffer.insert(cMoneyStringBuffer.length() - 1, JIAO);
cMoneyStringBuffer.insert(cMoneyStringBuffer.length(), FEN);
if (cMoneyStringBuffer.indexOf("零角零分") != -1)//没有零头,加整
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零角零分"), cMoneyStringBuffer.length(), "整");
}
else if (cMoneyStringBuffer.indexOf("零分") != -1)//没有零分,不输出零分,也不加整
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零分"), cMoneyStringBuffer.length(), "");
}
else if (cMoneyStringBuffer.indexOf("零角") != -1)
{
if(cMoneyStringBuffer.indexOf("零角")==(cMoneyStringBuffer.length()-4))
{
cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零角"), cMoneyStringBuffer.indexOf("零角") + 2, ZERO);
}
else
{
cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf("零角"), cMoneyStringBuffer.indexOf("零角") + 2);
}
}
result = cMoneyStringBuffer.toString();
return result;
} private void checkPrecision(String moneyStr)
{
int fractionDigits = moneyStr.length() - moneyStr.indexOf(DOT) - 1;
if (fractionDigits > 2)
{
throw new RuntimeException("金额" + moneyStr + "的小数位多于两位。"); //精度不能比分低
}
} public static void main(String args[])
{
System.out.println(getInstance().format(new Double(70052080.70)));
}
}
package ch07;public class MoneyUtil1 { /** 大写数字 */
private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
"柒", "捌", "玖" };
/** 整数部分的单位 */
private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰",
"仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" };
/** 小数部分的单位 */
private static final String[] DUNIT = { "角", "分", "厘" }; /**
* 得到大写金额。
*/
public static String toChinese(String str) {
str = str.replaceAll(",", "");// 去掉","
String integerStr;// 整数部分数字
String decimalStr;// 小数部分数字 // 初始化:分离整数部分和小数部分
if (str.indexOf(".") > 0) {
integerStr = str.substring(0, str.indexOf("."));
decimalStr = str.substring(str.indexOf(".") + 1);
} else if (str.indexOf(".") == 0) {
integerStr = "";
decimalStr = str.substring(1);
} else {
integerStr = str;
decimalStr = "";
}
// integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去)
if (!integerStr.equals("")) {
integerStr = Long.toString(Long.parseLong(integerStr));
if (integerStr.equals("0")) {
integerStr = "";
}
}
// overflow超出处理能力,直接返回
if (integerStr.length() > IUNIT.length) {
System.out.println(str + ":超出处理能力");
return str;
} int[] integers = toArray(integerStr);// 整数部分数字
boolean isMust5 = isMust5(integerStr);// 设置万单位
int[] decimals = toArray(decimalStr);// 小数部分数字
return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals);
} /**
* 整数部分和小数部分转换为数组,从高位至低位
*/
private static int[] toArray(String number) {
int[] array = new int[number.length()];
for (int i = 0; i < number.length(); i++) {
array[i] = Integer.parseInt(number.substring(i, i + 1));
}
return array;
} /**
* 得到中文金额的整数部分。
*/
private static String getChineseInteger(int[] integers, boolean isMust5) {
StringBuffer chineseInteger = new StringBuffer("");
int length = integers.length;
for (int i = 0; i < length; i++) {
// 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元)
// 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元)
String key = "";
if (integers[i] == 0) {
//System.out.println(i+":"+(length - i));
if ((length - i) == 13)// 万(亿)(必填)
key = IUNIT[4];
else if ((length - i) == 9)// 亿(必填)
key = IUNIT[8];
else if ((length - i) == 5 && isMust5)// 万(不必填)
key = IUNIT[4];
else if ((length - i) == 1)// 元(必填)
key = IUNIT[0];
// 0遇非0时补零,不包含最后一位
else if ((length - i) > 1 && integers[i + 1] != 0)
{key += NUMBERS[0];
//System.out.println(i+":"+key);
}
}
chineseInteger.append(integers[i] == 0 ? key
: (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
}
return chineseInteger.toString();
} /**
* 得到中文金额的小数部分。
*/
private static String getChineseDecimal(int[] decimals) {
StringBuffer chineseDecimal = new StringBuffer("");
for (int i = 0; i < decimals.length; i++) {
// 舍去3位小数之后的
if (i == 3)
break;
chineseDecimal.append(decimals[i] == 0 ? ""
: (NUMBERS[decimals[i]] + DUNIT[i]));
}
return chineseDecimal.toString();
} /**
* 判断第5位数字的单位"万"是否应加。
*/
private static boolean isMust5(String integerStr) {
int length = integerStr.length();
if (length > 4) {
String subInteger = "";
if (length > 8) {
// 取得从低位数,第5到第8位的字串
subInteger = integerStr.substring(length - 8, length - 4);
} else {
subInteger = integerStr.substring(0, length - 4);
}
return Integer.parseInt(subInteger) > 0;
} else {
return false;
}
} public static void main(String[] args) {
String number = "54452";
System.out.println(number + " " + MoneyUtil1.toChinese(number));
number = "300120030200";
System.out.println(number + " " + MoneyUtil1.toChinese(number));
number = "301001.05";
System.out.println(number + " " + MoneyUtil1.toChinese(number));
number = "30000.20";
System.out.println(number + " " + MoneyUtil1.toChinese(number));
number = "305020300200.02";
System.out.println(number + " " + MoneyUtil1.toChinese(number));
} }
1.数据结构设计(单位和数字两个数组下标之间的关系);2.特殊位置的处理(圆,万,亿,万)通过%4可以达到目的;3.判断前面是否读了0,定义变量preReadZero来说明。