计数Kotlin中的位数

cngwdvgl  于 2022-12-19  发布在  Kotlin
关注(0)|答案(7)|浏览(321)

我目前正在使用简单的字符串长度方法来计算位数:

val number = 829
val length = number.toString().length

我想知道这是一个好方法还是在Kotlin有一个更合适的方法。

i2byvkas

i2byvkas1#

您可以使用java.lang.Math中的标准Java数学库(编辑:从Kotlin1.2开始,使用kotlin.math)。log10函数将给予你数字减1的长度(有一些例外)。这个函数可以使用双精度数,所以你必须来回转换。
length函数在Kotlin中可以写成这样:

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)
myzjeezk

myzjeezk2#

这个任务可以如下递归地解决:

  • 检查该数字是否在-9..9范围内,如果是,则结果为1。
  • 否则,将该数字除以10,计算结果中的位数,并将该计数加1。
fun numberOfDigits(n: Int): Int = 
    when (n) {
        in -9..9 -> 1
        else -> 1 + numberOfDigits(n / 10)
    }
3mpgtkmj

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))
    }
}

所有这些都假设你不关心负整数,如果你关心负整数,并且在修改代码时遇到困难,请随时寻求帮助。

de90aj5v

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)
ztigrdn8

ztigrdn85#

您可以将其转换为字符串类型,并在Kotlin中使用count函数,例如:

val c= "123".count { it.isDigit() }
println(c) // 3

如果你的值是字母表中的字母,它也能正常工作。

val c2= "a6li211".count { it.isDigit() }
println(c2) // 4
axzmvihb

axzmvihb6#

如果不只有数字。例如:“-11.345华氏度”

fun countDigits(str: String): Int = str.filter{ Character.isDigit(it) }.count()

// countDigits("-11.345F") == 5
t0ybt7op

t0ybt7op7#

我比较了这个解决方案,这个似乎比其他答案快一点(至少在我的机器上)。

fun Int.digitCount(): Int
{
    if (this == 0) return 1

    var count = 0

    var currentNumber = this

    while (currentNumber > 0)
    {
        currentNumber /= 10
        count++
    }

    return count
}

相关问题