我目前正在使用简单的字符串长度方法来计算位数:
val number = 829 val length = number.toString().length
我想知道这是一个好方法还是在Kotlin有一个更合适的方法。
i2byvkas1#
您可以使用java.lang.Math中的标准Java数学库(编辑:从Kotlin1.2开始,使用kotlin.math)。log10函数将给予你数字减1的长度(有一些例外)。这个函数可以使用双精度数,所以你必须来回转换。length函数在Kotlin中可以写成这样:
java.lang.Math
kotlin.math
log10
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)
myzjeezk2#
这个任务可以如下递归地解决:
-9..9
fun numberOfDigits(n: Int): Int = when (n) { in -9..9 -> 1 else -> 1 + numberOfDigits(n / 10) }
3mpgtkmj3#
如果出于某种原因不想使用字符串或双精度型,可以对整数数组使用二进制搜索:
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)) } }
所有这些都假设你不关心负整数,如果你关心负整数,并且在修改代码时遇到困难,请随时寻求帮助。
de90aj5v4#
我将使用以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)
ztigrdn85#
您可以将其转换为字符串类型,并在Kotlin中使用count函数,例如:
val c= "123".count { it.isDigit() } println(c) // 3
如果你的值是字母表中的字母,它也能正常工作。
val c2= "a6li211".count { it.isDigit() } println(c2) // 4
axzmvihb6#
如果不只有数字。例如:“-11.345华氏度”
fun countDigits(str: String): Int = str.filter{ Character.isDigit(it) }.count() // countDigits("-11.345F") == 5
t0ybt7op7#
我比较了这个解决方案,这个似乎比其他答案快一点(至少在我的机器上)。
fun Int.digitCount(): Int { if (this == 0) return 1 var count = 0 var currentNumber = this while (currentNumber > 0) { currentNumber /= 10 count++ } return count }
7条答案
按热度按时间i2byvkas1#
您可以使用
java.lang.Math
中的标准Java数学库(编辑:从Kotlin1.2开始,使用kotlin.math
)。log10
函数将给予你数字减1的长度(有一些例外)。这个函数可以使用双精度数,所以你必须来回转换。length
函数在Kotlin中可以写成这样:那么你可以这样称呼它:
myzjeezk2#
这个任务可以如下递归地解决:
-9..9
范围内,如果是,则结果为1。3mpgtkmj3#
如果出于某种原因不想使用字符串或双精度型,可以对整数数组使用二进制搜索:
当然,如果你想让二进制搜索变得更高效,或者你是按代码行付费的,你可以为这个特定的用例硬编码二进制搜索:
无论哪种方式,请确保您正确地获得了所有这些边界情况:
所有这些都假设你不关心负整数,如果你关心负整数,并且在修改代码时遇到困难,请随时寻求帮助。
de90aj5v4#
我将使用以10为底的对数创建一个扩展属性。
如果您希望
-
也计入负数,则应为:如果您只想计算已计算的位数,而忽略负数的
-
,则为:然后你就可以
ztigrdn85#
您可以将其转换为字符串类型,并在Kotlin中使用count函数,例如:
如果你的值是字母表中的字母,它也能正常工作。
axzmvihb6#
如果不只有数字。例如:“-11.345华氏度”
t0ybt7op7#
我比较了这个解决方案,这个似乎比其他答案快一点(至少在我的机器上)。