文档章节

金额转换

徐航
 徐航
发布于 2014/08/04 09:53
字数 1801
阅读 106
收藏 0

@author  CeoiHong

答:首先分析数字的读法规则,将数字每四位一组,每组末尾连续的0读作 仟(如1000)、佰(100)、拾(10),非0数字之前的0读零,多个0只读一个零。

每四个数一组,组的单位从右往左依次是 : 一(不读)、萬、亿...这里不考虑更大的数。

当一组数全为0时,所处的位置不同,读法也不同。比如1010 0000 1010 中读零;1010 0000 0000 这里不读出来。

先确定每组数的读法,再确定该组的单位,最后将各组的读法连接起来即可。

 

每个四位数组先判断千位数是否为0,再判断百位数,再判断十位数,最后判断个位数。

这种四层嵌套判断比较麻烦,容易出错。所以在纸上画出判断的先后顺序会好理解点。

* 下面是判断的顺序:

 * 仟    佰    拾    个

 * 1    1    1    1    x仟x佰x拾x    ---x代表阿拉伯数字的中国传统写法,如 1 对应 壹

 * 1    1    1    0    x仟x佰x拾

 * 

 * 1    1    0    1    x仟x佰零x

 * 1    1    0    0    x仟x佰

 * 

 * 1    0    1    1    x仟零x拾x

 * 1    0    1    0    x仟零x拾

 * 

 * 1    0    0    1    x仟零x

 * 1    0    0    0    x仟

 * 

 * 0    1    1    1    x佰x拾x

 * 0    1    1    0    x佰x拾

 * 

 * 0    1    0    1    x佰零x

 * 0    1    0    0    x佰

 * 

 * 0    0    1    1    x拾x

 * 0    0    1    0    x拾

 * 

 * 0    0    0    1    x

 * 0    0    0    0    零/不读

 * 每个四位数组都只有这16中情况,将每种可能的情况进行判断后即可得到正确的读法。

 * 确定了单组的读法之后,组的排序不同又有不同的读法。针对不同单位内的读法,采取与上面相同的操作

 * 全为0的记为0,非全0的记为1,即又有以下几种可能情况:

 * 亿    萬    一

 * 1    1    1    x亿x萬x    ----x代表每4位数组的写法,如1034  对应 壹仟零叁拾肆

 * 1    1    0    x亿x萬

 * 1    0    1    x亿零x  ---如果最后一组数是0开头,则删除一个“零”

 * 1    0    0    x亿

 *         1    1    x萬x

 *         1    0    x萬

 *             1    x



public static void main(String[] args) {
        //关联输入流,读取键盘录入。
        Scanner sc = new Scanner(System.in);
        System.out.println("输入一个12位以内的数字,输入end结束:");
        //循环录入数据
        while(true){
            String input = sc.next();
            //如果输入数据是0开头,去掉数据头部的0
            String num = null;
            for(int i=0;i<input.length();i++){
                if(input.charAt(i) != '0'){
                    num = input.substring(i);
                    break;
                }
            }
            //输入数字长度超过12则跳过此次循环
            if(num.length() > 12){
                System.out.println("请输入12位以内的数字:");
                continue;
            }
            //输入end结束录入
            if(num.equals("end"))
                break;
            //解析该数字
            writeWithUnit(num);
        }
    }
    private static void writeWithUnit(String num) {
        //四位数一组,不足四位的也作为一组。
        int groups = (int) Math.ceil(num.length()/4.0);
        //创建一个和组数相同的字符串数组。
        String[] parts = new String[groups];
        //不足四位的第一组内数字个数,比如“123456”,第一组内存放“12”,第二组存放“3456”
        int firstGroup = num.length()%4;
        if(firstGroup != 0){
            for(int i=0;i<groups;i++){
                if(i==0){
                    parts[i] = num.substring(0, firstGroup);
                }else{
                    parts[i] = num.substring((i-1)*4 + firstGroup,i*4 + firstGroup);
                }
            }
        }else{
            //如果数字刚好可以被4整除,则每组放4个数字
            for(int i=0;i<groups;i++){
                    parts[i] = num.substring(i*4,(i+1)*4);
            }
        }
        StringBuffer sb = new StringBuffer();
        /**
         * 由于全0组的位置会影响单位和写法,所以采用和writeInTraditionalWay方法中相同的判断方法
         * 每组数中,四位全0的记为0,非全0 的记为1,在考虑的范围内(不考虑亿以上级别的数)的可能情况有下面几种。
         * 1    1    1
         * 1    1    0
         * 1    0    1
         * 1    0    0
         *         1    1
         *         1    0
         *             1
         * 依次对数字个数的不同进行判断。
         */
        //只有一组数时,即只有1~4位数
        if(groups == 1){
            sb.append(writeInTraditionalWay(parts[0]));
            //不满4位的在writeInTraditionalWay方法中在StringiBuffer对象首部添加了“零”,这里去掉首部的“零”。
            if(parts[0].length()<4){
                sb.deleteCharAt(0);
            }
        //当有两组数时,即有5~8位数
        }else if(groups == 2){
            sb.append(writeInTraditionalWay(parts[0])).append("萬");
            //在不足8位数时,即第一组数不足4位,在StringBuffer对象首部添加了“零”,要去掉首部的“零”。
            if(parts[0].length()<4){
                sb.deleteCharAt(0);
            }
            //第二组数如果不是全0,则添加到sb末尾,单位“一”省略不写。
            if(!parts[1].contains("0000"))
                sb.append(writeInTraditionalWay(parts[1]));
        //当有三组数时,即9~12位数
        }else if(groups == 3){
            sb.append(writeInTraditionalWay(parts[0])).append("亿");
            //在不足12位数时,即第一组数不足4位,在StringBuffer对象首部添加了“零”,要去掉首部的“零”。
            if(parts[0].length()<4){
                sb.deleteCharAt(0);
            }
            //如果第二组数不是全0,则添加到sb末尾,单位为“萬”
            if(!parts[1].contains("0000")){
                sb.append(writeInTraditionalWay(parts[1])).append("萬");
                //如果第三组数不全为0,则添加到sb末尾,单位为“一”,省略不写。
                if(!parts[2].contains("0000")){
                    sb.append(writeInTraditionalWay(parts[2]));
                }
            //如果第二组数全为0
            }else{
                //如果第三组数不全为0则添加到sb末尾,单位为“一”,省略不写。如果全为0时,不读。比如1234 0000 5678中的四个0不读出来。
                if(!parts[2].contains("0000")){
                    if(writeInTraditionalWay(parts[2]).startsWith("零")){
                        sb.append(writeInTraditionalWay(parts[2]));
                    }
                    sb.append(writeInTraditionalWay(parts[1])).append(writeInTraditionalWay(parts[2]));
                }
            }
        }
        //输出
        System.out.println(sb.toString());
    }
    //将一个单独的四位数组转换成传统写法
    public static String writeInTraditionalWay(String str){
        StringBuffer sb = new StringBuffer();
        int i = Integer.parseInt(str);
        //得到这个数的千位,百位,十位,个位的数
        int qianwei = i/1000;
        i = i%1000;
        int baiwei = i/100;
        i = i%100;
        int shiwei = i/10;
        i = i%10;
        int gewei = i;
        //千位不为0
        if(qianwei > 0){
            //写作x仟
            sb.append(baseNumber(qianwei)).append("仟");
            //百位也不为0
            if(baiwei > 0){
                //写作x仟x佰
                sb.append(baseNumber(baiwei)).append("佰");
                //十位不为0
                if(shiwei > 0){
                    //写作x仟x佰x拾
                    sb.append(baseNumber(shiwei)).append("拾");
                    //个位不为0
                    if(gewei > 0){
                        //写作x仟x佰x拾x,此时写法已经确定,返回该值。
                        return sb.append(baseNumber(gewei)).toString();
                    }else{
                        //个位为0,写作x仟x佰x拾,写法确定,返回。
                        return sb.toString();
                    }
                //十位为0
                }else{
                    if(gewei > 0){
                        //个位不为0,写作x仟零x,写法确定,返回。
                        return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();
                    }else{
                        //个位为0,写作,x仟x佰,写法确定,返回。
                        return sb.toString();
                    }
                }
            }else{//baiwei == 0  一下的判断和上面的判断类似。
                if(shiwei > 0){
                    sb.append(baseNumber(0)).append(baseNumber(shiwei)).append("拾");
                    if(gewei > 0){
                        return sb.append(baseNumber(gewei)).toString();
                    }else{
                        return sb.toString();
                    }
                }else{
                    if(gewei > 0){
                        return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();
                    }else{
                        return sb.toString();
                    }
                }
            }
        }else{
            if(baiwei > 0){
                sb.append(baseNumber(0)).append(baseNumber(baiwei)).append("佰");
                if(shiwei > 0){
                    sb.append(baseNumber(shiwei)).append("拾");
                    if(gewei > 0){
                        return sb.append(baseNumber(gewei)).toString();
                    }else{
                        return sb.toString();
                    }
                }else{
                    if(gewei > 0){
                        return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();
                    }else{
                        return sb.toString();
                    }
                }
            }else{
                if(shiwei > 0){
                    sb.append(baseNumber(0)).append(baseNumber(shiwei)).append("拾");
                    if(gewei > 0){
                        return sb.append(baseNumber(gewei)).toString();
                    }else{
                        return sb.toString();
                    }
                }else{
                    if(gewei > 0){
                        return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();
                    }else{
                        return sb.append(baseNumber(0)).toString();
                    }
                }
            }
        }
    }
    //返回基本数字的写法
    public static String baseNumber(int i){
        switch(i){
            case 0:
                return "零";
            case 1:
                return "壹";
            case 2:
                return "贰";
            case 3:
                return "叁";
            case 4:
                return "肆";
            case 5:
                return "伍";
            case 6:
                return "陆";
            case 7:
                return "柒";
            case 8:
                return "捌";
            case 9:
                return "玖";
            default:
                return null;
                
        }
    }


© 著作权归作者所有

下一篇: JAVASCRIPT
徐航
粉丝 15
博文 24
码字总数 16835
作品 0
武汉
程序员
私信 提问
【转载】C#工具类:人民币金额转换为中文大写

在涉及到金融业务这一块的系统设计中,时常能够遇到的情况是需要将阿拉伯数字的人民币金额自动转换为中文的大写金额。现在互联网上也有很多网站提供此类服务,只要你输入人民币的阿拉伯数字金...

江湖逍遥
03/29
0
0
【laravel-amount】Model 中自动转换金额的 Trait

背景 系统中涉及到金额的字段,View 层表现的时候一般都是以元为单位使用小数形式展示,不过 Domain 层存储时从空间、性能、容错角度出发,经常以分为单位,用整型来存储。 在 Lavarel 中,可...

haolisand
2016/09/17
0
0
golang实现人民币小写转大写

使用golang的正则表达式实现人民币小写转大写,代码如下: 上面代码执行结果如下(可以使用ConvertNumToCny函数输入任何转换金额作为参数): 我们对于大金额的数据经常需要数位数而降低了我...

知止software
2016/08/21
126
0
Excel数据表中的金额由“元”转换为“万元”的方法

Excel数据表中的金额由“元”转换为“万元”的方法 2012-05-23 09:33:16 分类: Office操作 标签:excel技巧 举报 字号 订阅 有下列Excel数据表,金额栏的单位为“元”,为简便起见,需将金额...

EDIAGD
2015/03/03
741
0
PHP ChineseUtil v1.1 新增中文数字、人民币大写转换

PHP 中文工具类 ChineseUtil,支持汉字转拼音、拼音分词、简繁互转、数字、金额大写; 本类库字典数据总共收录 73925 个汉字,包括:3955 个简体字,1761 个繁体字,68209 个其它汉字。 v1.1...

宇润
2018/12/17
970
6

没有更多内容

加载失败,请刷新页面

加载更多

VMware vSphere ESXi主机的访问控制

在vShpere中,访问ESXi主机的途径很多,如下: ESXi DCUI ESXi Shell ESXi SSH ESXi Host Client vCenter --> vSphere web client / vSphere Client VMware vSphere ESXi主机的访问控制,除了......

大别阿郎
23分钟前
3
0
大神讲解CGI、FastCGI和PHP-FPM关系图解

参考资料 概念了解:CGI,FastCGI,PHP-CGI与PHP-FPM:http://www.nowamagic.net/librarys/veda/detail/1319 php中fastcgi和php-fpm是什么东西:https://www.zybuluo.com/phper/note/50231 ......

网络小虾米
32分钟前
3
0
《DNS攻击防范科普系列3》 -如何保障 DNS 操作安全

引言 前两讲我们介绍了 DNS 相关的攻击类型,以及针对 DDoS 攻击的防范措施。这些都是更底层的知识,有同学就来问能否讲讲和我们的日常操作相关的知识点,今天我们就来说说和我们日常 DNS 操...

Mr_zebra
32分钟前
3
0
zk中ServerCnxn

实现接口Stats, Watcher 内部类 DisconnectReason CloseRequestException EndOfStreamException(流关闭) 属性 方法 getSessionTimeout 获取session失效时间 sendResponse 发送回复数据 se......

writeademo
37分钟前
3
0
如何将 Redis 用于微服务通信的事件存储

来源:Redislabs 作者:Martin Forstner 翻译:Kevin (公众号:中间件小哥) 以我的经验,将某些应用拆分成更小的、松耦合的、可协同工作的独立逻辑业务服务会更易于构建和维护。这些服务(也...

中间件小哥
41分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部