当前位置: 首页 > 知识库问答 >
问题:

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

罗浩然
2023-03-14

想打印一个单词(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个答案

关宏毅
2023-03-14

你说的是这个代码段:

if (len > 3 && len % 2 == 0) {
   len++;
}

这意味着如果len大于3(显然!)如果len是一个偶数。

%符号用于模运算。

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

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

更新

关于这个代码段背后的逻辑。我只想猜测原作者的意图。len变量将保存数字的长度。

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

所以,对于数字

现在,关于数字

但是,我从给定的字符串中猜测该方法应该可以用于0到999999之间的数字。试试这个想法:

int err = 0;
for(int i = 0;i<999999;i++) {
        try {
             numtostring(i);
        } catch (Exception e){                
            err++;
        }            
    }
System.out.println(err+" ERORRS");

这将打印900000个错误。它适用于1000和从100000到999999的所有数字。这两个案例无法从该代码中正确处理。我发现整个len操作非常麻烦,很难理解。我不确定作者是否还有别的想法。

这是一个修订版,它似乎适用于从0到999999的数字,我发现它更容易理解。

        public static String numtostring(int num) {
    StringBuilder sb = new StringBuilder();

    // Count number of digits in num.
    int len = String.valueOf(num).length();

    String[] wordarr1 = {"", "One ", "Two ", "Three ", "Four ",
        "Five ", "Six ", "Seven ", "Eight ", "Nine "};
    String[] wordarr11 = {"", "Eleven ", "Twelve ", "Thirteen ",
        "Fourteen ", "Fifteen ", "Sixteen ",
        "Seventeen ", "Eighteen ", "Nineteen "};
    String[] wordarr10 = {"", "Ten ", "Twenty ", "Thirty ", "Forty ",
        "Fifty ", "Sixty ", "Seventy ", "Eighty ",
        "Ninety "};
    int tmp;
    if (num == 0) {
        sb.append("Zero");
    } else if (num >= 1000000) {
        System.err.println("Numbers > 999999 are not supported!");
        System.exit(1);
    } else {
        do {
            // Number greater than 999
            if (len > 3) {
                int n = num / 1000;
                sb.append(numtostring(n)).append("Thousand ");
                num = num % 1000;
                len -= String.valueOf(n).length();
            } else { // Number is less than 1000
                tmp = num / 100;
                if (tmp != 0) {
                    sb.append(wordarr1[tmp]);
                    sb.append("Hundred ");
                }
                tmp = num % 100;
                if (tmp / 10 == 1 && tmp % 10 != 0) {
                    sb.append(wordarr11[tmp % 10]);
                } else {
                    sb.append(wordarr10[tmp / 10]);
                    sb.append(wordarr1[tmp % 10]);
                }
                len = 0;
            }
        } while (len > 0);
    }
    return sb.toString();
}

您还可以通过再次调用numtostring()n作为参数并将其附加到sb来消除do-while循环。

无论如何,在使用它之前自己测试一下,以确保我没有忘记任何事情:)我希望我对您有一点帮助!

更新2

好的,所以我们讨论的原始方法适用于具有长度的数字

让我们看看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)。然后剩下的就像其他部分或多或少。看到我的第一次更新,我在修改后的代码中这样做。

最后,还有另一个问题。正如我之前所说的,1000年后,再次出现了一个例外。这是因为长度计数错误。

int len = 1;
while (Math.pow((double)10, (double)len ) < num) {
   len++;
}

对于1000,它将返回len=3,但对于1001,它将返回len=4。对于10000,它将返回len=4,但对于10001,它将返回len=5

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

 类似资料:
  • 本文向大家介绍最短描述数,10的最短描述数是3^2+1^2所以是2,求一个数的最短描述数相关面试题,主要包含被问及最短描述数,10的最短描述数是3^2+1^2所以是2,求一个数的最短描述数时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 动态规划问题,参考牛客网“拼凑面额”题解

  • 主要内容:一个简短的英语自我介绍【篇1】,一个简短的英语自我介绍【篇2】,一个简短的英语自我介绍【篇3】,一个简短的英语自我介绍【篇4】,一个简短的英语自我介绍【篇5】,一个简短的英语自我介绍【篇6】,一个简短的英语自我介绍【篇7】,一个简短的英语自我介绍7篇 一个简短的英语自我介绍?其实一份好的自我介绍是很容易写好的,只要你把自己优秀的那一面展现出来,把自己的基本信息讲清楚就可以了。下面小编给大家带来了一个简短的英语自我介绍,供大家参考。 一个简短的英语自我介绍【篇1】 Dear teache

  • 主要内容:英语自我介绍短一点的(篇1),英语自我介绍短一点的(篇2),英语自我介绍短一点的(篇3),英语自我介绍短一点的(篇4),英语自我介绍短一点的(篇5),英语自我介绍短一点的(篇6),英语自我介绍短一点的(篇7),英语自我介绍短一点的7篇 英语自我介绍短一点的?我们要知道,一个好的自我介绍对自我能力以及前途也是起到不可缺少的作用的。那么下面小编给大家带来了英语自我介绍短一点的,供大家参考。 英语自我介绍短一点的(篇1) Three years of technical secondary

  • 我在打印通过使用任何opencv描述符提取器的“compute”方法获得的描述符矩阵的值时遇到了一些麻烦。我想逐个打印一个特征的描述符到一个文件,但总是当我访问带有'at'的描述符矩阵的某个元素时,我收到该元素的不同值。下面是一个'for'循环,我用来测试使用'at'时描述符矩阵的输出值: 和预期的一样,前两个打印在第二个“if”中: 给我[20] 但另外两个指纹 提前谢谢,抱歉我的英语和问题的大

  • 本文对用于描述Apache配置指令的术语加以说明。 说明 对指令用途的简单说明。 语法 说明该指令在配置文件中使用的形式(随指令的不同而不同),在指令的定义中有说明。指令后面一般可以跟一个或多个用空格分开的参数。如果参数中有空格,则必须用双引号括起来,用方括号括起来的是可选参数。如果一个参数可以取多个值,则各个可能的值用"|"分开。应该原样输入的文字使用默认字体,而可变的必须按实际情况加以替换的会

  • 本文对用于描述模块的术语加以说明。 说明 对模块用途的简要说明。 状态(Status) 状态(Status)代表了此模块与Apache服务器结合的紧密程度;也就是说,有可能需要重新编译服务器以获得一个模块的功能。其可能的值有: MPM 一个多路处理模块。与其他类型的模块不同的是,必须在编译配置时进行选择,必须有且仅有一个MPM被静态编译到服务器中。此类型的模块负责基本的对请求的处理和指派。 Bas