这个lua的例子为什计算的结果是120,求告知n * factorial1(n - 1)的计算顺序

1742人阅读
#include &iostream&
int factorialn(int n){
if (n & 1) {
return n * factorialn(n - 1);
int main() {
int n, sum = 0;
while (cin && n) {
for (int i = 1; i &= i++) {
sum += factorialn(i);
// 如果你只想打印n的阶乘
//sum += factorialn(n);
cout && sum &&
#include &iostream&
int main() {
int n, sum = 0;
while (cin && n) {
for (int i = 0; i &= i++) {
int factorial = 1;
for (int j = 0; j & j++) {
factorial += factorial *
cout && sum &&
代码仅供参考,如果哪里有不足,欢迎各位指教,我一定会及时进行改进和优化。
如果要转载,请注明出处。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13194次
排名:千里之外
原创:13篇
评论:10条
(2)(3)(2)(1)(2)(2)(4)博客访问: 667885
博文数量: 271
博客积分: 6005
博客等级: 大校
技术积分: 2776
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
Hello World
print("Hello World")
lua hello.lua
-- defines a factorial function
function fact (n)
&&& if n == 0 then
&&&&&& return 1
&&&&&& return n
* fact(n-1)
print("enter a number:")
io.read("*number")&&&&& -- read a number
print(fact(a))
ChunkLuaChunk
1&& b = a*2&&& -- ugly, but
ChunkChunkLuaMByteChunk
5.0& Copyright ©
"Hello World"Ctrl-D in Unix, Ctrl-Z in DOS/WindowsOSos.exit()
LuaChunkLuaChunkChunk.Lua>>.
LuaChunkax=1bprint(x)
lua -la -lb
Chunkab-lrequire8.1the
require function
-iLuaChunk.
lua -i -la -lb
Chunkdofiledofile.:
-- file 'lib1.lua'
function norm (x, y)
&&& local n2 =
&&& return
math.sqrt(n2)
function twice (x)
&&& return 2*x
dofile("lib1.lua")&&&& -- load your
n = norm(3.4, 1.0)
print(twice(n))&&&&&&& --> 7.7
-idofileLua
print(b)&&&&& --> nil
print(b)&&&&& --> 10
print(b)&&&&& --> nil
(letter).LuaLualetter
and&&&&&&& break&&&&& do&&&&&&&& else&&&&&& elseif
end&&&&&&& false&&&&& for&&&&&&& function&& if
in&&&&&&&& local&&&&& nil&&&&&&& not&&&&&&& or
repeat&&&& return&&&& then&&&&&& true&&&&&& until
--[[&&& --]]
print(10)&&&&&&&& --
no action (comment)
命令行方式
lua [options]
[script [args]]
lua -e "print(math.sin(12))"&& --> -0.43
lua -i -e "_PROMPT=' lua> '"
LuaLuaLUA_INIT@filenameLua@LuafilenameLua
lua script a b c
Luaarg01-1
lua -e "sin=math.sin" script a b
= "sin=math.sin"
= "script"
阅读(1933) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。Posts - 610, Comments - 29797
其实这从来不是一个很简单的事情,虽然有些朋友认为这很简单。 伪递归我的意思是,某些看上去像递归的做法,事实上并非是递归,所以我把它叫做是“伪”递归。 例如,我们想要使用Lambda表达式编写一个计算递归的fac函数,一开始我们总会设法这样做:Func&int, int& fac = x =& x &= 1 ? 1 : x * fac(x - 1);
不过此时编译器会无情地告诉我们,fac还没有定义。于是您可能会想,这个简单,分两行写咯。于是有朋友就会给出这样的代码:Func&int, int& fac = null;
fac = x =& x &= 1 ? 1 : x * fac(x - 1);
这样看起来也很“递归”,执行起来似乎也没有问题。但是,其实这并没有使用Lambda表达式构造一个递归函数,为什么呢?因为我们使用Lambda表达式构造的其实只是一个普通的匿名方法,它是这样的:x =& x &= 1 ? 1 : x * fac(x - 1);
既然是“匿名方法”,这个构造的东西是没有名字的——因此用Lambda表达式写递归“从来不是一个很简单的事情”。那么这个Lambda表达式里的fac是什么呢?是一个“委托”。因此,这只是个“调用了一个委托”的Lambda表达式。“委托对象”和“匿名方法”是有区别的,前者是一个实际的对象,而后者只是个“定义方式”,只是“委托对象”可以成为“匿名方法”的载体而已。这个Lambda表达式构造的“委托对象”在调用时,它会去寻找fac这个引用所指向的委托对象。请注意,这里是根据“引用”去找“对象”,这意味着Lambda表达式构造的委托对象在调用时,fac可能已经不再指向当初的委托对象了。例如:Func&int, int& fac = null;
fac = x =& x &= 1 ? 1 : x * fac(x - 1);
Console.WriteLine(fac(5)); // 120;
Func&int, int& facAlias =
fac = x =&
Console.WriteLine(facAlias(5)); // 20
第一次打印出的120是正确的结果。不过facAlias从fac那里“接过”了使用Lambda表达式构造的委托对象之后,我们让fac引用指向了新的匿名方法x =& x。于是facAlias在调用时:facAlias(5)
&— facAlias是x =& x &= 1 ? 1 : x * fac(x – 1)
= 5 &= 1 ? 1 : 5 * fac(5 - 1)
= 5 * fac(4)
&— 注意此时fac是x =& x
自然就不对了。
因此,使用Lambda表达式构造一个递归函数不是一件容易的事情。
把自己传给自己吧
可能已经有朋友知道“标准”的做法是什么样的,不过我这里还想谈一下我当时遇到这个问题时想到的一个做法。比较笨(非常符合我的特点),但是可以解决问题。
我的想法是,既然使用“Lambda表达式来构造一个递归函数”的难点是因为“我们正在构造的东西是没有名字的”,因此“我们无法调用自身”。那么,如果我们换种写法,把我们正在调用的匿名函数作为参数传给自己,那么不就可以在匿名函数的方法体中,通过调用参数来调用自身了吗?于是,原本我们构造fac方法的Lambda表达式:x =& x &= 1 ? 1 : x * fac(x - 1);
就需要变成:(f, x) =& x &= 1 ? 1 : x * f(f, x - 1);
请注意,这里的f参数是一个函数,它也是我们正在使用Lambda表达式定义的匿名委托(就是“(f, x) =& ...”这一长串)。为了递归调用,它还必须把自身作为第一个参数传入下一层的调用中去,所以最后不是fac(x - 1)而是f(f, x - 1)。我们可以把这个匿名函数放到一个叫做selfFac的变量中去:var selfFac = (f, x) =& x &= 1 ? 1 : x * f(f, x - 1);
在第一次调用selfFac时,我们必须把它自身传递进去。于是我们可以这样来获得阶乘的结果:Console.WriteLine(selfFac(selfFac, 5)); // 120;
但是这段代码没法编译通过,因为编译器不知道selfFac应该是什么类型的委托对象。不过根据selfFac(selfFac, 5)的调用方式,我们可以推断出,这个委托类型会接受两个参数,第一个是它自身的类型,第二个是个整型,而返回的也是个整型。于是,我们可以得出委托的签名了:delegate int SelfFactorial(SelfFactorial selfFac, int x);
哎,但是这一点都不通用啊。没关系,我们可以写的通用一些:delegate TResult SelfApplicable&T, TResult&(SelfApplicable&T, TResult& self, T arg);
这样,我们便可以定义selfFac,甚至于selfFib(菲波纳契数列):SelfApplicable&int, int& selfFib = (f, x) =& x &= 1 ? 1 : f(f, x - 1) + f(f, x - 2);
Console.WriteLine(selfFib(selfFib, 5)); // 8
但是,这还不是我们所需要的递归函数啊。没错,我们需要的是传入一个x就可以得到结果的函数,这种每次还需要把自己传进去的东西算什么?不过这个倒也容易,在selfXxx的基础上再前进一步就可以了:SelfApplicable&int, int& selfFac = (f, x) =& x &= 1 ? 1 : x * f(f, x - 1);
Func&int, int& fac = x =& selfFac(selfFac, x);
SelfApplicable&int, int& selfFib = (f, x) =& x &= 1 ? 1 : f(f, x - 1) + f(f, x - 2);
Func&int, int& fib = x =& selfFib(selfFib, x);
为此,我们甚至可以总结出一个辅助方法:static Func&T, TResult& Make&T, TResult&(SelfApplicable&T, TResult& self)
return x =& self(self, x);
于是乎:var fac = Make&int, int&((f, x) =& x &= 1 ? 1 : x * f(f, x - 1));
var fib = Make&int, int&((f, x) =& x &= 1 ? 1 : f(f, x - 1) + f(f, x - 2));
这样我们便使用Lambda表达式定义了递归函数。当然,需要两个参数的递归函数定义方式也比较类似。首先是SelfApplicable委托类型和对应的辅助方法:// 委托类型
delegate TResult SelfApplicable&T1, T2, TResult&(SelfApplicable&T1, T2, TResult& self, T1 arg1, T2 arg2);
// 辅助方法
static Func&T1, T2, TResult& Make&T1, T2, TResult&(SelfApplicable&T1, T2, TResult& self)
return (x, y) =& self(self, x, y);
于是使用“辗转相除法”计算最大公约数的gcd函数便是:var gcd = Make&int, int, int&((f, x, y) =& y == 0 ? x : f(f, y, x % y));
Console.WriteLine(gcd(20, 36)); // 4
这也是我目前凭“个人能力”能够走出的最远距离了。
不动点组合子
但是很早给了我们更好的解决方法:static Func&T, TResult& Fix&T, TResult&(Func&Func&T, TResult&, Func&T, TResult&& f)
return x =& f(Fix(f))(x);
static Func&T1, T2, TResult& Fix&T1, T2, TResult&(Func&Func&T1, T2, TResult&, Func&T1, T2, TResult&& f)
return (x, y) =& f(Fix(f))(x, y);
Fix求出的是函数f的不动点,它就是我们所需要的递归函数:var fac = Fix&int, int&(f =& x =& x &= 1 ? 1 : x * f(x - 1));
var fib = Fix&int, int&(f =& x =& x &= 1 ? 1 : f(x - 1) + f(x - 2));
var gcd = Fix&int, int, int&(f =& (x, y) =& y == 0 ? x : f(y, x % y));
用脑袋的话来说,Fix方法应该被视为是内置方法。您比较Fix方法内部和之前的Make方法内部的写法,就能够意识到两种做法之间的差距了。
由于我的脑袋不如装配脑袋的脑袋装配的那么好,即使看来一些之后还是无法做到100%的理解,我还需要阅读更多的内容。希望在以后的某一天,我可以把这部分内容融会贯通地理解下来,并且可以详细地解释给大家听。在这之前,我还是听脑袋的话,把Fix强行记在脑袋里吧。
最后,希望大家多多参与一些如“”这样的趣味编程——不过,千万不要学脑袋这样做:var qsort = Fix&IEnumerable&int&, IEnumerable&int&&(f =& l =& l.Any() ? f(l.Skip(1).Where(e =& e & l.First())).Concat(Enumerable.Repeat(l.First(), 1)).Concat(f(l.Skip(1).Where(e =& e &= l.First()))) : Enumerable.Empty&int&());
当然,偶尔玩玩是有益无害的。所属话题:
Categories:
,登陆后便可删除或修改已发表的评论
(请注意保留评论内容)}

我要回帖

更多关于 lua回调函数例子 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信