如何用J语言实现“最大连续1问题”的APL对应表达式?
最大连续1问题:APL到J语言的实现转换
原APL解法回顾
论文《Combinatory Logic and Combinators in Array Languages》中给出的APL解法如下:
vec ← 1 1 0 1 1 1 0 0 0 1 ⍝ 按0分割连续1的子列表 ⊆⍨vec ┌───┬─────┬─┐ │1 1│1 1 1│1│ └───┴─────┴─┘ ⍝ 计算每个子列表长度 ≢¨⊆⍨vec 2 3 1 ⍝ 求最大值 ⌈/≢¨⊆⍨vec 3
核心逻辑可概括为:reduce(max, map(length, partition(vec, 0)))
J语言等价实现
核心表达式
对应APL核心语句⌈/≢¨⊆⍨vec的J语言实现为:
>./ #&> ;.1 (~1&=) vec
执行结果为3,与APL解法一致。
分步拆解与J分区操作说明
- 定义目标向量
vec =: 1 1 0 1 1 1 0 0 0 1
- 按0分割子列表(对应APL的
⊆⍨)
J中用;.(分区操作符)实现类似APL的分区功能,这里使用;.1模式(分割后丢弃分隔符),结合布尔掩码标记分隔位置:
;.1 (~1&=) vec NB. 掩码`~1&=vec`标记所有0的位置为分隔点,分割后丢弃0
输出结果:
+---+-----+-+ |1 1|1 1 1|1| +---+-----+-+
- 计算子列表长度(对应APL的
≢¨)
用#&>对每个子列表取长度(#是长度函数,&>表示对每个嵌套列表应用函数):
#&> ;.1 (~1&=) vec
输出结果:2 3 1
- 求最大值(对应APL的
⌈/)
用>./对长度列表做最大值归约:
>./ #&> ;.1 (~1&=) vec
输出结果:3
关于J的分区操作;.
;.是J语言的核心分区操作符,通过参数控制分割行为:
;.n中的n指定分隔符处理方式:;.1表示分割后丢弃分隔符,只保留有效数据段;;.0则会保留分隔符作为单独的段- 第一个参数为布尔掩码,掩码值为1的位置即为分割点
内容的提问来源于stack exchange,提问作者madeofmistake
相关产品推荐
相关产品推荐

