rai*_*ker 2 java char java-stream
代码战争的挑战在于计算你必须将 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我对代码的“(i - '0')”部分感到非常困惑。我昨天才知道 Java 的 chars() 方法返回一个 IntStream 表示字符,所以立即使用 reduce 对我来说很有意义。但随后它减去了一个让我失望的字符,因为它似乎适用于它正在使用字符,但是它们是如何相乘的?
我复制了上面的代码,然后删除了字符减法,所以这是我理解的一个简单的reduce语句,也就是
n = Long.toString(n).chars().reduce(1, (r, i) -> r * i);
Run Code Online (Sandbox Code Playgroud)
然后运行调试器。第一个循环将 3 * 9 计算为 2907。这个答案从何而来?我最好的猜测是它与字符编码有关,但是为什么减去字符 '0' 会修复它呢?
Achar只是在0to范围内的数字,0xFFFF在打印或连接到字符串时具有特殊含义。
你可以轻松写
int i = 'A';
Run Code Online (Sandbox Code Playgroud)
但是也
char c = 65;
Run Code Online (Sandbox Code Playgroud)
两个变量指代相同的数字,因此,
System.out.println(i == c);
Run Code Online (Sandbox Code Playgroud)
会打印true,但当你执行
System.out.println(i);
System.out.println(c);
Run Code Online (Sandbox Code Playgroud)
不同的变量类型将导致选择不同的方法对值的不同解释。
您可以使用char值进行计算并始终将它们分配给int变量,因为它们的值范围适合int值范围,因此可以使用 处理一系列char值IntStream并保存另一个专用 Stream 类的创建。您只需要注意正确解释结果值。
说到编码,char被定义为一个 UTF-16 单元,所以如果你想给它一个名字,那就是正确的。
对于你的问题的例子,它是重要的是了解的字符'0'到'9'必须在UTF-16编码(它适用于所有的Unicode编码)相邻值,这样做不仅减去'0'从'0'给你的int价值0,减去'0'从任何字符'0'to '9'range 会给你相应的int值。这一事实'0'的编码值是48不是连这个逻辑相关。
请注意该codepoints()方法的存在,该方法返回范围为( )的 Unicode代码点值序列。对于BMP 中的字符,值与值相同,但 BMP 之外的值被编码为两个 UTF-16 单元,因此用流处理它们更容易。01,114,1110x10FFFFcharcodepoints()