非VBA递归因子函数?

时间:2015-07-31 12:21:34

标签: excel recursion excel-formula

是否可以通过启用循环引用(在enable iterative calculation的{​​{1}}部分中选择Formulas),在Excel中创建递归因子函数?我当然知道Excel Options,并不是在寻找一种计算阶乘的实用方法。相反,我的目标是找到一种方法来利用循环引用作为在Excel中创建和使用递归函数的通用工具,而factorial提供了一个有趣的测试用例。

使用来自Jan Karel Pietrerse website的想法我能够接近,但结果函数取决于两个单元而不是一个,所以它不能解决问题。在

enter image description here

我使用顶行中的字符串创建了命名范围。在名为FACT()的单元格中,我输入了:

factorial

并在单元格=IF(initializing,1,IF(factor=0,factorial,factorial*factor)) 中输入:

factor

上图显示了=IF(initializing,n,IF(factor=0,factor,factor-1)) n = 10时的情况。 initializing = True中的公式对应于函数式编程中的标准技巧,通过引入具有累积参数的辅助函数来生成递归函数tail-call recursive。问题是需要调用辅助函数,并且factorial中的公式在某种意义上是函数本身及其辅助函数,factorial的内容决定了它当前正在扮演什么角色。

我所做的工作在某种意义上说,如果我将initializing的值转换为True(例如只是删除它),则initializing的值将成为正确的阶乘:

enter image description here

可以从图片中移除factorial吗?是否可以修改设置,以便例如initializing更改为5然后n立即更改为120而无需先设置然后更改其他一些单元格?我尝试了几个不同的东西,但最终只有两步而不是一步功能。也许一些涉及数组公式的魔法?

5 个答案:

答案 0 :(得分:3)

这是一个只有一个帮助单元格的公式,每当n发生变化时自动更新,当然辅助列比原始列更复杂:
enter image description here

  • 帮助:=IF(C2<>TEXT(A2,"0"),IF(ISNUMBER(C2),IF(C2=A2,TEXT(A2,"0"),C2+1),1),C2)
  • 阶乘:=IF(ISNUMBER(C2),IF(C2=1,1,C2*D2),D2)

关键是在达到结果时更改辅助单元格(也可以否定,用文本填写(例如A1&" Finished"),重要的是要明确它到达计算结束并保持可比性与输入单元格。)

只是为了好玩,在F2中没有迭代的数组公式:=PRODUCT(ROW(INDIRECT("a1:a"&A2,TRUE)))

更新

一步一步的公式:
帮手:

  • 稳定状态被格式化为文本,只要文本的值与n相同,没有任何反应,公式不会更改helper中的值
  • 更改n后:第一个条件C2<>TEXT(A2,"0")将为false,但helper仍为文字,因此第二个条件也为false,helper重置为1 < / LI>
  • 之后helper递增,直到达到n,达到目标时helper将转换为文本以标记计算已完成

阶乘:

  • helper文字没有任何反应
  • 一旦helper为数字:如果是1,则factorial重置为1,否则计算乘法helper * factorial

答案 1 :(得分:1)

这是我的评论意思 - 使用VBA来检查/取消选中&#34;初始化框,每当&#34; n&#34;改变了价值。

我尝试使用你的示例中的命名范围,它对我有用。可以推断用于其他目的;这里的关键是你仍然需要初始化&#39;单元格[真的你可能只是初始化&#39;是一个命名范围,仅指一个布尔值,而不是一个包含布尔值的单元格],但它至少会自动化。

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)


If Target.Address = Range("n").Address Then

    Range("initializing").Formula = True
    Range("initializing").Formula = False
End If

End Sub

答案 2 :(得分:1)

假设我们要创建一个具有以下限制的阶乘公式:

  1. 不要使用内置的FACT()工作表功能
  2. 不启用迭代计算
  3. 不要使用VBA
  4. 不要使用手动输入的数组公式
  5. 不要使用“辅助”单元格

使用 Excel 365 ,在单元格 A1 中输入一些值(例如8)
A2 中>输入:

=PRODUCT(SEQUENCE(A1))

enter image description here

SEQUENCE()函数给出的“历史记录”为8,并允许我们模拟?递归。

EDIT#1:

在Win 7计算机上使用 Excel 2007 ,此数组公式

=PRODUCT(ROW(INDIRECT("1:" & A1)))

enter image description here

给出等效项。我不得不违反第4条限制,因为 Excel 2007 中没有动态溢出。

答案 3 :(得分:0)

使用 VBA

Public Function factoid(n As Long) As Long
    If n = 1 Then
        factoid = 1
    Else
        factoid = factoid(n - 1) * n
    End If
End Function

答案 4 :(得分:0)

是的,可以从算法中删除“初始化”变量。

我们来看一个例子。

image

image

我有3个单元格:class HelloComponent2 extends React.Component { constructor(props){ super(props); this.state = {name: props.name} } render(){ return( <h1>Hello, {this.state.name}</h1> ) } } ReactDOM.Render( <HelloComponent2 name="DCR" />, document.getElementById("root")) numberfactorial

首先,在使用迭代计算时你应该记住的主要事情是检查0的iteration语句,因为默认情况下空单元格为0,并且如我们所知,乘法中的零(因子的主要部分是坏主意。

IF单元格得到了这个公式: iteration

=IF(i=0, number+1,i-1)单元格得到了这个公式: factorial

因此,如果在=IF(factorial=0, 1, IF(i=1, factorial, factorial*i))单元格中iteration单元格中的0或1(它取决于excel选择,还有月相),您应该得到正确的答案。

当然,通过更改factorial,您可以注意到number单元格不是0或1,而iteration看起来不像预期结果。尝试按 F9 直到你没有得到它。