最近回答了涉及Ackerman功能的问题,其中一部分功能涉及计算数字的分解。这让我思考是否有更有效的方法来做到这一点。我自己做了一些测试,但我主要受限于这样一个事实,即5 ^^ 3 = 5 ^ 3125给出5 ^ 3的数字大约是10 ^ 2,意味着5 ^ 3125~ = 10 ^(3125 * 2/3)大约2000位数。
由于取幂的性质,该函数不适用于划分和征服方法,即:
2 ^ ^ 5 = 2 ^(2 ^(2 ^(2 ^ 2))))= 2 ^(2 ^(2 ^ 4))= 2 ^(2 ^ 16)= 2 ^ 65536〜= 10 ^(65536 * 3/10)所以大约20k位...
问题的本质,因为它从电源树的顶部开始并向下工作,这让我觉得是阶乘的。可以使用快速功率算法来进行取幂运算,但是我还没有看到缩小取幂运算次数的方法。
如果有人不清楚我在说什么是wiki article,基本上虽然tetration是:
a ^^ b = a ^ a ^ a .... ^ a,b次然后在幂树的顶部元素处开始取幂并向下运算。
我目前正在使用的算法是(虽然如果我真的想要值,我会使用ruby版本):
long int Tetration(int number, int tetrate)
{
long int product=1;
if(tetrate==0)
return product;
product=number;
while(tetrate>1)
{
product=FastPower(number,product);
tetrate--;
}
return product;
}
任何想法都将不胜感激。
答案 0 :(得分:4)
对于tetration,如果最终答案是d位,则所有中间结果都是O(log d)位,而不是带取幂的O(d)位。因为与最终结果相比,分类的中间结果是如此之小,所以通过分而治之无法节省。由于取幂不是关联的,因此在单位成本RAM中保存取幂运算的可行方法也不太可能。
答案 1 :(得分:0)
快速测试确认您可以使用与功率算法相同类型的加速:
a↑↑2b =(a ^ a)
甚至更一般: a↑ⁿ2b =(a↑ⁿ-1 a)↑ⁿb
代码用于确认这一点:
for(long a = 2; a < 5; a++) {
for(long b = 2; b < 5; b++) {
if(b%2 == 0) {
System.out.println(a+"↑↑"+b+"="+tetration(BigInteger.valueOf(a), BigInteger.valueOf(b)));
long pow = (long) Math.pow(a, a); // pow = tetration(a,2)
System.out.println(pow+"↑↑"+b/2+"="+tetration(BigInteger.valueOf(pow), BigInteger.valueOf(b/2)));
}
}
}
答案 2 :(得分:-1)
我不认为有一种简单的方法可以进行tetration, 所以我做了这个:
<!DOCTYPE html>
<html>
<head>
<script>
var x = 1
//That is ▽ The Number You Are Powering//
var test = 3
var test2 = test
setInterval (function () {
// that is ▽ How many times you power it so this would be 3 tetra 3 which is 7625597484987//
if (x < 3) {
document.getElementById('test').innerHTML = test=test2**test
x++
}
}, 1);
</script>
<p id="test">0</p>