中文汉字转阿拉伯数字

1、中文汉字转阿拉伯数字

参考
思路:地位向高位遍历,每遇到一个数,乘以当前单位,累加在 res 上,遇到单位则改变当前单位

//可以处理十万以下
public class change {
    public static void main(String[] args) {

        String s="一千零三";
        int res=Chinese2Num(s);
        System.out.println(res);

    }
    public static int Chinese2Num(String s){
        Map<Character,Integer>number_map=new HashMap<Character, Integer>(){
            {
                put('零',0);
                put('一',1);
                put('二',2);
                put('三',3);
                put('四',4);
                put('五',5);
                put('六',6);
                put('七',7);
                put('八',8);
                put('九',9);
            }
        };
        Map<Character,Integer>unit_map=new HashMap<Character,Integer>(){
            {
                put('十',10);
                put('百',100);
                put('千',1000);
                put('万',10000);
                put('亿',100000000);
            }
        };
        int res=0;
        int unit=1;//当前一段数的单位
        int num=0;//当前一段数
        for(int i=s.length()-1;i>=0;i--){
            Character c=s.charAt(i);
            if(number_map.containsKey(c)){
                num=number_map.get(c);
                res+=num*unit;
            }else{
                unit=unit_map.get(c);
            }
        }
        return res;
    }
}

以上问题:处理不了万以上的数,比如"一十二万",被解析成了 2*10000 + 1*10
(另外,口语中说“十二万”,没法处理十,会得到20000

解决:我们需要在遍历到万位时,记录当前的单位是万,后面的单位再乘以万

//可以处理十亿以下
int res=0;
int unit=1;//当前一段数的单位
int ten_thousand_unit = 1;//万、亿的单位
int num=0;//当前一段数
for(int i=s.length()-1;i>=0;i--){
    Character c=s.charAt(i);
    if(number_map.containsKey(c)){
        num=number_map.get(c);
        res+=num*unit;
    }else{
        unit=unit_map.get(c);//十万的话,unit可能为“十”
        //判断万和亿
        if(unit%10000==0) ten_thousand_unit=unit;//遇到万,当前标志就为万
        if(unit<ten_thousand_unit) unit=ten_thousand_unit*unit;
    }
}

如果想处理十亿,百亿,千亿这些亿以上的单位,我们需要让代码在判断出万位的时候,朝前面单位看一下,如果有一个比它还大的单位(即亿)时,就把它们乘起来。

long res=0;
long unit=1;//当前一段数的单位
long ten_thousand_unit = 1;//万、亿的单位
long num=0;//当前一段数
for(int i=s.length()-1;i>=0;i--){
    Character c=s.charAt(i);
    if(number_map.containsKey(c)){
        num=number_map.get(c);
        res+=num*unit;
    }else{
        unit=unit_map.get(c);
        //判断万和亿
        if(unit%10000==0){//遇到万
            if(unit>ten_thousand_unit) ten_thousand_unit=unit;//比万大,即亿
            else{
                ten_thousand_unit = unit * ten_thousand_unit;//万*亿
                unit = ten_thousand_unit;
            }
        }
        if(unit<ten_thousand_unit) unit=ten_thousand_unit*unit;

2、阿拉伯数字转中文

参考1
参考2
特殊情况:

  1. 11,如果按照一个数字一个单位去放的话,这个数字会变成一十一,但是我们需要显示十一,所以需要排除当十位数是一且只有两位数字的时候,去掉前面的一。

  2. 1001,中间有多个零,我们转换成中文数字的时候只需要一个汉字零,比如我们应该是一百零一,而不是一百零零一,所以需要在循环中去除重复的零。

  3. 1000,还有这种情况去除重复的零后,会变成一千零,所以我们还得把最后一位是零且不只有零的这种情况的时候,去掉末尾的汉字零。

public class NumberUtils {
    private final static String[] GROUP_UNITS = {"", "万", "亿", "兆"};
    private final static String[] BASE_UNITS = { "", "十", "百", "千" };
    private final static char[] SIMPLIFIED_NUMBERIC = { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' };
    private final static char[] TRADITIONAL_NUMBERIC = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };

    /**
     * 转为中文数字
     * @param number 数值
     * @param isTraditional 是否转为繁体
     * @return
     */
    public static String toChinese(long number, boolean isTraditional){
        char[] numberic = isTraditional ? TRADITIONAL_NUMBERIC : SIMPLIFIED_NUMBERIC;

        if(number==0){//判断是否为0
            return String.valueOf(numberic[0]);
        }

        String str = String.valueOf(number);
        char[] numbers = str.toCharArray();
        int len = str.length();
        //统计连续出现的0
        int zeroCount = 0;

        StringBuffer stringBuffer = new StringBuffer();
        for(int i = 0; i<len ;i++){
            int value = Integer.parseInt(String.valueOf(numbers[i]));
            int index = len - i - 1;
            //在分组中的下标
            int _index  = index % 4;
            if(value == 0){
                zeroCount++;
                if((_index == 0 && zeroCount < 4 ) || (index % 8 == 0 && zeroCount < 8)){
                    stringBuffer.append(getGroupUnit(index));
                    zeroCount = 0;
                }
            }
            else{
                if(zeroCount > 0){
                    stringBuffer.append(numberic[0]);
                }
                if(_index == 0){
                    stringBuffer.append(numberic[value] + BASE_UNITS[_index] + getGroupUnit(index));
                    zeroCount = 0;
                }
                else{
                    //调整以“一十”开头的不需要出现“一” 如:100000 读“十万”而不是“一十万”
                    if(_index == 1 && i==0 && value== 1){
                        stringBuffer.append(BASE_UNITS[_index]);
                    }
                    else{
                        stringBuffer.append(numberic[value] + BASE_UNITS[_index]);
                    }
                }
                zeroCount = 0;
            }
        }
        return stringBuffer.toString();
    }

    /**
     * 获取分组单位
     * @param index
     * @return
     */
    private static String getGroupUnit(int index){
        String groupUnit = GROUP_UNITS[(index / 4) % 2];
        if(index % 8 == 0 && index > 0){
            groupUnit += GROUP_UNITS[(index / 8) +1];
        }
        return groupUnit;
    }

//--------------------以下可以忽略------------------------------
    /**
     * 转为中文数字
     * @param number 数值
     * @return
     */
    public static String toChinese(long number){
        return toChinese(number, false);
    }

    /**
     * 转为中文数字
     * @param number 数值
     * @param isTraditional 是否转为繁体
     */
    public static String toChinese(int number, boolean isTraditional){
        return toChinese((long)number, isTraditional);
    }


    /**
     * 转为中文数字
     * @param number 数值
     */
    public static String toChinese(int number){
        return toChinese(number, false);
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值