阿拉伯数字金额转汉字大写

这篇博客分享了一段Java代码,用于将阿拉伯数字转换为汉字的大写形式,支持0-1000亿的范围。代码包括三个类:CheckFormat用于检查输入合法性,Transform进行实际转换,而Client则作为程序入口读取数据并打印结果。作者指出这个任务比预期复杂,需要考虑汉字逻辑。提供了一些测试结果,并表示代码可供研究和指正。
摘要由CSDN通过智能技术生成
话不多说,直接上代码
  • 语言

    • Java
  • 代码功能说明

    • 实现对阿拉伯数字的汉字大写转换,范围:0 - 1000亿
    • 能够检测输入的字符内容,并给出提示信息
  • 代码结构

    • 三个类:
      • CheckFormat:检测输入的字符内容是否合法,是则送去进行转换,否则停止此次转换,给出提示信息,进入下一次转换
      • Transform:经过检测的无误信息会被送入该类中的transform()方法进行转换
      • Client:读入数据,创建对象,根据检查结果分流程序走向,打印结果最终结果。事实上没什么实际意义,仅包含一个main方法和一些提示信息
  • 要点

    • 一开始在写的时候并没有觉得有什么难的地方,但是发现输出一个非常符合汉字逻辑的结果并不像想的这么简单
  • 运行方法

    • CMD中用Java Client …data[ ]… 的方法运行
    • eclipse 中用Run Configuration输入转换数据 data[ ]
  • PS:
    代码是原创的,如果有哪位感兴趣完全可以拿去测试研究,鄙人才疏学浅,才学习了Java没多久,还望多多指教

  • 一些测试结果

!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  abc
错误类型:    输入非法字符!

----------无法转换,结束-----------



!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  @123
错误类型:    输入非法字符!

----------无法转换,结束-----------



!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  +-*/
错误类型:    输入非法字符!

----------无法转换,结束-----------



!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  ===
错误类型:    输入非法字符!

----------无法转换,结束-----------



!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  313.35.263
错误类型:   输入多于一个小数点! 

----------无法转换,结束-----------



!!!!!!!!!输入数据错误!!!!!!!!!!

你的输入是:  24515375412423424.34
错误类型:  输入数字位数超过转换范围!

----------无法转换,结束-----------



警告!  输入多于两位小数, 两位以后的数据将被忽略!
你的输入是:    1698.36598
转换结果为: 人民币壹仟陆佰玖拾捌元叁角陆分

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    0
转换结果为: 人民币零元整

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    0.
转换结果为: 人民币零元整

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    0.00
转换结果为: 人民币零元整

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    0000.01
转换结果为: 人民币零壹分

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    0000.10
转换结果为: 人民币壹角

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    00001.00
转换结果为: 人民币壹元整

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    1000001.00
转换结果为: 人民币壹佰万零壹元整

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    100010001.01
转换结果为: 人民币壹亿零壹万零壹元零壹分

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    475503884.58
转换结果为: 人民币肆亿柒仟伍佰伍拾万叁仟捌佰捌拾肆元伍角捌分

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    685337146.23
转换结果为: 人民币陆亿捌仟伍佰叁拾叁万柒仟壹佰肆拾陆元贰角叁分

----------转换成功,完毕----------



********输入数据格式正确********* 

你的输入是:    37212175744.87
转换结果为: 人民币叁佰柒拾贰亿壹仟贰佰壹拾柒万伍仟柒佰肆拾肆元捌角柒分

----------转换成功,完毕----------


Resource

  1. CheckFormat.java
/*
 * input is evil! check the input!
 */

public class CheckFormat 
{

    boolean isFormatRight;
    int howManyDot;         //小数点个数
    int howManyAfterDot;    //小数的位数
    int howManyBeforeDot;   //整数的位数
    int howManyHeadZero;    //开头的无用0数
    String errorType;       //错误类型信息
    String warning;         //警告信息

    public CheckFormat()
    {
        isFormatRight = true;
        howManyDot = 0;
        howManyAfterDot = 0;
        howManyBeforeDot = 0;
        howManyHeadZero = 0;
        errorType = null;
        warning = null;
    }
    /*
     * 方法的返回值:
     *  true: 格式正确,或含有警告 
     *  false: 格式错误 
     */
    public boolean isRight(String stringData) 
    {
        for(int i = 0; i < stringData.length(); i++)
        {
            if(!Character.isDigit(stringData.charAt(i)) && stringData.charAt(i) != '.')//不是数字或者小数点,返回错误1
            {
                errorType = "错误类型:    输入非法字符!";
                isFormatRight = false;
            }
            if(stringData.charAt(i) == '.')//统计小数点的个数
            {
                howManyDot++;
                if(howManyDot > 1)
                {
                    errorType = "错误类型:   输入多于一个小数点! ";
                    isFormatRight = false;
                }
            }
            if(howManyDot == 1)//检测到一个小数点后开始统计小数后有多少位
            {
                howManyAfterDot++;
                if(howManyAfterDot > 3)
                {
                    warning = "警告!  输入多于两位小数, 两位以后的数据将被忽略!";
                }
            }
            if(howManyDot == 0)
            {
                howManyBeforeDot++;
            }
        }
        //在数据格式没有出错的前提下读出真正的有效数字有多少位,从而避免开头的0浪费转换位数!
        if(isFormatRight)
        {
            //统计开头的0有多少,用于判断真正有用的数据位数是否超过了转换范围
            for(int i = 0; i < stringData.length(); i++)
            {
                if(stringData.charAt(i) == '0')
                {
                    howManyHeadZero++;
                }
                if(stringData.charAt(i) != '0' || stringData.charAt(i) == '.')
                {
                    break;
                }
            }
            if((howManyBeforeDot - howManyHeadZero) > 12)
            {
                errorType = "错误类型:  输入数字位数超过转换范围!";
                isFormatRight = false;
            }
        }
        return isFormatRight;
    }
}
  1. Transform.java
import java.util.HashMap;
/*
 * 如果格式是正确的,根据有无小数,将整数部分和小数部分分开存储在两个数组内 分开转换后合并
 */
public class Transform 
{

    HashMap<Character,String> numbermap = new HashMap<Character,String>();//数字map
    HashMap<Integer,String> unitmap0 = new HashMap<Integer,String>();//一块以下的
    HashMap<Integer,String> unitmap1 = new HashMap<Integer,String>();//十白千
    HashMap<Integer,String> unitmap2 = new HashMap<Integer,String>();//元万亿

    //构造方法,多个方法进行操作的一定要设置为成员变量,且赋值要放在构造方法里
    //若赋值放在某一方法中,另一方法访问map将失败
    public Transform()
    {

        numbermap.put('0', "零");
        numbermap.put('1', "壹");
        numbermap.put('2', "贰");
        numbermap.put('3', "叁");
        numbermap.put('4', "肆");
        numbermap.put('5', "伍");
        numbermap.put('6', "陆");
        numbermap.put('7', "柒");
        numbermap.put('8', "捌");
        numbermap.put('9', "玖");

        unitmap2.put(0, "元");               
        unitmap2.put(1, "万");               
        unitmap2.put(2, "亿");

        unitmap1.put(1, "拾");
        unitmap1.put(2, "佰");
        unitmap1.put(3, "仟");

    }

    /*
     * 返回一个当前位置所应该具有的单位
     * 利用了汉字大写里四个为一个循环的特点
     * 单位特点:(元) 十 百 千 (万) 十 百 千 (亿)      
     *  location/4  取商
     *  location%4  取余
     */ 
    public String localUnit(int location)
    {       

        return location%4 != 0 ? unitmap1.get(location%4):unitmap2.get(location/4);
    }

    /*
     * 转换整数部分
     * 若结果是零,则返回null,非零值被正常转换
     */
    public StringBuffer intTransform(StringBuffer intpart)
    {       
        int newlength = 0;
        StringBuffer chineseString = null;

        //如果开头有0,删掉
        //捕获输入为0的时候删除操作产生的异常,捕获后返回空
        try
        {
            while(intpart.charAt(0) == '0')
            {
                intpart.deleteCharAt(0);
            }           
            newlength = intpart.length();//去掉开头的0之后新的字符长度
        }
        catch(StringIndexOutOfBoundsException e)
        {
            return null;   //这里必须返回,如果不返回,下面的转换将出现异常
        }

        chineseString = new StringBuffer(numbermap.get(intpart.charAt(0)) + localUnit(newlength - 1));

        //从buffer的第二个字符开始遍历,依次转换
        for(int i = 1; i < newlength; i++)
        {
            int location = newlength - i - 1;//单位的位置
                                             //i是数字的位置
            if(location % 4 != 0 && intpart.charAt(i) == '0')//千百十去掉单位,只保留0
            {
                chineseString = chineseString.append(numbermap.get(intpart.charAt(i)));
            }
            else
            {
                chineseString = chineseString.append(numbermap.get(intpart.charAt(i)) + localUnit(location));
            }
        }

        //连续0的处理
        //这里需要注意处理的顺序有前后,先处理多个零连在一起的情况!
        while(chineseString.indexOf("零零零零万") > 0)// > 0代表找到的意思
        {
            chineseString.replace(chineseString.indexOf("零零零零万"),chineseString.indexOf("零零零零万")+5,"零");
        }
        while(chineseString.indexOf("零零零") > 0)
        {
            chineseString.replace(chineseString.indexOf("零零零"),chineseString.indexOf("零零零")+3,"零");
        }
        while(chineseString.indexOf("零零") > 0 )
        {
            chineseString.replace(chineseString.indexOf("零零"),chineseString.indexOf("零零")+2,"零");
        }
        if(chineseString.indexOf("零万") > 0)
        {
            chineseString.replace(chineseString.indexOf("零万"),chineseString.indexOf("零万")+2,"万");
        }
        if(chineseString.indexOf("零元") > 0)
        {
            chineseString.replace(chineseString.indexOf("零元"),chineseString.indexOf("零元")+2,"元");
        }
        if(chineseString.indexOf("零亿") > 0)
        {
            chineseString.replace(chineseString.indexOf("零亿"),chineseString.indexOf("零亿")+2,"亿");
        }

        return chineseString;
    }

    //小数部分的转换,如果是0则返回null,最多只有两位,所以就逐位进行判断和转换
    public StringBuffer dotTransform(StringBuffer dotpart)
    {
        //输入数据格式合法但是超长,则剪掉用户输入的超过两位的部分
        int oldlength = dotpart.length();
        if(oldlength > 2)
        {
            dotpart.delete(2,oldlength);
        }

        int newlength = dotpart.length();//新长度,非1即2

        StringBuffer chineseString = null;

        if(newlength == 1)
        {
            chineseString = dotpart.charAt(0) == '0' ? null : new StringBuffer(numbermap.get(dotpart.charAt(0))).append("角");
        }
        if(newlength == 2)
        {
            if(dotpart.charAt(0) == '0')
            {
                chineseString = dotpart.charAt(1) == '0' ? null : new StringBuffer("零").append(numbermap.get(dotpart.charAt(1))).append("分");
            }
            else
            {
                chineseString = dotpart.charAt(1) == '0' ? new StringBuffer(numbermap.get(dotpart.charAt(0))).append("角") : new StringBuffer(numbermap.get(dotpart.charAt(0))).append("角").append(numbermap.get(dotpart.charAt(1))).append("分");
            }
        }   
        return chineseString;
    }

    //转换,判断输入数据的格式,将整数和小数分开转换,然后合到一起输出
    public StringBuffer transform(String data) 
    {
        StringBuffer databuff = new StringBuffer(data);
        int whereisdot = data.indexOf(".");
        int length = data.length();
        StringBuffer chineseCapital = null;

        if(whereisdot < 0)//完全是整数的形式
        {
            //如果在转换中捕获到异常则说明用户输入的全部都是0,则返回0元整
            //System.out.println("你进入了整数转换!");
            chineseCapital = intTransform(databuff) == null? new StringBuffer("零元整") : intTransform(databuff).append("整");
        }
        if(whereisdot > 0 && whereisdot == databuff.length() - 1)//小数点在末尾,删掉后直接调用整数转换方法
        {
            //System.out.println("你进入了末尾有小数点的转换");
            databuff.deleteCharAt(whereisdot);
            chineseCapital = intTransform(databuff) == null? new StringBuffer("零元整") : intTransform(databuff).append("整");
        }
        else if(whereisdot > 0 && whereisdot < databuff.length() - 1)//完整的小数
        {
            //System.out.println("你进入了完整的小数转换");
            StringBuffer intpart = null;
            StringBuffer dotpart = null;

            intpart = new StringBuffer(databuff.subSequence(0,whereisdot));//提取整数
            dotpart = new StringBuffer(databuff.subSequence(whereisdot + 1,length));//提取小数部分

            if(intTransform(intpart) == null)//整数为0
            {
                chineseCapital = dotTransform(dotpart) == null? new StringBuffer("零元整") : dotTransform(dotpart);
            }
            else//整数不为0
            {
                chineseCapital = dotTransform(dotpart) == null? intTransform(intpart).append("整") : intTransform(intpart).append(dotTransform(dotpart));
            }
        }
        return chineseCapital;
    }
}
  1. Client.java
public class Client
{
    public static void main(String[] args) 
    {

        for(String data : args)
        {
            CheckFormat check = new CheckFormat();  
            if(check.isRight(data))
            {
                Transform tran = new Transform();           
                if(check.warning == null)
                {
                    System.out.println("********输入数据格式正确********* "+"\n");
                }
                else
                {
                    System.out.println(check.warning);
                }
                System.out.print("你的输入是:    "+data+"\n"+"转换结果为: 人民币");
                System.out.print(tran.transform(data)+"\n\n"+"----------转换成功,完毕----------"+"\n\n\n\n");
            }
            else
            {
                System.out.println("!!!!!!!!!输入数据错误!!!!!!!!!!"+"\n");
                System.out.println("你的输入是:  "+data);
                System.out.print(check.errorType+"\n\n"+"----------无法转换,结束-----------"+"\n\n\n\n");
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值