Подтвердить что ты не робот

Char или String → Unicode значение в Scala?

Итак, я работаю над несколькими упражнениями в "Scala для нетерпимого", и один из них:

Напишите цикл for для вычисления произведения кодов Юникода всех букв в строке. Например, произведение символов в "Привет" равно 9415087488 L.

Следующая проблема заключается в том, чтобы сделать то же самое, но без цикла for - подсказывает, что мы должны проверять StringOps в Scaladoc.

Я проверил раздел RichChar и StringOps в Scaladoc, и, возможно, я неправильно читаю или смотрю не в то место, но я не могу найти ничего, что позволило бы мне соответствовать их результатам. Я до сих пор пробовал:

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?

Спасибо!

4b9b3361

Ответ 1

Когда вы выполняете x.foldLeft(1)(_ * _.toInt), тип результата будет выводить на Int, но 9415087488 слишком велик для Int для его сохранения.

Итак, вам нужно сказать Scala, используя Long, чтобы сохранить его.

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

Ответ 2

Если вы конвертируете каждый RichChar из String.toLong, он также работает. Например, это:

str.map (_.toLong).product - работать отлично и без foldLeft или циклов

Это циклический вариант:

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

Ответ 3

В StringOps существует специальный метод "продукта", который умножает элементы коллекции. Но он использует тип Char, потому что строка состоит из элементов Char. И у нас переполнение при попытке вычислить "Hello".product. Поэтому я преобразовал строку в значения Vector of Long Unicode с помощью "Hello".map(_. ToLong) и вычислил произведение своих элементов по этому коду:

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

Ответ 4

Здесь другой способ:

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

Ответ 5

Самый простой способ, который я нашел, это:

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

Метод принимает два параметра: Long и функция делегата, которая принимает длину и a Char, и возвращает Long. Вы можете передать анонимную функцию прямо так, или вы можете определить функцию в другом месте и передать ее, например:

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

Ответ 6

Я думаю, что преобразование в промежуточную карту неэффективно, потому что в этом случае коллекция повторяется дважды: один раз для создания карты длин и второй раз для умножения всех элементов. Необязательный временный сбор Long также не нужен. Я отдаю свой голос

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

Ответ 7

Другой вариант: "Hello".aggregate(1L)({(prod,ch) => prod * ch.toLong}, {(p1,p2)=>p1*p2})