美文网首页
数字的英文表达和中文表达

数字的英文表达和中文表达

作者: chengcongyue | 来源:发表于2019-04-17 20:47 被阅读0次

    题目

    给定一个32位的整数num,写两个函数分别返回它的英文表达和中文表达字符串.
    然后我们来看看几个例子.


    图片.png

    笔者已经将最复杂的数字进行了分析,这个值是Integer.MIN_VALUE,如图Two Billion,One Hundred Forty Seven Million,.......Thousand,Six Hundred Forty Eight.我们注意到其中基本都是1---999的数字然后在加上Million,Thousand这些单位,这样的话,我们的首要目的就是找出1---999的数字表达.

    1---19的英文表达

    我们可以通过枚举的方式,将所有19个可能性放入到一个String数组中去,十分简单,如下图:

    public static String num1To19(int num)
        {
            if(num<1||num>19)
            {
                return "";
            }
            String[] names={"One ","Two ","Three ","Four ","Five ","Six ","Seven ","Eight ","Nine ",
            "Ten ","Eleven ","Twelve ","Thirteen ","Fourteen ","Fifteen ","Sixteen ","Seventeen ",
            "Eightteen ","Nineteen "
            };
            return names[num-1];
        }
    

    当我们传入16是,就找出这个数组中16-1,下标为15的表达.十分简单,现在完成了1---19的表达,然后我们来完成1---99的表达,我们通过/运算得到十位,用一个数组来承担,然后通过%运算得到低位,然后使用num1to19来表达

    public static String num1To99(int num)
        {
            if(num<1||num>99)
            {
                return "";
            }
            if(num<20)
            {
                return num1To19(num);
            }
            int high=num/10;
            String[] tyNames={"Twenty ","Thirty ","Forty ","Fifty ","Sixty ","Seventy ","Eighty "
                    ,"Ninety "};
            return tyNames[high-2]+num1To19(num%10);
        }
    

    依次类推,我们现在知道了1---99的表达,然后我们通过/和%运算就可以得到1---999的表达了,但是要注意,在中间加上,"Hundred".

    //1---999
        public static String num1To999(int num)
        {
            if(num<1||num>999)
            {
                return "";
            }
            if(num<100)
            {
                return num1To99(num);
            }
            int high=num/100;
            return num1To19(high)+"hundred "+num1To99(num%100);
        }
    

    然后就是主函数了.
    我们先把代码贴上来,然后再去分析为什么这样写

    public static String getNumEngExp(int num)
        {
            if(num==0)
            {
                return "Zero";
            }
            String res="";
            if(num<0)
            {
                res="Negative, ";
            }
            if(num==Integer.MIN_VALUE)
            {
                res+="Two Billion,";
                num%=-2000000000;
            }
            num=Math.abs(num);//求绝对值
            int high=1000000000;
            int highIndex=0;
            String[] names={"Billion","Million","Thousand",""};
            while(num!=0)
            {
                int cur=num/high;
                System.out.println(cur);
                num%=high;
                if(cur!=0)
                {
                    res+=num1To999(cur);
                    res+=names[highIndex]+(num==0?" ":", ");
                }
                high/=1000;
                highIndex++;
            }
            return res;
        }
    
    • 第一步判断num是不是0,如果是0的话直接返回num
    • 第二步判断是不是负数,如果num<0,我们家在操作之前加上negative,
    • 重点来了,我们这儿为什么要将Integer.MIN_VALUE单另的拿出来做判断.
      因为如果不做处理的话,将Integer.MIN_VALUE转化成整数的话,就会溢出,我们举个例子.
            System.out.println(Integer.MAX_VALUE);
            System.out.println(Integer.MIN_VALUE);
    

    就是简单了两句代码,我们知道MAX_VALUE指的是32位有符号正整数的最大位置,如果这个位置加1的话就会溢出,结果运行结果如下:


    图片.png

    所以这就是我们要对Integer.MIN_VALUE进行单独处理的原因.
    先得到他的最高位,然后取模,得到他除了最高位的数,然后进行循环.

    • 然后就是循环了,我们再把循环贴出来
    while(num!=0)
            {
                int cur=num/high;//1000000000
                System.out.println(cur);
                num%=high;
                if(cur!=0)
                {
                    res+=num1To999(cur);
                    res+=names[highIndex]+(num==0?" ":", ");
                }
                high/=1000;
                highIndex++;
            }
            return res;
    

    我们以Integer.MAX_VALUE为例,第一次遍历得到的cur为2,然后得到它的次高位等待.每次都要选出三位来,如果我们每次要选出一位出来,那就/10,如果一次要选出两位出来那就/100,所以这里我们要/1000,每次/1000,就可以选出3位,同时最开始的high的设值,0的个数一定是3的倍数,这道题就是9个零.
    同时我们要注意/和%的协作运算.加深印象,我们在这道题中,在重新写一下

    num=Math.abs(num);
    int high=1000000000;
    while(num!=0)
    {
          cur=num/high;
          num=num%high;
          if(cur!=0)
         {
              res+=num1To999(cur);
              加上位数 
         } 
         high/=1000;
         highIndex++;
    }
    

    然后就是中文的表达

    图片.png

    我们注意到中文时4位为一次重复,然后修改其后面的单位即可.
    直接贴代码了

    public static String num1To9(int num)
        {
            if(num<1||num>9)
            {
                return "";
            }
            String[] names={"一","二","三","四","五","六","七","八","九"};
            return names[num-1];
        }
        
        public static String num1To99(int num,boolean hasBai)
        {
            if(num<1||num>99)
            {
                return "";
            }
            if(num<10)
            {
                return num1To9(num);
            }
            //得到高位
            int shi=num/10;
            if(shi==1&&(!hasBai))//如果有百位的情况  三百一十九
            {
                return "十"+num1To9(num%10);
            }else
            {
                return num1To9(shi)+"十"+num1To9(num%10);
            }
        }
        
        public static String num1To999(int num)
        {
            if(num<1||num>999)
            {
                return "";
            }
            if(num<100)
            {
                return num1To99(num,false);
            }
            String res=num1To9(num/100)+"百";
            int rest=num%100;
            if(rest==0)
            {
                return res;
            }else if(rest>=10)
            {
                res+=num1To99(rest,true);
            }else
            {
                res+="零"+num1To9(rest);
            }
            return res;
        }
        
        public static String num1To9999(int num)
        {
            if(num<1||num>9999)
            {
                return "";
            }
            if(num<1000)
            {
                return num1To999(num);
            }
            String res=num1To9(num/1000)+"千";
            int rest=num%1000;
            if(rest==0)
            {
                return res;
            }else if(rest>=100)
            {
                res+=num1To999(rest);
            }else
            {
                res+="零"+num1To99(rest, false);
            }
            return res;
        }
        
        public static String num1To99999999(int num)
        {
            if(num<1||num>99999999)
            {
                return "";
            }
            int wan=num/10000;
            int rest=num%10000;
            if(wan==0)
            {
                return num1To9999(rest);
            }
            String res=num1To9999(wan)+"万";
            if(rest==0)
            {
                return res;
            }else
            {
                if(rest<1000)
                {
                    return res+"零"+num1To999(rest);
                }else
                {
                    return res+num1To9999(rest);
                }
            }
        }
        public static String getNumChiExp(int num)
        {
            if(num==0)
            {
                return "零";
            }
            String res=num<0?"负":"";
            int yi=Math.abs(num/100000000);
            int rest=Math.abs(num%100000000);
            if(yi==0)
            {
                return res+num1To99999999(rest);
            }
            res+=num1To9999(yi)+"亿";
            if(rest==0)
            {
                return res;
            }else
            {
                if (rest < 10000000) {
                    return res + "零" + num1To99999999(rest);
                } else {
                    return res + num1To99999999(rest);
                }
            }
        }
        public static String getNumChiExp2(int num)
        {
            if(num==0)
            {
                return "零";
            }
            String res=num<0?"负":"";
            int high=100000000;
            int highIndex=0;
            if(num==Integer.MIN_VALUE)
            {
                res+=num1To9999(num/high*-1)+"亿";
                num=num%high;
                highIndex++;
            }
            num=Math.abs(num);
            String[] names={"亿","万",""};
            while(num!=0)
            {
                int cur=num/high;
                num=num%high;
                if(cur!=0)
                {
                    res+=num1To9999(cur)+names[highIndex];
                }
                high/=10000;
                highIndex++;
            }
            return res;
        }
        public static void main(String[] args) {
            System.out.println(getNumChiExp2(323232));
            System.out.println(getNumChiExp(323232));
        }
    

    最后还有几句想说的,关于/和%的配合使用问题,如果想获得当前的位,那么就是用一个10000.....(总位数等于被除数),这是做/运算,如果是做%运算,上面的情况就是获取除当前位的其他位数.
    然后就是Integer.MAX_VALUE和Integer.MIN_VALUE,当处理比较大的数据时,就要考虑到溢出的情况,同时MAX_VALUE比MIN_VALUE的绝对值小1.

    相关文章

      网友评论

          本文标题:数字的英文表达和中文表达

          本文链接:https://www.haomeiwen.com/subject/vulowqtx.html