zoukankan      html  css  js  c++  java
  • 将一个数转化为中文金额的大写方式(有详细的解题步骤)

      1 /*
      2  * 程序目的: 从命令行输入一个数,并将其转化为中文金额的大写方式 
      3  * 思路:
      4  * 所需对象:用到两个数组,一个存中文大写的数字,一个存金额单位;
      5  *          为了保持精度的相对准确,用到BigDecimal类;(不懂的朋友,上网一查就知道了);
      6  *          我这里用了StringBuilder类来存转化后的结果;(其实用String,StringBuffer都可以)
      7  * 过程:输入一个double类型的数———>转化为BigDecimal类的对象———>四舍五入后转化为long类型的数;
      8  *     先判断一下小数部分出现的特殊情况;
      9  *     统一处理数字;(每次取一位【用%10的方法】,通过和预先设置好的数组对应的方式来填充数据)
     10  *     输出最终的结果;
     11  * 难点:就零的处理;
     12  * 
     13  * 1、阿拉伯数字中间有“0”时,中文大写要写“零”字,如¥1409.50应写成人民币壹仟肆佰零玖元伍角;
     14   2、阿拉伯数字中间连续有几个“0”时、中文大写金额中间可以只写一个“零”字,如¥6007.14应写成人民币陆仟零柒元壹角肆分。
     15   3、阿拉伯金额数字万位和元位是“0”,或者数字中间连续有几个“0”,万位、元位也是“0”但千位、角位不是“0”时,中文大写金额中可以只写一个零字(我这这里用的就是这种),也           可以不写“零”字,如¥1680.32应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分。又如¥107000.53应写成人民币壹拾万柒仟元零伍角叁分,或          者写成人民币壹拾万零柒仟元伍角叁分。
     16   4、阿拉伯金额数字角位是“0”而分位不是“0”时,中文大写金额“元”后面应写“零”字,如¥16409.02应写成人民币壹万陆仟肆佰零玖元零贰分,又如¥325.04应写成人民币叁佰贰拾           伍元零肆分。
     17  * 
     18  * 方法:分情况处理;
     19  * 注:其实可以更加简洁写,但是为了看的更清楚,更加具有良好的编程习惯;故有些写的“啰嗦”,请见谅!
     20  *       若发现我的程序有不妥之处,还望评论指正,共同学习;
     21  */
     22 
     23 import java.math.BigDecimal;
     24 import java.util.Scanner;
     25 
     26 public class NumToCn {
     27     
     28     //这里使用String, StringBuffer其实都可以;但从可变长度和单线程方面考虑,StringBuilder较为合适;
     29     private static StringBuilder sb = new StringBuilder();
     30     
     31     private static final String[] CN_NUMBER = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
     32     private static final String[] CN_UNIT  = { "分", "角", "圆","拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾", "佰",                                                  "仟", "顺" };
     33 
     34     //一些额外附加的字符
     35     private static final String CN_NEGATIVE = "负";
     36     private static final String CN_FULL = "整";
     37     private static final String CN_ZERO_FULL = "零圆整";
     38     private static final int PERCISION = 2; // 精度
     39     
     40     public static String numToCn (BigDecimal numOfMoney) {
     41         
     42         //当此 BigDecimal 的值为负、零或正时,返回 -1、0 或 1。
     43         int signum = numOfMoney.signum();
     44         
     45         //若输入为0,输出零圆整;
     46         if(signum == 0) {
     47             return CN_ZERO_FULL;
     48         }
     49         
     50         //对金额进行四舍五入转化为long类型的整数;先将数的小数点向右移两位,然后在四舍五入,取绝对值,最后将它转换为长整型;
     51         long number = numOfMoney.movePointRight(PERCISION).setScale(0, BigDecimal.ROUND_HALF_UP).abs().longValue();
     52         int numIndex = 0; //记录数字的个数;
     53         boolean getZero = false;
     54 /*
     55  * 思路:要先判断一下小数部分的具体情况;究其根本是因为:小数部分和整数部分在处理“0”的问题上略有不同;避免出现如图1所示的情况;
     56  */
     57         //得到小数部分(小数点后两位);
     58         long scale = number % 100;
     59         if(scale == 0) { //若小数部分为"00"时的情况;骚年,不要忘了在最后追加特殊字符:整
     60             numIndex += 2;
     61             getZero = true;
     62             number /= 100;  // 从number去掉为0数;
     63             sb.append(CN_FULL);
     64         } else if(scale % 10 == 0){ //若小数部分为"*0"时的情况;
     65             numIndex += 1;
     66             getZero = true;
     67             number /= 10;// 从number去掉为0数;
     68         }
     69         
     70         //排除上述两种小数部分的特殊情况,则对小数和整数的处理就是一样一样一样地了!
     71         while(true) {
     72             //循环结束条件;
     73             if(number <= 0){
     74                 break;
     75             }
     76             
     77             //每次通过取余来得到最后一位数;
     78             int numUnit = (int)(number % 10);
     79             if(numUnit != 0){
     80                 sb.insert(0, CN_UNIT[numIndex]);  //先添加单位
     81                 sb.insert(0, CN_NUMBER[numUnit]); //在添加根据数字值来对应数组中的中文表述;
     82                 getZero = false; //表明当前数不是0;
     83             }
     84             else {
     85                 //意思是它的上一次的数不是零,那么打印出零;
     86                 if(!getZero) {
     87                     sb.insert(0, CN_NUMBER[numUnit]);
     88                 }
     89                 //若角分位为零,那么打印零;
     90                 if(numIndex == 2) {
     91                      if(number > 0) {
     92                          sb.insert(0, CN_UNIT[numIndex]);
     93                      }
     94                 } else if((numIndex - 2) % 4 == 0 && number % 1000 !=0 ) { //第一个条件是为了每隔4位,打印“圆,万,亿”;第二个条件是为了避免出现如图3的情况;
     95                     sb.insert(0, CN_UNIT[numIndex]);
     96                 }
     97                 getZero = true; //将其置为true,那么如果下一位还是0,也不会再打印一遍'零';避免出现图2的情况;
     98             }
     99             
    100          // 从number每次都去掉最后一个数
    101             number  = number / 10;
    102             numIndex++;
    103         }
    104         
    105         // 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
    106         if(signum == -1) {
    107             sb.insert(0, CN_NEGATIVE);
    108         }
    109         
    110         return sb.toString();
    111     }
    112     
    113     
    114     public static void main(String[] args) {
    115         Scanner scan = new Scanner(System.in);
    116         double money =  scan.nextDouble();
    117         BigDecimal numOfMoney = new BigDecimal(money);
    118         String s = NumToCn.numToCn(numOfMoney);
    119         System.out.println(s);
    120     }
    121 
    122 }

    图一:

    图二:

    图三:上边数是100000000;因为是测试时用的,所以会是图中所示,不用纠结;

    如果我引用您的博文记录,没有指出,请求您的原谅。可以私信告诉我,我一定改正! 注:我写博文的目的主要是记录得失,若有什么误人子弟的地方,请多多见谅指正;
  • 相关阅读:
    Ado.net继续学习_人力管理系统开发
    ASP.Net中
    接口实例_模拟简单的播放器解码插件扩展
    JQuery 学习进阶
    android UI进阶之仿iphone的tab效果
    Windows 8 Metro Stype App 学习笔记(五)文件操作
    Windows 8 学习笔记(六)—Accelerormeter和GeoLocation
    mmap如何使用?
    Android自定义组合控件
    Android系列开发博客资源汇总
  • 原文地址:https://www.cnblogs.com/zhaojinxin/p/5402757.html
Copyright © 2011-2022 走看看