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

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

作者: 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