我最近遇到了一个方法,它返回给定数字的最小因子:
public static int findFactor(int n)
{
int i = 1;
int j = n - 1;
int p = j; // invariant: p = i * j
while(p != n && i < j)
{
i++;
p += j;
while(p > n)
{
j--;
p -= i;
}
}
return p == n ? i : n;
}
在检查了方法后,我能够(很可能是错误的)确定某些变量分别代表的数量:
n = the int that is subject to factorization for
the purposes of determining its smallest factor
i = the next potential factor of n to be tested
j = the smallest integer which i can be multiplied by to yield a value >= n
问题是我不知道p
代表什么数量。内循环似乎将(p+=j) - n
视为一个
i
的潜在倍数,但鉴于我认为j
所代表的,我不明白这是怎么回事
对于所有i
,或外循环如何解释执行的内循环的“额外”迭代
在后者因p < n
假设我已正确确定n
,i
和j
代表什么,p
表示的数量是多少?
如果我的任何决定都不正确,那么每个数量代表什么?
答案 0 :(得分:4)
p
代表“产品”。如上所述,不变量是p == i*j
;并且算法会尝试i
和j
的不同组合,直到产品(p
)等于n
。如果它永远不会(while
循环失败),则会得到p != n
,因此返回n
(n
为素数)。
在外while
循环体的末尾,j
是最大整数,i
可以乘以得到一个值≤n
该算法避免显式划分,并尝试限制每个j
检查的i
值的数量。在外循环的开头,p==i*j
小于n
。随着i
逐渐增加,j
需要逐渐缩小。在每个外部循环中,i
增加(并且p
被更正以匹配不变量)。然后内部循环减少j
(并更正p
),直到p
再次<n
。由于i*j
仅在下一个外部循环开始时小于n
,因此增加i
会使产品再次大于n
,并重复这个过程。
答案 1 :(得分:1)
该算法会尝试1
和n / i
之间的所有除数(继续n / i
之后没有用,因为已经尝试了相应的商数。)
所以外循环实际执行
i= 1
while i * (n / i) != n && i < n / i)
{
i++;
}
通过避免分裂,它以巧妙的方式完成。正如注释所说,保持了不变p = i * j
;更准确地说,p
是i
的最大倍数,不超过n
,实际上它确定j = n / i
。
i
增加时需要进行一些调整:i
成为i + 1
,p = i * j
成为(i + 1) * j = p + j
,p
可能变得太大了。这可以通过根据需要递减j
次数(j--, p-= i
)来修复。