You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在J语言中编写无循环的累加递归函数

J语言无循环实现阶乘基迭代收集

首先,针对你的需求,我们可以利用J语言的前缀扫描(\)和条件迭代特性,无需显式循环或累加器来实现目标。

核心逻辑梳理

你的函数f=:([<.@%]),(]|[)本质是输入(num, k),返回(num//k, num%k)(整数商和余数)。我们需要的迭代逻辑是:

  1. 初始输入为(n, 1)(n是目标数,初始k=1)
  2. 每次迭代用前一次的商作为新的num,同时k自增1,作为下一次输入
  3. 直到num变为0,收集所有余数并反转(得到你要的3:4:1:0:1:0顺序)

问题2:传递迭代参数(无需显式循环)

先构造一个状态转换函数,用来生成下一次迭代的输入参数:

next_state=: ([: <.@% [ ]), (>: ])

这个函数接收二元组(num, k),返回(num//k, k+1)——也就是把前一次的商作为新num,k自增1,直接作为下一次的输入。

用J的**前缀扫描(\)**配合无限迭代^:_,可以自动生成所有迭代状态:

states=: next_state\^:_ 463 1

执行后会得到所有中间状态序列:

463 1
463 2
231 3
77 4
19 5
3 6
0 7
0 8
...

我们只需要保留num>0的有效状态(到3 6为止),用筛选器过滤:

valid_states=: #~ 0&<.~ {. each states

这样就得到了所有需要参与余数计算的状态,完全不需要手动维护循环变量或累加器。


问题1:生成目标余数序列

从有效状态中提取每个(num, k)的余数(num%k),再反转顺序就能得到你要的序列:

remainders=: {: | {. each valid_states  // 提取每个状态的余数
target_seq=: |. remainders              // 反转得到最终序列

执行target_seq会输出:3 4 1 0 1 0,和你要的结果一致。

封装成完整函数

把上述步骤封装成一个可复用的动词,直接传入目标数即可:

factorial_base_digits=: 3 : 0
  next_state=: ([: <.@% [ ]), (>: ])
  states=: next_state\^:_ y , 1
  valid_states=: #~ 0&<.~ {. each states
  |. {: | {. each valid_states
)

测试调用:

factorial_base_digits 463

输出结果:3 4 1 0 1 0


关于windowing技术的说明

你提到的windowing技术,本质是通过序列的滑动窗口传递上下文参数。这里的前缀扫描\其实就是一种自动的windowing实现——它把每次迭代的结果作为下一次的输入窗口,自动完成参数的传递和推进,完美契合你的需求,无需手动处理窗口滑动逻辑。

内容的提问来源于stack exchange,提问作者Shmuel Greenberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 02:54:52