首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

用数组语言思考 (2022)

摘要

Thinking in an array language You can view the full source code for this chapter at GitHub。Since you are now properly acquainted with K, let's do some programming。

the and with programming more
2026-05-22 1 阅读 约7分钟阅读 tosh
分享:
字号:
用数组语言思考 您可以在 GitHub 上查看本章的完整源代码。既然您现在已经熟悉了 K,那么让我们开始一些编程吧。大多数 K 编程都是通过 REPL 进行的,因为迭代以前的代码非常有用。 ngn/k 和 rlfe 具有使用向上/向下箭头键的历史,这应该足以开始在 K 中开发更大的程序。函数在 REPL 中进行测试,然后转移到实际代码中。请注意,ngn/k 的 beautifulprinting 始终返回有效的 k 数据,您可以预先计算一些内容以加快程序速度。 K 脚本总是像在 repl 中键入一样执行,即:执行每一行,并打印其返回值,除非它以分号结尾。脚本还允许多行定义,这方便了可读性。通常,您可能会将工作保存在脚本中,并希望在 repl 中使用它。为了使用您存储的数据和函数,只需在 repl 中执行 \l file.k ,您的文件将被执行,并且其数据将被加载。您可以多次将文件加载到 REPL 中,从而覆盖旧数据。使用 \ 访问的 repl 帮助还列出了更多有用的命令。 K 编程(以及一般的数组编程)是一个简化模式的连续过程。一个大的、笨拙的模式有一种或多种方法可以压缩成一个更小、更具声明性、易于阅读的模式。如果您想更好地理解它,请在 APL 中的模式和反模式:逃离初学者的高原 - Aaron Hsu - Dyalog '17 中详细讨论这一点。大多数人在 K 中遇到的一个常见问题是需要将常见的、众所周知的算法转换为 K,通常取自 geeksforgeeks 等编程网站或维基百科文章。让我们举一个例子:矩阵乘法。从这篇维基百科文章中,矩阵乘法的迭代算法如下: 输入:矩阵 A 和 B 设 C 为适当大小的新矩阵 对于 i 从 1 到 n: 对于 j 从 1 到 p:让 sum = 0 对于 k 从 1 到 m: Set sum ← sum + Aik × Bkj Set Cij ← sum Return C 如果需要,可以尝试将其转换为 K。直接转换为: matmul: { A::x B::y n::#A m::#*A p::#*B C::(n;p)#0 i::0 j::0 k::0 sum::0 { i::x { j::x sum::0 { k::x sum::sum+A[i;k]*B[k;j] }'!m C[i;j]::sum }'!p }'!n C} 这是最差的 K 代码我曾经写过,因为我们试图像命令式语言一样编写 K,而 K 不太适合这种设计。主要问题是: 很多很多的全局变量被分配了多个嵌套循环大量的修改幸运的是,这里我们可以简化很多事情,我们可以一一解决这些问题。让我们从最里面的循环开始: sum::0 { k::x sum::sum+A[i;k]*B[k;j] }'!m C[i;j]::sum 我们可以做的第一个也是最简单的修复是使用折叠 ( / ) 求和。 C[i;j]::+/{ k::x A[i;k]*B[k;j] }'!m 1 个全局故障,还有 9 个故障。我们可以删除的下一个全局是 C 。由于 ' (each) 返回一个数组,因此不需要修改 C。我们可以简单地返回嵌套循环的值。 { i::x { j::x +/{ k::x A[i;k]*B[k;j] }'!m }'!p }'!n} 现在,我们有了三个没有修改的循环,这使我们的工作变得更加容易。现在要查看的主要变量是 i 、 j 和 k 。 i 索引 A 的每一行。 j 索引 B 的每一列。 k 索引 A 的每一列和 B 的行。基本上,k 负责将 A 的每一行与 B 的每一列配对,然后将它们相乘。因此,我们可以消除这里的中间人,直接匹配它们而无需 k 。这也消除了一个循环,并且不再需要 m 。 { j::x +/A[i]*B[;j] }'!p }'!n} 接下来,要删除 j ,我们需要获取 B 的每一列并将其与 A[i] 配对。为此,我们转置 B 并将每个元素与每个右 ( /: ) 配对。 matmul: { A::x B::y n::#A i::0 { i::x A[i]{+/x*y}/:+B}'!n } 为了删除 i ,我们做了类似的事情:使用 everyleft 将 A 的每一行与 B 的每一列配对。 matmul: { A::x B::y A{+/x*y}/:\:+B } 我们不需要更多的全局变量! matmul: {x{+/x*y}/:\:+y} 现在就是K中的矩阵乘法。这是矩阵乘法最直接的算法转换。现在我们将研究缩短它并删除更多循环的方法。 +(转置)的成本很高,我们可以将其删除。我们目前所做的事情很幼稚。我们可以将 B 的每一行与 A 的整体一致,而不是将 x 的每一行与 y 的每一列相乘,隐式地执行相同的操作。 matmul: {x{+/x*y}\:y} 现在,我们有了一个可以轻松默认的函数。根据第 3 章的规则,我们得到最终结果: matmul: (+/*)\: 一个值得您自豪的矩阵乘法函数。这个过程可能看起来有很多步骤,但是当您练习 K 技能时,压缩代码将变得更加容易和直观。矩阵乘法是一个简单的过程,与 K 的数组支持配合得很好。我们将在以后的章节中看到更多与 K 不能很好配合的算法,以及如何处理它们。
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱