(4/3)^S <= A+B
S <= lg[4/3](A+B)
S is O(lg[4/3](A+B))
S is O(lg(A+B))
S is O(lg(A*B)) //because A*B asymptotically greater than A+B
S is O(lg(A)+lg(B))
//Input size N is lg(A) + lg(B)
S is O(N)
所以迭代次数与输入位数成线性关系。对于适合于 CPU 寄存器的数字,将迭代建模为采用常数时间并假设 gcd 的 总数运行时间是线性的是合理的。
当然,如果处理的是大整数,就必须考虑到每次迭代中的模运算的成本不是常数这一事实。粗略地说,总的渐近运行时间将是 n ^ 2乘以一个多对数因子。差不多n^2 lg(n) 2^O(log* n).通过使用 二进制 GCD可以避免多对数因子。
int iterativeEGCD(long long n, long long m) {
long long a;
int numberOfIterations = 0;
while ( n != 0 ) {
a = m;
m = n;
n = a % n;
numberOfIterations ++;
}
printf("\nIterative GCD iterated %d times.", numberOfIterations);
return m;
}
int iterativeEGCDForWorstCase(long long n, long long m) {
long long a;
int numberOfIterations = 0;
while ( n != 0 ) {
a = m;
m = n;
n = a - n;
numberOfIterations ++;
}
printf("\nIterative GCD iterated %d times.", numberOfIterations);
return m;
}
是的,与斐波那契对,n = a % n和 n = a - n,这是完全相同的事情。
We also know that, in an earlier response for the same question, there is a prevailing decreasing factor: factor = m / (n % m).
void iterativeGCDSimulator(long long x, long long y) {
long long i;
double factor = x / (double)(x % y);
int numberOfIterations = 0;
for ( i = x * y ; i >= 1 ; i = i / factor) {
numberOfIterations ++;
}
printf("\nIterative GCD Simulator iterated %d times.", numberOfIterations);
}
首先想想如果我们取两个斐波那契数 F (k + 1)和 F (k)的 gcd。你可能会很快发现,欧几里得的算法迭代到 F (k)和 F (k-1)。也就是说,在每次迭代中,我们向下移动斐波那契数列中的一个数。由于 Fibonacci 数是 O (Phi ^ k) ,其中 Phi 是黄金比率,我们可以看到 GCD 的运行时间是 O (log n) ,其中 n = max (a,b) ,log 以 Phi 为基数。接下来,我们可以证明这将是最坏的情况,通过观察斐波那契数一直产生对,其余部分在每次迭代中保持足够大,并且直到你到达序列的开始才变为零。
我们可以使 O (logn) ,其中 n = max (a,b)的束缚更加紧密。假设 b > = a,这样我们就可以在 O (log b)上写定界。首先,观察 GCD (ka,kb) = GCD (a,b)。由于 k 的最大值是 gcd (a,c) ,因此我们可以在运行时用 b/gcd (a,b)替换 b,从而得到更紧的 O 界(log b/gcd (a,b))。