for (i in2..Math.sqrt(max.toDouble()).toInt()) { if (isPrime[i]) { for (j in i * i..max step i) { isPrime[j] = false } } }
// 统计数组中的素数个数 var count = 0 for (num in arr) { if (num >= 2 && isPrime[num]) { count++ } }
return count }
funmain() { val arr = intArrayOf(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) println("Count of prime numbers in the array with sieve: ${countPrimesInArrayWithSieve(arr)}") }
funremoveDuplicates(nums: IntArray): Int { if (nums.isEmpty()) return0 var i = 0 for (j in1 until nums.size) { if (nums[j] != nums[i]) { i++ nums[i] = nums[j] } } return i + 1// 返回不重复数组的长度 }
// 使用例子 funmain() { val nums = intArrayOf(1, 1, 2, 2, 3) val length = removeDuplicates(nums) println("新的数组长度: $length") for (i in0 until length) { print("${nums[i]} ") } }
funfindPivotIndex(nums: IntArray): Int { val totalSum = nums.sum() var leftSum = 0 for ((index, value) in nums.withIndex()) { // 如果左侧和的两倍加上当前值等于总和,则当前索引是中心索引 if (2 * leftSum + value == totalSum) { return index } leftSum += value } return -1// 如果没有找到,返回-1 }
fun main(){ val fFlow = FFlow() fFlow.demoList() fFlow.demoSequence() }
fun demoSequence() { val currentTimeMillis = System.currentTimeMillis() val list = (0..10000000).asSequence().map { it * 2 }.map { it - 1 }.take(20).toList() println("demoSequence:${System.currentTimeMillis() - currentTimeMillis}:$list") }
fun demoList() { val currentTimeMillis = System.currentTimeMillis() val list = (0..10000000).map { it * 2 }.map { it - 1 }.take(20).toList() println("demoList:${System.currentTimeMillis() - currentTimeMillis}:$list") }
val noEnd = sequence { var i = 1 while (true) { yield(i) i *= 2 } } noEnd.take(4).toList() //输出:[1, 2, 4, 8]
但是一定要注意,我们虽然可以这么写,但是务必不能真的让while一直循环。我们不能直接使用toList。必须提供一个能结束循环的操作符,也就是不能取出所有元素(无限个)——要么使用类似take的操作来限制它们的数量,要么使用不需要所有元素的终端操作,例如first, find, any, all, indexOf等。
private class GeneratorSequence<T : Any>(private val getInitialValue: () -> T?, private val getNextValue: (T) -> T?) : Sequence<T> { override fun iterator(): Iterator<T> = object : Iterator<T> { var nextItem: T? = null var nextState: Int = -2 // -2 for initial unknown, -1 for next unknown, 0 for done, 1 for continue
private fun calcNext() { nextItem = if (nextState == -2) getInitialValue() else getNextValue(nextItem!!) nextState = if (nextItem == null) 0 else 1 }
override fun next(): T { if (nextState < 0) calcNext()
if (nextState == 0) throw NoSuchElementException() val result = nextItem as T // Do not clean nextItem (to avoid keeping reference on yielded instance) -- need to keep state for getNextValue nextState = -1 return result }
override fun hasNext(): Boolean { if (nextState < 0) calcNext() return nextState == 1 } } }
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> { //出啊年一个新的ArrayList,并调用mapTo方法 return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform) }
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C { //遍历原始的集合,进行变换操作,然后将变换后的数据依次加入到新创建的集合 for (item in this) destination.add(transform(item)) //返回新集合 return destination }
override fun next(): R { return transformer(iterator.next()) }
//由于这里都是执行的+1操作,所以变换逻辑transformer可以认为等同于如下操作:
override fun next(): R { return iterator.next()+1 }
而当我们通过sequence3.toList执行代码时,它的流程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
public fun <T> Sequence<T>.toList(): List<T> { return this.toMutableList().optimizeReadOnlyList() }
public fun <T> Sequence<T>.toMutableList(): MutableList<T> { //末端操作符,此处才会开始创建新的集合 return toCollection(ArrayList<T>()) }
public fun <T, C : MutableCollection<in T>> Sequence<T>.toCollection(destination: C): C { //执行迭代器next操作 //当调用(末端操作符)走到这里时,便会和普通结合的操作符一样 //此时为新创建的集合赋值 for (item in this) { destination.add(item) } return destination }
// external cancel with cause, never invoked implicitly from internal machinery public override fun cancel(cause: CancellationException?) { cancelInternal(cause ?: defaultCancellationException()) }
/** * Returns a context containing elements from this context and elements from other [context]. * The elements from this context with the same key as in the other one are dropped. */ public operator fun plus(context: CoroutineContext): CoroutineContext = if (context === EmptyCoroutineContext) thiselse// fast path -- avoid lambda creation context.fold(this) { acc, element -> valremoved= acc.minusKey(element.key) if (removed === EmptyCoroutineContext) element else { // make sure interceptor is always last in the context (and thus is fast to get when present) valinterceptor= removed[ContinuationInterceptor] if (interceptor == null) CombinedContext(removed, element) else { valleft= removed.minusKey(ContinuationInterceptor) if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else CombinedContext(CombinedContext(left, element), interceptor) } } }