String.chars()-为什么在此使用“ i-'0'”?

时间:2019-12-25 15:03:49

标签: java java-stream

我解决了代码战的任务,如下所示:

  

编写一个持久性函数,该函数接受一个正数num   并返回其乘法持久性,即   您必须将num中的数字相乘,直到达到单个   数字。

     

例如:

 persistence(39) == 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
                      // and 4 has only one digit

 persistence(999) == 4 // because 9*9*9 = 729, 7*2*9 = 126,
                       // 1*2*6 = 12, and finally 1*2 = 2

 persistence(4) == 0 // because 4 is already a one-digit number

解决此问题后,我发现了其他解决方案:

  class Persist {
    public static int persistence(long n) {
        int times = 0;
        while (n >= 10) {
            n = Long.toString(n).chars().reduce(1, (r, i) -> r * (i - '0'));
            times++;
        }
        return times;
    }
 }

它正在工作,但是为什么我们必须这样做:-减少'0'?

2 个答案:

答案 0 :(得分:2)

通常,这是一种将代表数字(如char的{​​{1}}(或在您的情况下,int类似,保留代码点)转换为将保留数字的char ch = '3';对应于该数字(此处为int)。


类型为int num = 3;的变量实际上并不包含字符的图形表示,但具有与位置/索引相对应的数字 。例如,小写字母"a"放置在索引97处,即char的值将保留在其16个字节中(因为它是char ch = 'a';类型的大小)。

由于 char包含数字 ,我们被允许使用对char+之类的数字进行运算的运算符。这意味着我们可以编写像-这样的代码,该代码将作为'b' - 'a'执行并得到整数97 - 96。我们还可以使用1int - char,因为这两种形式都将转换为char - intint - int将转换为char)并返回{{1 }},表示这些字符之间的距离

这是int背后的主要思想。

我们知道,在Unicode表中,数字按以下顺序放置在某处(我们不希望确切地知道位置)... ... 0 1 2 3 4 5 6 7 8 9...。 (并且它们之间没有字符)。

这使我们确定

  • int将返回0,
  • i - '0'将返回1,
  • '9' - '9'将返回2,
  • ...
  • '9' - '8'将返回9,
  • '9' - '7'将返回8,
  • '9' - '0'将返回7,
  • ...
  • '8' - '0'将返回1,
  • '7' - '0'将返回0。

所以简而言之,'1' - '0'给我们'0' - '0'的值为indexOfNumberN - indexOfZero


为避免此类混乱的代码,您可以将lambda重写为更具可读性的形式

int

答案 1 :(得分:1)

i - '0'是一种常见的破解方法,可以将ASCII(或类似)数字的值转换为实际数字。例如,'5'的编码实际上不是5,而是其他一些值(我认为是53或ASCII码)。但是在大多数系统中,'5'的编码比'0'的编码大5倍。因此,从字符“ 5”的编码中减去'0'的值(字符“ 0”的编码)将得出5的数值