我想写一个在scala中反转数字的算法
我没有背景
object Main {
def main(args : Array[String]){
println(reverse(-136))
}
//Par defaut les paramètres d'une fonction scala sont immutables
def reverse(x : Int):Int={
var x1:Int = Math.abs(x)
var rev:Int = 0;
while (x1 > 0){
var pop:Int = x1 % 10
x1 /=10
if(rev > Int.MaxValue/10 || ((rev eq Int.MaxValue/ 10) && pop > 7)) 0.##
if (rev < Int.MinValue / 10 || ((rev eq Int.MinValue / 10) && pop < -8)) 0.##
rev = (rev * 10) + pop
}
if (x < 0) rev *= -1
return rev
}
}
错误:(15,58)隐式转换的结果类型必须比AnyRef更具体
if(rev > Int.MaxValue/10 || ((rev eq Int.MaxValue/ 10) && pop > 7)) 0.##
答案 0 :(得分:6)
eq
是 Scala 中的指针比较运算符,因此用于比较类型AnyRef
的值。但是您正在比较整数值,并且Int
是从AnyVal
而不是AnyRef
派生的。
要比较Int
数量是否相等(或在此情况下, Scala 中的其他任何值),请使用==
运算符。
偶然地,您的if
语句都不会影响结果,因为您没有更改任何内容并丢弃结果。 (而且,正如其他人所评论的,0.##
等同于0.hashCode
,而Int
的值恰好是0,而import scala.annotation.tailrec
import scala.util.Try
// By extending from the App trait, we do not need a main function.
object Main
extends App {
println(reverse(-136))
// Return a decimal number with the digits in x reversed. If an error occurs (such as an
// overflow), then the exception will be returned wrapped in a Failure instance.
// If it succeeds, the result is wrapped in a Success.
def reverse(x: Int): Try[Int] = {
// If x is negative, we need to subtract values; if positive, we need to add them. In
// both cases, we need to trap integer overflows. Math.subtractExact does the former,
// Math.addExact does the latter.
//
// If an overflow occurs, an ArithmeticException will be thrown.
val op: (Int, Int) => Int = if(x < 0) Math.subtractExact else Math.addExact
// Process the next digit.
//
// Note: this function will throw an exception if an overflow occurs (of type
// ArithmeticException).
@tailrec
def nextDigit(value: Int, result: Int): Int = {
// If value is now 0, then return the result.
if(value == 0) result
// Otherwise, process the right-most digit of value into a new result.
else {
// Take the right-most digit of value (removing the sign).
val digit = Math.abs(value % 10)
// Perform the next iteration, updating value and result in the process.
//
// Note: The result is updated according to the "op" we defined above.
nextDigit(value / 10, op(Math.multiplyExact(result, 10), digit))
}
}
// Perform the conversion by looking at the first digit. Convert any thrown exceptions
// to failures.
Try(nextDigit(x, 0))
}
}
的值恰好是0。实际需要。)
更新代码的功能版本如下所示:
var
一些注意事项:
while
声明,也没有while
循环。 (这些是过程编程的症状,而 Scala 鼓励使用功能编程作为替代。)@tailrec
循环被a代替 tail-recursive 函数。 ({nextDigit
告诉 Scala 编译器var
必须是尾部递归的;如果不是,则编译器将发出编译时错误。){{1 }}声明被此递归函数的参数替换。reverse
函数已完全定义。它不会引发异常(nextDigit
引发的任何异常都将被处理并且不会传递给调用方),并且会为提供的每个x
值返回一个结果;对于那些无法取反的值(例如,因为它们溢出了32个整数结果),则返回Failure
实例。return
条语句;考虑到功能性,在{em> Scala 中使用return
被认为是较差的样式。如果对此有任何疑问,请添加评论,我将尝试回答。
答案 1 :(得分:3)
您可以将Int
更改为String
,这很容易反转,然后再次将其更改回来,但是您必须测试-
字符。
x.toString.reverse.foldLeft(0)((n,c) => if (c=='-') -1*n else n*10 + c.asDigit)
如果您希望将其全部保留在数字字段中...
Stream.iterate(x)(_/10) //an infinite reduction of the original number
.takeWhile(_ != 0) //no longer infinite
.map(_ % 10) //reduce to single digits
.foldLeft(0)(_*10 + _) //fold all the digits back into an Int