перебор значений BigInteger с использованием foreach в Kotlin

#kotlin

#kotlin

Вопрос:

Я пытаюсь перебрать BigInteger значения, Kotlin используя следующий фрагмент кода. Но это говорит For-loop range must have an 'iterator()' method само за себя . Как я могу перебирать BigInteger значения в Kotlin ?

 private fun pow(base: BigInteger, power: BigInteger): String {
        for(i in BigInteger.ZERO..power){ //Giving error

        }
    }
  

Комментарии:

1. Вам действительно нужно иметь power as a BigInteger ? Если вы ослабите свои ограничения, вы можете использовать встроенную pow функцию на BigInteger : base.pow(Int)

2. Нет, я не могу. Параметры функции действительно огромны. Так что это путь. То есть вы имеете Kotlin в виду, что не предоставляет нам способ перебора BigInteger значений с использованием цикла for? @Todd

3. Хотя ответ, предоставленный @caco3, является хорошим способом написания диапазона BigInteger, я думаю, вам действительно нужно пересмотреть свои предположения здесь для этой проблемы. Long.MAX_VALUE равно 2 ^ 63-1, наибольшее число, которое вы можете использовать без необходимости переключения BigInteger . Теперь я понимаю, что ответ на ваше вычисление может превышать Long.MAX_VALUE , но итеративное вычисление в цикле с таким большим показателем займет много человеческих жизней. Пожалуйста, пересмотрите свои предположения и посмотрите, можете ли вы использовать встроенную функцию для этого!

4. Тот факт, что BigInteger.pow в int качестве аргумента используется an, а не BigInteger (это даже отмечено в javadoc ), может подтвердить слова @Tedd’s. Несмотря на то, что Kotlin настолько гибкий , что позволяет нам перебирать все, что угодно , это может быть не лучшим способом решения возникшей у вас проблемы

Ответ №1:

Вы можете расширить BigInteger , чтобы разрешить это

В частности, нам нужно:

  1. введите rangeTo функцию BigInteger (чтобы разрешить использование .. operator )
  2. добавьте iterator функцию в диапазон, возвращаемый rangeTo operator

Функция rangeTo

Здесь я определяю функцию расширения для BigInteger

 operator fun BigInteger.rangeTo(other: BigInteger) = 
        BigIntegerRange(this, other)
  

BigIntegerRange :

 class BigIntegerRange(
        override val start: BigInteger,
        override val endInclusive: BigInteger
) : ClosedRange<BigInteger>, Iterable<BigInteger> {
    override operator fun iterator(): Iterator<BigInteger> =
            BigIntegerRangeIterator(this)
}
  

BigIntegerRangeIterator :

 class BigIntegerRangeIterator(
        private val range: ClosedRange<BigInteger>
) : Iterator<BigInteger> {
    private var current = range.start

    override fun hasNext(): Boolean =
            current <= range.endInclusive

    override fun next(): BigInteger {
        if (!hasNext()) {
            throw NoSuchElementException()
        }
        return current  
    }
}
  

Теперь этот код:

 fun main() {
    for (i in BigInteger.ZERO..BigInteger.TEN) {
        println(i)
    }
}
  

Компилирует и печатает:

 0
1
2
3
4
5
6
7
8
9
10
  

Не забудьте import rangeTo функцию

Смотрите также: