计算Kotlin中的位数
我目前正在使用简单的string.length方法计算位数:计算Kotlin中的位数,kotlin,Kotlin,我目前正在使用简单的string.length方法计算位数: val number = 829 val length = number.toString().length 我想知道这是一种好方法还是有一种更合适的方法在Kotlin中实现这一点。您可以在Java.lang.math中使用标准Java数学库(编辑:由于Kotlin 1.2,请使用Kotlin.math)。log10函数将给出数字的长度减去1(有些例外)。不过,此函数与double一起工作,因此必须来回转换 Kotlin中的leng
val number = 829
val length = number.toString().length
我想知道这是一种好方法还是有一种更合适的方法在Kotlin中实现这一点。您可以在
Java.lang.math
中使用标准Java数学库(编辑:由于Kotlin 1.2,请使用Kotlin.math
)。log10
函数将给出数字的长度减去1(有些例外)。不过,此函数与double一起工作,因此必须来回转换
Kotlin中的length
函数可以这样编写:
fun Int.length() = when(this) {
0 -> 1
else -> log10(abs(toDouble())).toInt() + 1
}
然后你可以这样称呼它:
println(829.length()) // Prints 3
println((-1234).length()) // Prints 4 (it disregards the minus sign)
如果出于某种原因不想使用字符串或双精度,可以对整数数组使用二进制搜索:
private val limits = arrayOf(-1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999)
fun countDigits(x: Int): Int {
assert(x >= 0)
val result = limits.binarySearch(x)
return result.xor(result.shr(31)) // one's complement absolute value
}
当然,如果您希望这个特定用例真正高效,并且/或者您通过代码行获得报酬,您可以对其进行硬编码二进制搜索:
fun countDigits(x: Int): Int {
assert(x >= 0)
if (x <= 99999) {
if (x <= 99) {
if (x <= 9) {
return 1
} else {
return 2
}
} else {
if (x <= 999) {
return 3
} else {
if (x <= 9999) {
return 4
} else {
return 5
}
}
}
} else {
if (x <= 9999999) {
if (x <= 999999) {
return 6
} else {
return 7
}
} else {
if (x <= 99999999) {
return 8
} else {
if (x <= 999999999) {
return 9
} else {
return 10
}
}
}
}
}
所有这些都假设您不关心负整数。如果您这样做了,并且在调整代码时遇到困难,请随时寻求帮助。我将使用以10为底的对数创建一个扩展属性 如果您希望对负数也计算
-
,则应为:
import kotlin.math.log10
val Int.length get() = when {
this == 0 -> 1
this < 0 -> log10(-toFloat()).toInt() + 2
else -> log10(toFloat()).toInt() + 1
}
import kotlin.math.absoluteValue
import kotlin.math.log10
val Int.length get() = when(this) {
0 -> 1
else -> log10(toFloat().absoluteValue).toInt() + 1
}
你就可以这么做了
println(1234.length)
println((-1234).length)
此任务可以按如下方式递归解决:
- 检查该数字是否符合范围
。如果这是真的,结果是1-9..9
- 否则,将数字除以10,对结果中的数字进行计数,然后将该计数加1
如果不是只有数字。 例如:“-11.345F”
是的,除了负数,它们的长度中会有负号。一些使用“log”的解决方案也会起作用。由于Kotlin 1.2,您可以使用
absoluteValue
。这包括负数number.absoluteValue.toString().length
唯一错误的情况是number
是Int.MIN\u值
,而下面答案中的数字解对性能更好,问题中的原始代码可以简化为“$number.length
,在我看来,这看起来更简洁。不过,我不建议在真正的代码中使用它。我想知道为什么标准库中没有包含它。顺便问一下,检查'Int.MIN\u VALUE->10'的条件是什么?因为Math.abs(Int.MIN\u VALUE)
溢出,我只是硬编码了它Int.MIN_值
等于-2147483648
,长度为10位。如果先转换为double,然后计算绝对值,则可以去掉Int.MIN_值
特例:else->Math.log10(Math.abs(toDouble()).toInt()+1
,很好。已编辑。关于此解决方案的一些注释在我的回答中有不同的做法:1。我不会使用java.lang.Math
方法,而是使用kotlin.Math
函数,这样它就独立于底层运行时。2.我将使用扩展属性,而不是扩展函数。3.第二个示例是错误的,它将在计算1234.length()
时打印-4
,然后对结果求反,您需要将-1234
放在括号中,如println((-1234.length())
。我相信其他人可能会发现它很有用,但就我而言,这有点过头了。我只是在找一句俏皮话。不过,谢谢你的反馈。对于负数的位数,你不需要取绝对值吗?似乎是一件小事。。。还是我遗漏了什么?@thecoshmanMath.abs(Int.MIN\u VALUE)
仍然是负数。。。一个经典:)@fredsoverflow,这实际上是非常有意义的。想想4位2的恭维数字。最小的数字是-8,而最大的数字是7(当然是1000和0111)。-8的绝对值为8;它的二进制值应该是1000
,但是我们有两个补充,所以它被解释为它自己。耶,电脑!
println(1234.length)
println((-1234).length)
fun numberOfDigits(n: Int): Int =
when (n) {
in -9..9 -> 1
else -> 1 + numberOfDigits(n / 10)
}
fun countDigits(str: String): Int = str.filter{ Character.isDigit(it) }.count()
// countDigits("-11.345F") == 5