kotlin - Kotlin:直到n的素数列表
问题描述
我正在尝试在 kotlin 中创建一个函数来返回素数列表,直到输入参数 n。我试过下面的代码,但它返回的列表包含多个相同的数字。
/**
* You can edit, run, and share this code.
* play.kotlinlang.org
*/
fun main() {
fun primes(n : Int):MutableList<Int>{
var li : MutableList<Int> = mutableListOf(2)
for(num in 2..n+1){
for(i in 2..num){
if(num % i == 0)
break
else
li.add(num)
}
}
return li
}
print(primes(7))
}
输出 :
[2, 3, 5, 5, 5, 7, 7, 7, 7, 7]
我的代码有什么问题?
解决方案
这是一个可以用更多函数式代码替换循环的主要示例(!)——在这种情况下,none()
函数:
fun primes(n: Int): MutableList<Int> {
val li = mutableListOf<Int>()
for (num in 2..n) {
if ((2 until num).none{ num % it == 0 })
li.add(num)
}
return li
}
解释一下:none()
只有当 lambda 为列表的每个项目都返回 false 时,该函数才返回 true。并且it
表示参数值(想象it ->
在 lambda 中)。所以它正在检查 num 是否可以除以从 2 到 num-1 的任何数字(这当然是素数的定义)。这不仅更短,而且希望更容易阅读。(当然,一旦你习惯了函数式风格。)
事实上,你也可以替换外循环,让整个事情变成一个单行:
fun primes(n: Int)
= (2..n).filter{ num -> (2 until num).none{ num % it == 0 } }
该版本纯粹是功能性的,但可能有点过于压缩而难以阅读。它取从 2 到 n 的数字,并且只保留那些是素数的(如上所述)。(filter()
返回一个列表,因此无需手动创建。)
然而,在算法方面,没有必要检查每个可能的除数,直到你正在测试的数字——你只需要检查主要的除数。这是一种更有效的方法。因为它使用你已经找到的素数列表,所以你不能filter()
像第二个例子那样简单地做到这一点。但是您可以轻松地调整第一个示例来做到这一点:只需将 替换if ((2 until num).none{
为if (li.none{
.
推荐阅读
- elasticsearch - Elasticsearch 给出 [function_score] 格式错误的查询,预期为 [END_OBJECT] 但找到 [FIELD_NAME]
- python - 使用 Python 和 Doc2Vec 的 MemoryError
- react-native-navigation-v2 - React-Native-Navigation v2 - 头像/图像/组件作为底部标签图标
- php - 更改 Wordpress 注册重定向的位置
- hbase - HBase 列族位置
- mysql - 获取会计年度的总和并相应地分组 SQL 结果
- git - 通过提交消息标题引用 git commit
- sql - NOT IN 不会产生与 NOT EXISTS 相同的结果
- python - 多语言文本语料库的词干提取
- android - 在 BottomSheetDialogFragment 中安排布局,以便所有视图都符合预期