Java 打印一个描述整数的英文短语

Java 打印一个描述整数的英文短语,java,algorithm,Java,Algorithm,想要打印一个单词(0到999999之间)的英文表示形式,例如,对于1234,我想打印为“壹仟贰佰叁拾四”。找到了以下解决方案,但不确定第23行到第25行的逻辑含义。欢迎提供任何见解。谢谢 1 public static String numtostring(int num) { 2 StringBuilder sb = new StringBuilder(); 3 4 // Count number of digits in num. 5 int len = 1;

想要打印一个单词(0到999999之间)的英文表示形式,例如,对于1234,我想打印为“壹仟贰佰叁拾四”。找到了以下解决方案,但不确定第23行到第25行的逻辑含义。欢迎提供任何见解。谢谢

 1 public static String numtostring(int num) {
 2    StringBuilder sb = new StringBuilder();
 3
 4    // Count number of digits in num.
 5    int len = 1;
 6    while (Math.pow((double)10, (double)len ) < num) {
 7       len++;
 8    }
 9
10    String[] wordarr1 = {“”,”One ”, “Two ”, “Three ”, “Four ”,
11       “Five ”, “Six ”, “Seven ”, “Eight ”,”Nine ”};
12    String[] wordarr11 = {“”, “Eleven ”, “Twelve ”, “Thirteen ”,
13       “Fourteen ”, “Fifteen ”, “Sixteen ”,
14       “Seventeen ”, “Eighteen ”, “Nineteen ”};
15    String[] wordarr10 = {“”,”Ten ”, “Twenty ”, “Thirty ”, “Forty ”,
16    “Fifty ”, “Sixty ”, “Seventy ”, “Eighty ”,
17    “Ninety “};
18    String[] wordarr100 = {“”, “Hundred ”, “Thousand ”};
19    int tmp;
20    if (num == 0) {
21       sb.append(“Zero”);
22    } else {
23       if (len > 3 && len % 2 == 0) {
24          len++;
25       }
26       do {
27          // Number greater than 999
28          if (len > 3) {
29             tmp = (num / (int)Math.pow((double)10,(double)len-2));
30             // If tmp is 2 digit number and not a multiple of 10
31             if (tmp / 10 == 1 && tmp%10 != 0) {
32                sb.append(wordarr11[tmp % 10]) ;
33             } else {
34                sb.append(wordarr10[tmp / 10]);
35                sb.append(wordarr1[tmp % 10]);
36             }
37             if (tmp > 0) {
38                sb.append(wordarr100[len / 2]);
39             }
40             num = num % (int)(Math.pow((double)10,(double)len-2));
41             len = len-2;
42          } else { // Number is less than 1000
43             tmp = num / 100;
44             if (tmp != 0) {
45                sb.append(wordarr1[tmp]);
46                sb.append(wordarr100[len / 2]);
47             }
48             tmp = num % 100 ;
49             if(tmp / 10 == 1 && tmp % 10 != 0) {
50                sb.append(wordarr11[tmp % 10]) ;
51             } else {
52                sb.append(wordarr10[tmp / 10]);
53                sb.append(wordarr1[tmp % 10]);
54             }
55             len = 0;
56          }
57       } while(len > 0);
58    }
59    return sb.toString();
60 }
1公共静态字符串numtostring(int num){
2 StringBuilder sb=新StringBuilder();
3.
4//计算num中的位数。
5 int len=1;
6 while(数学功率((双)10,(双)len)3&&len%2==0){
24 len++;
25       }
26做{
27//大于999的数字
28如果(长度>3){
29 tmp=(num/(int)数学功率((double)10,(double)len-2));
30//如果tmp是2位数字,而不是10的倍数
31如果(tmp/10==1&&tmp%10!=0){
32 sb.追加(wordarr11[tmp%10]);
33}其他{
34 sb.追加(第10字[tmp/10]);
35 sb.追加(wordarr1[tmp%10]);
36             }
37如果(tmp>0){
38某人附加(字arr100[len/2]);
39             }
40 num=num%(int)(数学功率((双)10,(双)len-2));
41 len=len-2;
42}否则{//数字小于1000
43 tmp=num/100;
44如果(tmp!=0){
45某人附加(字arr1[tmp]);
46某人附加(字arr100[len/2]);
47             }
48 tmp=num%100;
49如果(tmp/10==1&&tmp%10!=0){
50某人追加(wordarr11[tmp%10]);
51}其他{
52 sb.追加(wordarr10[tmp/10]);
53 sb.追加(wordarr1[tmp%10]);
54             }
55 len=0;
56          }
57}时(len>0);
58    }
59把某人送回弦上();
60 }

您正在谈论此代码段:

if (len > 3 && len % 2 == 0) {
   len++;
}
这意味着如果len大于3(显然!),如果len是一个数字

%
符号用于

维基百科对模运算的定义是:

在计算中,模运算找到除法后的余数 一个数乘以另一个数(有时称为模数)

更新

关于此代码段背后的逻辑。我只会尝试猜测原始作者的意图。
len
变量将保存数字的长度

如果长度小于100,则作者将在
}中创建所需字符串,否则{//Number小于1000
块。如果您更好地看到此代码段,则永远不会使用
len
变量,除非最后他将其设为等于零以退出循环

因此,对于<999的数字,决不使用
len

现在,对于大于1000的数字,使用它,我想作者需要更改它,以便将其用于阵列访问。这就是为什么使用第23行到第25行。因此,对于1000到9999
len
是4,对于10000到99999
len
是5,对于100000到99999
len
是6。我想在不更改它的情况下,作者是6uldn无法访问所需的数组值。这是我猜测此代码用于的原因

但是,我从给定的字符串中猜测,对于0到999999的数字,该方法应该可以正常工作。请尝试以下想法:

int err = 0;
for(int i = 0;i<999999;i++) {
        try {
             numtostring(i);
        } catch (Exception e){                
            err++;
        }            
    }
System.out.println(err+" ERORRS");
您还可以通过使用
n
作为参数再次调用
numtostring()
并将其附加到
sb
来消除
do-while
循环

无论如何,在使用它之前自己测试一下,确保我没有忘记任何东西:)我希望我帮了你一点忙

更新2

好的,我们讨论的原始方法对于长度小于3的数字有效。对于4位和5位数字有效,但对于6位数字中的一位无效

让我们看看如何使用
len

   if (len > 3 && len % 2 == 0) {
      // if len is 4 it becomes 5, if it is 5 it stays as is
      // if len is 6 it becomes 7 and an exception occurs
      len++;
   }
   ...
   if (len > 3) {
         // puts the thousand part in tmp
         // so if num is 9000, len is 5 and tmp is 9 (9000/10^3)
         // if num is 99000, len is 5 and tmp is 99 (99000/10^3)
         // and if num is 999000, len is 7 and tmp is 9 instead of 999 (999000/10^5)
         tmp = (num / (int)Math.pow((double)10,(double)len-2));
         // If tmp is 2 digit number and not a multiple of 10
         // So, if tmp is 11 to 19 (num was 11000 to 19999) it enters the if
         if (tmp / 10 == 1 && tmp%10 != 0) {
            // if tmp is 11 tmp % 10 is 1 and the wordarr11[1] is eleven etc.
            sb.append(wordarr11[tmp % 10]) ;
         } else {
            // if tmp is not 11 to 19 it enters here
            // this means if tmp is 1 to 9 for num 1000 to 9999
            // if tmp is 10 for num 10000 to 10999
            // if tmp is 20 to 99 for num 20000 to 99999
            // if tmp is 100 to 999 for num 100000 to 999999

            // wordarr10 contains the dozens
            // if tmp is 10 this will be ten, if it is 20 this will be twenty etc.
            // if tmp is 1 to 9 tmp / 10 will return 0 and sb will append an empty string (wordarr10[0])
            sb.append(wordarr10[tmp / 10]);

            // wordarr1 contains the units
            // if tmp is 1 to 9 then tmp % 10 will return the tmp as it is
            // if tmp is 10 or 20 tmp % 10 will return 0 and append the empty string
            // if tmp is 23 tmp % 10 will return 3 and append the word three
            sb.append(wordarr1[tmp % 10]);
         }
         // if tmp is a positive numbers... we know it is but ok...
         // we append the word hundrend if len is 2 or three, which is impossible because we are in the if(len > 3) branch
         // if original len was 4 it have become 5 earlier so
         // if len is 5 the len / 2 is 2 and we append the word thousand
         // if len is 7 len / 2 is 3 and an out of bounds exception gets thrown
         if (tmp > 0) {
            sb.append(wordarr100[len / 2]);
         }
         // finally we remove the part of num that we have printed in order to print the rest
         // so if num is 1123 then it will become 123
         // or if it is 12123 it will become again 123 (because len is 5)
         // if len is 7 this will fail and for example 123123 will become 23123
         num = num % (int)(Math.pow((double)10,(double)len-2));
         // if len is 5 then we make it three in order to run the else branch and print the rest part
         // if len was 7 this would make it 5 and the same branch would run again which I guess is also wrong
         len = len-2;
整个混乱或多或少是由这两条线造成的:

tmp = (num / (int)Math.pow((double)10,(double)len-2));
num = num % (int)(Math.pow((double)10,(double)len-2));
他们最好使用
1000
而不是
(int)Math.pow((double)10,(double)len-2)
。然后剩下的部分或多或少会像else部分一样。请参阅我的第一次更新,我在修订的代码中这样做

最后,还有另一个问题。正如我之前所说,对于1000,再次出现了一个异常。发生这种情况是因为长度计数错误

int len = 1;
while (Math.pow((double)10, (double)len ) < num) {
   len++;
}
int len=1;
while(数学功率((双)10,(双)len)
对于1000,它将返回
len=3
,但是对于1001,它将返回
len=4
。对于10000,它将返回
len=4
,但是对于10001,它将返回
len=5


如果您有具体问题,请询问:)

我想,这是代替(或补充)在描述java语言时,问题是为什么在这种情况下会增加一个
len
。啊……你可能是对的:)我会再看一看代码,并尝试提供一个答案:)@LinMa原始代码见Update2。
len-=String.valueOf(n).length();
用于获取n的长度,因此else分支将在do while循环的第二次迭代中执行
int len = 1;
while (Math.pow((double)10, (double)len ) < num) {
   len++;
}