我正在使用简单的string.length方法计算位数:
val number = 829
val length = number.toString().length
我想知道这是否是一种好方法,或者在Kotlin中有更合适的方法。
答案 0 :(得分:15)
您可以在java.lang.Math
中使用标准的Java数学库。 log10
函数将为您提供数字长度减1(有一些例外)。此功能适用于双打,因此您必须来回转换。
在Kotlin中可以这样写出length
函数:
fun Int.length() = when(this) {
0 -> 1
else -> Math.log10(Math.abs(toDouble())).toInt() + 1
}
然后你可以这样称呼它:
println(829.length()) // Prints 3
println(-1234.length()) // Prints 4 (it disregards the minus sign)
答案 1 :(得分:1)
如果由于某种原因你不想求助于字符串或双精度,你可以对整数数组使用二进制搜索:
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
}
}
}
}
}
无论哪种方式,请确保所有这些边界情况都正确:
class CountDigitsTest {
@Test fun oneDigit() {
assertEquals(1, countDigits(0))
assertEquals(1, countDigits(9))
}
@Test fun twoDigits() {
assertEquals(2, countDigits(10))
assertEquals(2, countDigits(99))
}
@Test fun threeDigits() {
assertEquals(3, countDigits(100))
assertEquals(3, countDigits(999))
}
@Test fun fourDigits() {
assertEquals(4, countDigits(1000))
assertEquals(4, countDigits(9999))
}
@Test fun fiveDigits() {
assertEquals(5, countDigits(10000))
assertEquals(5, countDigits(99999))
}
@Test fun sixDigits() {
assertEquals(6, countDigits(100000))
assertEquals(6, countDigits(999999))
}
@Test fun sevenDigits() {
assertEquals(7, countDigits(1000000))
assertEquals(7, countDigits(9999999))
}
@Test fun eightDigits() {
assertEquals(8, countDigits(10000000))
assertEquals(8, countDigits(99999999))
}
@Test fun nineDigits() {
assertEquals(9, countDigits(100000000))
assertEquals(9, countDigits(999999999))
}
@Test fun tenDigits() {
assertEquals(10, countDigits(1000000000))
assertEquals(10, countDigits(Int.MAX_VALUE))
}
}
所有这些都假定您不关心负整数。如果您这样做,并且您在调整代码时遇到困难,请随时寻求帮助。
答案 2 :(得分:0)
可以按以下方式递归解决此任务:
-9..9
范围内。如果是这样,则结果为1。fun numberOfDigits(n: Int): Int =
when (n) {
in -9..9 -> 1
else -> 1 + numberOfDigits(n / 10)
}
答案 3 :(得分:0)
如果不仅只有数字。 例如:“ -11.345F”
y = (1212, 900, 730, 714, 650, 591, 565, 500, 450, 440, 430, 420, 407, 381, 324, 315, 283)
x = []
for i in y:
count = sum([1.0 for j in y if j > i])
x.append(round(count / len(y) * 100, 1))
print(tuple(x))
答案 4 :(得分:-1)
我将使用以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)