|
为了提升一些性能, 可以进行以下优化:
首先,1,10,100的幂的和, 都是1, 可以排除。
另外, 我们可以先找一个可能比较大的数, 比如99^100, 看看这个数的数字和:
with t1 as (select pkg_bignum.bigpower2(99, 100) p from dual )
,tsum as (select p, sum(substr(p,d,1)) sump from t1, (select rownum d from dual connect by rownum<=201) tlen where d<=length(p) group by p)
select max(sump) from tsum
MAX(SUMP)
----------
873
既然这个数是873, 那就意味着最大数一定>873. 而>873, 意味着那个幂至少有873/9=97位。 因此我们可以把幂的位数低于97的排除掉。
with t as (select level n from dual connect by level<=100)
,t1 as (select /*+ MATERIALIZE */ distinct pkg_bignum.bigpower2(t1.n, t2.n) p
from t t1, t t2
where t1.n not in (1, 10, 100) and t2.n*log(10,t1.n) >=97)
,tsum as (select p, sum(substr(p,d,1)) sump
from t1, (select rownum d from dual connect by rownum<=201) where d<=length(p) group by p)
select * from tsum
/
MAX(SUMP)
----------
972
Executed in 30.719 seconds
优化的结果是省了很多循环量(从tsum的行数可以看出, 从 9271减少到3639), 但没省多少时间。 这是因为无论大数幂运算,还是后面的对各位数字求和,都是当位数越多时计算越慢,耗时大的数都保留下来了, 节省的那些都是不需要太长时间计算的小数。 |
|