准备跳槽,找了网上的笔试题看了一下, 发现常考金额转换成大写的编程题。

网上给出的答案不太满意,iteye上搜索一下, 有不少人给出一些例子,很多转换结果不准确,还有人说不到30行代码就能完成,我一看代码,天书而已, 立马摒弃掉了。
     思考一番, 也写了下代码,测试也没问题,有兴趣的朋友可以提提意见。

网上其他人的代码大多是只能转换整数最多13位,一般转换方案都是下面两种(第一种看完都不想再当码农了 ,第二种看似挺好, 但是处理起来截取字符串麻烦,容易因规则太复杂找不到出路):

String capUnit[] = {'万','亿','万','圆',''};
String capDigit[][] = { {''},{''},{'角','分',''},{''} {'仟','佰','拾',''}};
String capNum[]={'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};     
String big = "壹贰叁肆伍陆柒捌玖";
String digit = new Array("圆拾佰仟万拾佰仟亿拾佰仟万","角分");

 
   我自己写的代码方案与第一种差不多,思路绝对清晰明了,代码里写得很清楚:

  

package com.liany.demo.translate;import java.math.BigDecimal;
import java.text.DecimalFormat;/*** 金额转换成大写* @author modiliany* @date 2012-04-10*/
public class TransformMoney {/*
以下摘自百度百科:http://baike.baidu.com/view/359995.htm
大写数字规则中文大写金额数字应用正楷或行书填写,如壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整(正)等字样。不得用一、二(两)、三、四、五、六、七、八、九、十、廿、毛、另(或0)填写,不得自造简化字。如果金额数字书写中使用繁体字,如贰、陆、亿、万、圆的,也可。中文大写金额数字到"元"为止的,在"元"之后,应写"整"(或"正")字,在"角"之后,可以不写"整"(或"正")字。大写金额数字有"分"的,"分"后面不写"整"(或"正")字。中文大写金额数字前应标明"人民币"字样,大写金额数字有"分"的,"分"后面不写"整"(或"正")字。中文大写金额数字前应标明"人民币"字样,大写金额数字应紧接"人民币"字样填写,不得留有空白。大写金额数字前未印"人民币"字样的,应加填"人民币"三字。在票据和结算凭证大写金额栏内不得预印固定的"仟、佰、拾、万、仟、佰、拾、元、角、分"字样。阿拉伯数字小写金额数字中有"0"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。举例如下:阿拉伯数字中间有"0"时,中文大写要写"零"字,如¥1409.50,应写成人民币壹仟肆佰零玖元伍角。阿拉伯数字中间连续有几个"0"时,中文大写金额中间可以只写一个"零"字,如¥6007.14,应写成人民币陆仟零柒元壹角肆分。阿拉伯金额数字万位和元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写金额中可以只写一个零字,也可以不写"零"字。如¥1680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分,又如¥107000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分。阿拉伯金额数字角位是"0",而分位不是"0"时,中文大写金额"元"后面应写"零"字。如¥16409.02,应写成人民币壹万陆仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元零肆分。
*/static final String big = "零壹贰叁肆伍陆柒捌玖";        //大写static final String[] units = {"仟佰拾", "角分"};   //单位/*** 双精度浮点数转换成字符串* 注:* 1、如果直接用String.toString(double d)方法,超大数额会出现科学计数法的字符串;* 2、如果整数部分超过15位数,低位部分可能出现误差,所以不支持超过15位整数的数值,*   一般数据库设计金额字段时都不会超过15位整数,如oracle用Number(18,3)的类型表示,整数部分最多15位,小数点后保留3位有效数字。*/public static String getDecimalStr(double d){//设置小数点后的精度,保留两位/*四舍五入结果参考:0.005,//0.01入0.015,//0.01舍0.025,//0.03入0.035,//0.04入0.045,//0.04舍0.055,//0.06入(前一位是5则入)*/String str = new BigDecimal(d).setScale(2, BigDecimal.ROUND_HALF_UP).toString();/*//经过测试,以下三种方法都是可以用的://或1:String str = new BigDecimal(d).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();//或2:DecimalFormat format = new DecimalFormat();format.applyPattern("#################0.00");String str = format.format(d);//或3:DecimalFormat decimalFormat = new DecimalFormat();  decimalFormat.setMinimumFractionDigits(2);  decimalFormat.setMaximumFractionDigits(2);  decimalFormat.setGroupingUsed(false);  decimalFormat.setMaximumIntegerDigits(15);  decimalFormat.setMinimumIntegerDigits(15);  str=decimalFormat.format(d); *///如果结果是整数,则去掉尾巴if(str.endsWith(".00")){str = str.replace(".00", "");}return str;}/*** 金额是double类型的要先转换成字符串* @param money 金额*/public static String transform(double money){String moneyStr = getDecimalStr(money);return transform(moneyStr);}/*** 金额转换成大字* 我的思路:* 1、double数值转换成数值字符串* 2、处理整数部分:*   填充到16位,不足16位则前面补'0',然后右起分成四组,每组根据"x仟x佰x拾x"的规则转换成大写,若该组为"0000"则结果是"零";*   对这四组结果从高位到低位拼接起来,规则:[组4]万[组3]亿[组2]万[组1]圆。* 3、处理小数部分(不多说)*/public static String transform(String moneyStr){String[] parts = moneyStr.split("\\.");    //区别整数、小数部分String result = "";//处理整数部分int length = parts[0].length();   //整数部分的位数if(length>15){return "金额太大,不能处理整数部分超过15位的金额!";}String intPart = parts[0];//填充到16位,因为是分4组,每组4个数字while(intPart.length()<16){intPart = '0' + intPart;}//共分四组,右起四位一组,例如:0001,2003,0030,3400String[] groups = new String[4]; for(int i=0; i < groups.length; i++){int start = intPart.length()-(i+1)*4;   //开始位置int end = intPart.length()-i*4;          //结束位置groups[i] = intPart.substring(start, end);groups[i] = transformGroup(groups[i]);    //当前组的四位数字转换成大写}//对这四组结果从高位到低位拼接起来,规则:[组4]万[组3]亿[组2]万[组1]圆for(int i=groups.length-1; i>=0; i--){if(i==3){  //第四组:万亿级if(!"零".equals(groups[i])){result += groups[i] + "万";}}else if(i==2){  //第三组:亿级if(!"零".equals(groups[i])){result += groups[i] + "亿";}else{if(result.length()>0){result += "亿";}}}else if(i==1){ //第二组:万级if(!"零".equals(groups[i])){result += groups[i] + "万";}else if(!groups[i].startsWith("零")){result += groups[i];} }else{    //第一组:千级if(!"零".equals(groups[i]) || result.length()==0){result += groups[i];}result += "圆";}}if(!"零圆".equals(result) && result.startsWith("零")){result = result.substring(1, result.length()); //最前面的可能出现的“零”去掉}//处理小数部分if(parts.length==2){String decimalPart = parts[1];    //小数部分for(int i=0; i < decimalPart.length();i++){int num = Integer.valueOf(decimalPart.charAt(i) + "");   //提取数字,左起result += big.charAt(num) + "" + units[1].charAt(i);  //数字变大写加上单位}result = result.replace("零角", "零");    //去掉"零角"的"角"result = result.replace("零分", ""); //去掉"零分"}else{result += "整";  //没有小数部分,则加上“整”}return result;}/*** 处理整数部分的组,右起每四位是一组* @param group 四位数字字符串*/public static String transformGroup(String group){String result = "";int length = group.length();for(int i=0; i < length; i++){int digit = Integer.valueOf(group.charAt(i)+"");   //单个数字,左起String unit = "";    //单位if(i!=length-1){unit = units[0].charAt(i) + "";    }result += big.charAt(digit) + unit; //数字变大写加上单位}result = result.replace("零仟", "零");result = result.replace("零佰", "零");result = result.replace("零拾", "零");while(result.contains("零零")){result = result.replace("零零", "零"); //如果有“零零”则变成一个“零”}if(!"零".equals(result) && result.endsWith("零")){result = result.substring(0, result.length()-1); //最未尾的可能出现的“零”去掉}return result;}/*** @param args*/public static void main(String[] args) {double[] testData = {//测试数据一0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000d,100000000000d,1000000000000d,10000000000000d,100000000000000d,//测试数据二110000000000000d,101000000000000d,100100000000000d,100010000000000d,100001000000000d,100000100000000d,100000010000000d,100000001000000d,100000000100000d,100000000010000d,100000000001000d,100000000000100d,100000000000010d,100000000000001d,//测试数据三101010101010101d,100100100100100d,100100010010001d,100100001000010d,100001000001000d,100010000100010d,111111111111111d,123456789012345d,//测试数据四(含小数)0.00,0.005,//0.01(转换成字符串后)0.015,//0.010.025,//0.030.035,//0.040.045,//0.040.055,//0.061.384,10.125,100.02,1000.045,10000.055,100000.1,1000000.11,10000000.10,100000000.105,1000000000.010,//测试数据五(整数超过15位)1000000000000000d,1000000000000000.01d};for(double money : testData){String moneyStr = getDecimalStr(money);System.out.println( moneyStr + ":" + transform(moneyStr));}}
}//打印结果:
/*
0:零圆整
1:壹圆整
10:壹拾圆整
100:壹佰圆整
1000:壹仟圆整
10000:壹万圆整
100000:壹拾万圆整
1000000:壹佰万圆整
10000000:壹仟万圆整
100000000:壹亿圆整
1000000000:壹拾亿圆整
10000000000:壹佰亿圆整
100000000000:壹仟亿圆整
1000000000000:壹万亿圆整
10000000000000:壹拾万亿圆整
100000000000000:壹佰万亿圆整
110000000000000:壹佰壹拾万亿圆整
101000000000000:壹佰零壹万亿圆整
100100000000000:壹佰万壹仟亿圆整
100010000000000:壹佰万零壹佰亿圆整
100001000000000:壹佰万零壹拾亿圆整
100000100000000:壹佰万零壹亿圆整
100000010000000:壹佰万亿壹仟万圆整
100000001000000:壹佰万亿零壹佰万圆整
100000000100000:壹佰万亿零壹拾万圆整
100000000010000:壹佰万亿零壹万圆整
100000000001000:壹佰万亿壹仟圆整
100000000000100:壹佰万亿零壹佰圆整
100000000000010:壹佰万亿零壹拾圆整
100000000000001:壹佰万亿零壹圆整
101010101010101:壹佰零壹万零壹佰零壹亿零壹佰零壹万零壹佰零壹圆整
100100100100100:壹佰万壹仟零壹亿零壹拾万零壹佰圆整
100100010010001:壹佰万壹仟亿壹仟零壹万零壹圆整
100100001000010:壹佰万壹仟亿零壹佰万零壹拾圆整
100001000001000:壹佰万零壹拾亿壹仟圆整
100010000100010:壹佰万零壹佰亿零壹拾万零壹拾圆整
111111111111111:壹佰壹拾壹万壹仟壹佰壹拾壹亿壹仟壹佰壹拾壹万壹仟壹佰壹拾壹圆整
123456789012345:壹佰贰拾叁万肆仟伍佰陆拾柒亿捌仟玖佰零壹万贰仟叁佰肆拾伍圆整
0:零圆整
0.01:零圆零壹分
0.01:零圆零壹分
0.03:零圆零叁分
0.04:零圆零肆分
0.04:零圆零肆分
0.06:零圆零陆分
1.38:壹圆叁角捌分
10.13:壹拾圆壹角叁分
100.02:壹佰圆零贰分
1000.04:壹仟圆零肆分
10000.06:壹万圆零陆分
100000.10:壹拾万圆壹角
1000000.11:壹佰万圆壹角壹分
10000000.10:壹仟万圆壹角
100000000.11:壹亿圆壹角壹分
1000000000.01:壹拾亿圆零壹分
1000000000000000:金额太大,不能处理整数部分超过15位的金额!
1000000000000000:金额太大,不能处理整数部分超过15位的金额!
*/

个人觉得代码宜读、宜于维护才是最重要,转换大写这个小功能没有必要追求什么超高性能。

人民币金额小写转换大写相关推荐

  1. 人民币金额小写转大写

    @echo off setlocal EnableDelayedExpansion set tbl1=零壹贰叁肆伍陆柒捌玖 set tbl2=分角元拾佰仟万拾佰仟亿拾佰仟 :test_ setloca ...

  2. Python TIPS上一道关于人民币金额小写转大写的题

    仅适用于亿元以下 题目链接:here.我发现我写的好复杂,但万幸编码还算符合人类,看了其他答案,感觉都是天书啊,都太追求简洁和技巧了,我们只能learn python with the hardway ...

  3. 在Excel中将人民币金额小写转成大写(转)

    在Excel中将人民币金额小写转成大写(转)[@more@] Excel中要将人民币小写金额转换成大写格式,将自定义格式类型中的"G/通用格式"改为"G/通用格式&quo ...

  4. Excel中将人民币金额小写转成大写(转)

    Excel中将人民币金额小写转成大写(转) Excel中要将人民币小写金额转换成大写格式,将自定义格式类型中的"G/通用格式"改为"G/通用格式"元" ...

  5. 小写转换大写(人民币)

    小写转换大写(人民币) 实现原理: 将小写数字转换成对应的大写数字.(数字数组) 将级别插在对应的大写数字后面.(级别数组) 组合称字符串. 小写转大写规律: 0123456789    零壹贰叁肆伍 ...

  6. C#人民币金额大小写转换

    C#人民币金额大小写转换 在财务相关的软件的时候,常常设计到大小写金额的转换,小编整理了自己常用的数字金额大小写转换的方法代码 给大家参考如下: /// <summary> /// 金额小 ...

  7. Oracle实现金额小写转大写函数

    Oracle实现金额小写转大写函数 今天工作的时候遇到了,于是上网百度了一下,发现了有个大佬写了一个很牛的函数,在此记录下来. 原文:http://www.itpub.net/thread-24028 ...

  8. jQuery金额小写转大写

    jQuery金额小写转大写 金额转换 金额转换 /*金额小写转大写*/ function smalltoBIG(n) {var fraction = ['角', '分'];var digit = [' ...

  9. C语言判断字符是否为数字 如果是输出yes 如果为字母 则大写转换小写 小写转换大写

    #include <stdio.h>int main(void) {char ch;printf("input a char:");ch=getchar();//判断c ...

  10. 人民币金额大小写转换函数

    [转帖]人民币金额大小写转换函数 Function NtoC( n0 :Extended) :wideString; //人民币金额大小写转换函数(如发现更为精简的,请告诉我) //作者:方小庆(上海 ...

最新文章

  1. java script 6 折线_Java入门第六篇:Java script(js)的事件
  2. 封装函数 f,使 f 的 this 指向指定的对象
  3. mysql 优化器_mysql之优化器、执行计划、简单优化
  4. c语言静态函数调用静态变量_C语言中的静态变量和函数
  5. 认识安全测试之SQL注入
  6. pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host=”files.pythonhosted.org“,
  7. Ubuntu12.04安装配置Nginx Tomcat环境
  8. Windows 上安装 Scala
  9. 微信公众号开发及h5分享兼容性问题总结
  10. [原创摄影]西藏行(一)从不同角度看布达拉
  11. window启动activemq失败
  12. 低代码真的是“行业毒瘤”?
  13. input框禁止输入空格
  14. 绝地求生组装电脑配置推荐2021 适合玩吃鸡游戏电脑清单
  15. 为什么8G运行内存的电脑,开几个WORD文档,运行内存就被占满了,WPS很占用内存吗
  16. 大端模式和小端模式的详细区别
  17. mobiscroll插件滑动时间选择效果
  18. 元素和小于等于阈值的正方形的最大边长(来源:力扣(LeetCode))
  19. 少年得志中年入狱,李一男能再造一个“四轮的小牛”吗?
  20. LeetCode 刷题记录 77. Combinations

热门文章

  1. MM眉心为什么会长痘痘
  2. 文件上传到ftp服务器命令,ftp上传文件到服务器命令
  3. liteon460w服务器电源管理系统,【LITEON PS-2112-5L 1200W C6100 C6220 C6220I服务器电源】价格_厂家 - 中国供应商...
  4. 重复渐变过渡 百分比
  5. 如何添加PR视频特效?
  6. Python学习笔记之小派读诗
  7. PS4 安装 Linux系统
  8. 基于单片机的智能家居环境监控系统的设计
  9. 造成增长停滞的各种原因
  10. 致远OA表单自定义函数(明细表去重拼接)