String 字符的 Scala int 值
我只想对 BigInt 的数字求和。我可以这样做
scala> "1 2 3".split(" ").map(_.toInt).sum
res23: Int = 6
所以我尝试了
scala> BigInt(123).toString().map(_.toInt).sum
res24: Int = 150
这不起作用,因为它将字符映射到它们的 Unicode 值。
以下两者都可以工作,但是有没有比使用 Java 静态方法或额外的 toString 转换更优雅的方法?
BigInt(123).toString().map(Character.getNumericValue(_)).sum
BigInt(123).toString().map(_.toString.toInt).sum
(我还使用递归函数来完成此操作,完全避开字符串,但我对简洁的 1-liner 感兴趣。)
I just want to sum the digits of a BigInt. I can do
scala> "1 2 3".split(" ").map(_.toInt).sum
res23: Int = 6
So I tried
scala> BigInt(123).toString().map(_.toInt).sum
res24: Int = 150
This doesn't work because it maps the characters to their Unicode values.
Both the following work, but is there a more elegant way than using the Java static method or an extra toString conversion?
BigInt(123).toString().map(Character.getNumericValue(_)).sum
BigInt(123).toString().map(_.toString.toInt).sum
(I've also done it using a recursive function, sidestepping strings altogether, but I'm interested here in a concise 1-liner.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
哇...这些答案到处都是!在这里,执行以下操作:
Wow... these answers are all over the place! Here, do this:
完全不使用字符串怎么样?
How about not using Strings at all?
这并不短,当然也效率不高,但它是另一种方法:(
您可能需要一个
Int
,无论如何它更快,但需要.map(i=>( i%10).toInt)
。)此方法(以及直接递归)的问题在于您必须计算与数字一样多的除法。 (您可以使用
/%
将速度提高 2 倍,但这仍然是一个问题。)转换为字符串要快得多,因为所有这些显式BigInt
创建是可以避免的。如果您确实想要一些快速工作的东西(我知道不是您所要求的),您需要一种分而治之的方法:
编辑:如果您想要真正快各种尺寸的转换,我修改了我的方案如下。有一些不完全功能的位主要是由于缺少
takeTo
方法。这应该比所有大小的其他所有东西都快(尽管对于非常大的 BigInts,它渐近于fastDigitSum
性能)。在 64 位机器上可能会比 32 位机器上运行得更好
。在创建此函数的过程中不会损害任何字符串。
(好吧——此时这有点像代码高尔夫。)
This is not short, and certainly not efficient, but it is another way to go:
(and you probably want an
Int
, which is faster anyway but requires.map(i=>(i%10).toInt)
.)The problem with this method (and straightforward recursion) is that you have to compute as many divisions as digits. (You could use
/%
to speed things up by a factor of 2, but that's still a problem.) Converting to a string is much faster because all those explicitBigInt
creations can be avoided.If you actually want something that works fast (not what you asked for, I know), you need a divide-and-conquer approach:
Edit: If you want really fast conversions at all sizes, I've modified my scheme as follows. There are some not-entirely-functional bits due largely to a lack of a
takeTo
method. This should be faster than everything else at all sizes (though it asymptotes tofastDigitSum
performance for very large BigInts).Probably will run better on 64 bit machines than 32.
No strings were harmed in the making of this function.
(Okay--this is ending up sort of like code golf at this point.)
我不认为它比你已经拥有的好多少,但
也有效。
另外
,根据 Rex Kerr 的评论,这可以简化为
I don't think it's much better than the ones you've already got, but
also works.
Also
and per Rex Kerr's comment, this can be simplified to
这不是问题的答案,而是对建议的速度测试。我多次运行测试,以确保虚拟机已预热且结果一致:这些结果具有代表性,并且适用于 10000 次迭代。请参阅代码以了解这些方法的定义。
对于 10 位 BigInts
对于 50 位 BigInts
对于 100 位 BigInts
对于 100,000 位 BigInts (1 次迭代)
所以看起来
BigInt(123).toString().map(_-'0').sum< /code> 是较小 BigInt 的速度和简洁性方面的赢家,但如果您的 BigInt 很大,则 Rex Kerr 的方法很好。
基准代码:
This in not an answer to the question but a speed test of the suggestions. I ran the tests several times to ensure the VM was warmed up and results were consistent: these results are representative and are for 10000 iterations. See code for definitions of what these methods are.
For 10-digit BigInts
For 50-digit BigInts
For 100-digit BigInts
For 100,000-digit BigInts (1 iteration)
So it seems
BigInt(123).toString().map(_-'0').sum
is the winner for speed and conciseness for smaller BigInts, but Rex Kerr's method is good if your BigInts are huge.Benchmark code:
我刚刚注意到 RichChar 类有一个 getNumericValue 方法,所以答案是
I just noticed that the RichChar class has a getNumericValue method, so the answer would be