主题:阶乘
moz
[专家分:37620] 发布于 2007-05-24 21:15:00
DECLARE FUNCTION js$ (n&)
DECLARE FUNCTION xxx$ (s$, i&)
DEFLNG A-Z
t1# = TIMER
PRINT js$(1000)
PRINT TIMER - t1#
FUNCTION js$ (n)
s$ = "1"
FOR i = 1 TO n
s$ = xxx$(s$, (i))
DO WHILE RIGHT$(s$, 1) = "0"
k = k + 1
s$ = LEFT$(s$, LEN(s$) - 1)
LOOP
NEXT
js$ = s$ + STRING$(k, "0")
END FUNCTION
FUNCTION xxx$ (s$, i)
L3 = 8 - LEN(STR$(i))
p = 10 ^ L3
v = 0
FOR j = (LEN(s$) - L3 + 1) TO 1 STEP -L3
v = VAL(MID$(s$, j, L3)) * i + v
ss$ = RIGHT$(STR$(v), L3) + ss$
v = v \ p
NEXT
IF j > 1 - L3 THEN v = VAL(LEFT$(s$, j + L3 - 1)) * i + v
IF v > 0 THEN ss$ = STR$(v) + ss$
xxx$ = LTRIM$(ss$)
END FUNCTION
回复列表 (共26个回复)
11 楼
剑圣风暴 [专家分:450] 发布于 2007-07-23 12:17:00
翻书去!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12 楼
V2战警2 [专家分:390] 发布于 2007-07-27 17:35:00
[i]是不是跟帖就能加分啊??[/i]
13 楼
Lovely哆啦 [专家分:1360] 发布于 2007-09-30 14:35:00
看不懂,能解释一下吗?
14 楼
QB小猪 [专家分:1200] 发布于 2007-10-10 18:43:00
同意10楼的.........好难懂..........
15 楼
tujunqiang [专家分:150] 发布于 2007-11-07 22:55:00
CLS
INPUT "n="; n
DIM a(5000)
a(0) = 1: a(1) = 1
FOR i = 1 TO n
a(1) = a(1) * i
FOR j = 2 TO a(0)
a(j) = a(j) * i
a(j) = a(j) + a(j - 1) \ 10
a(j) = a(j) MOD 10
NEXT j
DO WHILE a(a(0)) >= 10
a(0) = a(0) + 1
a(a(0)) = a(a(0) - 1) \ 10
a(a(0) - 1) = a(a(0) - 1) MOD 10
LOOP
next i
FOR i = a(0) TO 1 STEP -1
PRINT USING "#"; a(i);
NEXT i
END
16 楼
moz [专家分:37620] 发布于 2008-03-21 23:46:00
3楼代码错写多了一个括号.
速度是比2楼快上一倍的.
但缺点就是只能算到 3*N+1 比如是3*666+1=1999!
但这跟单纯的乘法是不同的,
因为它有一个参数是数值类型的,
所以要比一般乘法快上几倍.
17 楼
雨中飞燕 [专家分:18980] 发布于 2008-03-24 23:11:00
请问算10000!用多长时间?顺便说明一下测试环境
18 楼
moz [专家分:37620] 发布于 2008-03-25 00:51:00
狱中肺炎别拿我来开玩笑了,我QB哪能跟你C来比?
我只是说说个人方法,你有更好的算法就指点一二嘛,
网上经常能看到秒杀的字样,可我就是没理解到底是怎么一回事.
干嘛拿我来出丑呢,QB里肯定要溢出了.
而且我的机器那么老,这么一折腾,还不得爆炸?
19 楼
moz [专家分:37620] 发布于 2008-03-25 02:31:00
我看过你的四行代码了,
我C不在行,也少用(应该说是从来没用过)
看得出来,当中并没有取巧的办法,其中并没有数理方面的技巧.
也只是把每一个数都算一次,
我用我的代码算了一下1000!的得数是跟你的一致的.
赛扬1.7G,时间约为1秒.
QB是没办法和C作比较的,因为它的限制,因为它的效率.
数组也好,字符串也好,不能超过64K,总量不能超过640K
而且不能直接访问内存空间,我大部份时间里都会拿字符串来幻想它是一个内存空间来操作.
虽然,我已经利用最大的货币型进行运算了.
而且因为需要减少字符串转换运算的原因,已经改到一次计算三个数值了.
但是还是没有办法和没有限制没有转换的C来作比较的.
不过我还是特地运算了几次10000!
在QB里字符串溢出,最大值只能算到6907! 需时200秒,
我把6907!改到EXCEL里运行,时间变成了350秒.
在EXCEL里算到10000! 的时候,需要1200秒.(算了20分钟,得数长度为35560,我够耐性了吧)
20 楼
moz [专家分:37620] 发布于 2008-03-25 19:55:00
既然省略字符串转换的数组速度更快,
那么我也按照你的方法来做成QB代码,
QB里62秒.的确要快上几倍.
DEFLNG A-Z
t1# = TIMER
DIM s(16383)
s(0) = 1
s(1) = 1
FOR i = 1 TO 10000
FOR j = 1 TO s(0)
x = i * s(j) + x
s(j) = x MOD 10000
x = x \ 10000
NEXT
IF x > 0 THEN
s(0) = s(0) + 1
s(s(0)) = x
x = 0
END IF
NEXT
Print s(s(0));
FOR i = s(0) TO 1 STEP -1
PRINT right$("0000"+ltrim$(str$(s(i))),4);
NEXT
PRINT TIMER - t1#
我来回复