字符串或字符串 - > Scala中的Unicode值?

时间:2012-06-23 00:07:56

标签: scala unicode

所以我正在完成“Scala for the Impatient”中的一些练习,其中一个是:

编写一个for循环,用于计算字符串中所有字母的Unicode代码的乘积。例如,“Hello”中字符的乘积为9415087488 L.

下一个问题是做同样的事情,但没有for循环 - 它暗示我们应该检查Scaladoc中的StringOps

我检查了Scaladoc中的RichCharStringOps部分,也许我误读或查找错误的地方,但我找不到任何能让我匹配其输出的内容。我到目前为止尝试过:

scala> x.foldLeft(1)(_ * _.toInt)
res0: Int = 825152896

scala> x.foldLeft(1)(_ * _.getNumericValue)
res5: Int = 2518992

scala> x.foldLeft(1)(_ * _.intValue())
res6: Int = 825152896

scala> var x = 1
x: Int = 1

scala> for (c <- "Hello") x *= c.toInt

scala> x
res12: Int = 825152896

哪个与他们的输出不匹配。

我如何以for和非for的方式执行此操作?

谢谢!

10 个答案:

答案 0 :(得分:29)

执行x.foldLeft(1)(_ * _.toInt)时,结果类型将推断为Int,但9415087488太大而Int无法存储。

因此,您需要使用Long告诉Scala存储它。

scala> val x = "Hello"
x: java.lang.String = Hello

scala> x.foldLeft(1L)(_ * _.toInt)
res1: Long = 9415087488

scala> var x: Long = 1
x: Long = 1

scala> for (c <- "Hello") x *= c.toInt

scala> x
res7: Long = 9415087488

答案 1 :(得分:13)

如果你转换每个字符串的RichChar .toLong它也可以。例如,这个:

str.map (_.toLong).product - 工作正常,没有foldLeft或周期

这是循环变体:

def product(str: String): Long = {
    var prod: Long = 1
    for (ch <- str) prod *= ch
    prod
}

答案 2 :(得分:8)

这是一个特殊的产品&#34; StringOps中的方法,它将系列的元素相乘。但它使用Char类型,因为字符串由char元素组成。我们在尝试计算&#34; Hello&#34; .product时会溢出。所以我通过&#34; Hello&#34; .map(_。toLong)将字符串转换为Vector of Long Unicode值,并通过以下代码计算其元素的乘积:

scala> "Hello".map(_.toLong).product
res79: Long = 9415087488

答案 3 :(得分:5)

这是另一种方式:

scala> (for (c <- "Hello") yield c.toLong).product
res36: Long = 9415087488

答案 4 :(得分:3)

我发现这样做最直接的方法是:

"Hello".foldLeft(1L)((x:Long, y:Char) => x*y)

该方法有两个参数:Long和委托函数,它接受Long和Char并返回Long。您可以像这样直接传递匿名函数,或者您可以在其他地方定义函数并将其传入,如下所示:

def multiply(x:Long, y:Char) = {
    x*y
}
"Hello".foldLeft(1L)(multiply)

答案 5 :(得分:2)

我认为转换到中间贴图是低效的,因为在这种情况下,集合被迭代两次:一次创建长图和第二次乘以所有元素。也不需要不必要的临时收集Long。我投票给

"Hello".foldLeft(1L)(_ * _)

答案 6 :(得分:1)

该练习不需要使用for循环,所以我进行了递归:

def unicode_rec(s: String): Int = 
  if(s == "") 1 
  else s.head.toInt * unicode_rec(s.tail)

答案 7 :(得分:0)

另一种变体:

"Hello".aggregate(1L)({(prod,ch) => prod * ch.toLong}, {(p1,p2)=>p1*p2})

答案 8 :(得分:0)

所以这里我们在一起:)

    // one way
    val longs = for (c <- str) yield c.toLong
    println(longs.product)

    // 2nd way
    println(str.foldLeft(1L)(_ * _.toInt))

    // 3rd way
    var x = 1L
    for (c <- str) yield x *= c.toInt
    println(x)

    // 4th way
    var product = 1L
    for (c <- str) {
      product *= c.toInt
    }
    println(product)

    // 5th way
    println(str.map(_.toLong).product)

    // 6th way
    println(str.foldLeft(1L)(_ * _))

    // 7th way
    println(str.map(_.toLong).reduceLeft(_ * _)) // my IDE warns `Replace reduce with product` 

    // 8th way
    println(str.map(_.toLong).scanLeft(1L)(_ * _).last)

    // 9th way
    println(str.map(_.toLong).reduce((x, y) => (x * y))) // my IDE warns `Replace reduce with product`

   // using recursion
   def exercise9(str: String): Long = {
    var product = str.head.toLong
    if (str.tail.length > 0) {
        product *= exercise9(str.tail)
    }
    product
  }

答案 9 :(得分:0)

也在同一本书上取得进展。 可能看起来有点像 Java 的味道,但它确实完成了它的工作:

scala> "Hello".map( x => x.toLong).reduce( (a, b) => a * b)
val res45: Long = 9415087488