Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 220 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Count number of digits in Kotlin

#1
I'm currently counting number of digits using simple string.length approach:

val number = 829
val length = number.toString().length
I wonder whether this is a good way or there is a more appropriate way to do that in Kotlin.
Reply

#2
If for some reason you don't want to resort to strings or doubles, you can use binary search on an array of integers:

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
}

Of course, you could hard-code binary search for this specific use case if you wanted it to be really efficient, and/or you got paid by lines of code:

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

Either way, make sure you got all those boundary cases right:

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

All of this assumes that you don't care about negative integers. If you do, and you have trouble adapting the code, feel free to ask for help.
Reply

#3
I would create an extension property using a base-10 logarithm.

If you want the `-` counted too for negative numbers it would be:

```kotlin
import kotlin.math.log10

val Int.length get() = when {
this == 0 -> 1
this < 0 -> log10(-toFloat()).toInt() + 2
else -> log10(toFloat()).toInt() + 1
}
```

If you want to count only the digits counted and the `-` for negative numbers ignored it would be:

```kotlin
import kotlin.math.absoluteValue
import kotlin.math.log10

val Int.length get() = when(this) {
0 -> 1
else -> log10(toFloat().absoluteValue).toInt() + 1
}
```

You can then just do
```kotlin
println(1234.length)
println((-1234).length)
```
Reply

#4
This task could be solved recursively as following:

- check it the number fits in the range `-9..9`. If that's true, the result is 1.
- otherwise divide the number by 10, count digits in the result, and add 1 to that count.


```
fun numberOfDigits(n: Int): Int =
when (n) {
in -9..9 -> 1
else -> 1 + numberOfDigits(n / 10)
}
```
Reply

#5
You can use the standard Java-math library in `java.lang.Math` (edit: since Kotlin 1.2, use `kotlin.math`). The `log10` function will give you the length of the number minus 1 (with some exceptions). This function works with doubles though, so you have to convert back and forth.

A `length` function could be written like this in Kotlin:

fun Int.length() = when(this) {
0 -> 1
else -> log10(abs(toDouble())).toInt() + 1
}

Then you can call it like this:

println(829.length()) // Prints 3
println((-1234).length()) // Prints 4 (it disregards the minus sign)
Reply

#6
If there are not only digits.
For example: "-11.345F"

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

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

Reply

#7
I compared this solution and this one seems a little faster (at least on my machine) than other answers.

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

var count = 0

var currentNumber = this

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

return count
}
```
Reply

#8
You can convet it to string type and use count function in kotlin, For example:


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

If your value have the letters of the alphabet, it also works corectlly.

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



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through