代码大战中存在一个挑战,即计算必须将 Long 的各个整数相互乘以多少次才能使其成为单个数字。例如
39 -> 3 * 9 = 27 -> 2 * 7 = 14 -> 1 * 4 = 4//答案是 3
这是已发布的解决方案之一 -
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;
}
}
我对代码的“(i - '0')”部分感到非常困惑。我昨天刚刚了解到 Java 的 chars() 方法返回一个代表字符的 IntStream,因此立即使用 reduce 对我来说很有意义。但随后它减去了一个字符,这让我感到困惑,因为它似乎适用于它正在处理字符,但是它们是如何相乘的呢?
我复制了上面的代码,然后删除了字符减法,这样这是一个我理解的简单的reduce语句,又名
n = Long.toString(n).chars().reduce(1, (r, i) -> r * i);
然后运行调试器。第一个循环计算出 3 * 9 为 2907。这个答案来自哪里?我最好的猜测是它与字符编码有关,但是为什么减去字符“0”可以修复它呢?
最佳答案
一个char
只是 0
范围内的一个数字至 0xFFFF
打印或连接字符串时具有特殊含义。
你可以轻松编写
int i = 'A';
而且
char c = 65;
两个变量引用相同的数字,因此,
System.out.println(i == c);
将打印true
但是当你执行时
System.out.println(i);
System.out.println(c);
不同的变量类型将导致选择不同的方法并对值进行不同的解释。
您可以使用char
计算值并始终将它们分配给 int
变量,因为它们的值范围适合 int
值范围,因此可以处理 char
的序列值为 IntStream
并保存另一个专门的 Stream 类的创建。您只需注意正确解释结果值即可。
说到编码,char
被定义为 UTF-16 单位,因此如果您想给它一个名称,那就是正确的名称。
对于您的问题的示例,了解字符 '0'
至关重要。至'9'
在 UTF-16 编码中具有相邻值(它适用于所有 Unicode 编码),因此不仅减去 '0'
来自'0'
给你int
值0
,减去'0'
来自 '0'
中的任何字符至'9'
range 会给你相应的 int
值(value)。事实是'0'
的编码值为48
甚至与这个逻辑无关。
注意 codepoints()
的存在返回 Unicode code point 序列的方法0
范围内的值至 1,114,111
( 0x10FFFF
) 。对于 BMP 中的字符,这些值与 char
相同值,但 BMP 之外的值被编码为两个 UTF-16 单元,因此使用 codepoints()
处理它们更容易改为流式传输。
关于java - java的chars()流如何与reduce一起工作?它使用字符编码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66035216/