针对计算给定数字的约数数量,最优算法(在性能上)是什么?
如果您能提供伪代码或示例链接,那将非常好。
编辑:所有答案都非常有帮助,谢谢。 我正在实现Atkin筛法,然后将使用类似于Jonathan Leffler指出的方法。 Justin Bozonier发布的链接提供了我所需的更多信息。
针对计算给定数字的约数数量,最优算法(在性能上)是什么?
如果您能提供伪代码或示例链接,那将非常好。
编辑:所有答案都非常有帮助,谢谢。 我正在实现Atkin筛法,然后将使用类似于Jonathan Leffler指出的方法。 Justin Bozonier发布的链接提供了我所需的更多信息。
这是一个高效的解决方案:
#include <iostream>
int main() {
int num = 20;
int numberOfDivisors = 1;
for (int i = 2; i <= num; i++)
{
int exponent = 0;
while (num % i == 0) {
exponent++;
num /= i;
}
numberOfDivisors *= (exponent+1);
}
std::cout << numberOfDivisors << std::endl;
return 0;
}
这是计算一个数的因子最基本的方法:
class PrintDivisors
{
public static void main(String args[])
{
System.out.println("Enter the number");
// Create Scanner object for taking input
Scanner s=new Scanner(System.in);
// Read an int
int n=s.nextInt();
// Loop from 1 to 'n'
for(int i=1;i<=n;i++)
{
// If remainder is 0 when 'n' is divided by 'i',
if(n%i==0)
{
System.out.print(i+", ");
}
}
// Print [not necessary]
System.out.print("are divisors of "+n);
}
}
n
的除数数量,那么显然无需跨越整个范围1...n
。我没有进行任何深入研究,但我解决了欧拉计划中三角形数问题12。我为解决方案编写了这个除数函数,用于进行大于500个除数的测试,运行时间为309504微秒(约0.3秒)。请参考以下代码:int divisors (int x) {
int limit = x;
int numberOfDivisors = 1;
for (int i(0); i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
numberOfDivisors++;
}
}
return numberOfDivisors * 2;
}
每个算法都有弱点。我曾认为它对质数不利,但由于三角形数不是质数,这个算法毫无瑕疵地发挥了作用。从我的剖析结果来看,我认为它表现得非常好。
节日快乐。
public static List<Integer> divisors(n) {
ArrayList<Integer> aList = new ArrayList();
int top_count = (int) Math.round(Math.sqrt(n));
int new_n = n;
for (int i = 2; i <= top_count; i++) {
if (new_n == (new_n / i) * i) {
aList.add(i);
new_n = new_n / i;
top_count = (int) Math.round(Math.sqrt(new_n));
i = 1;
}
}
aList.add(new_n);
return aList;
}
质数筛法在这里非常明确。 P[] 是一个质数列表,其中包含小于等于 sq = sqrt(n) 的所有质数;
for (int i = 0 ; i < size && P[i]<=sq ; i++){
nd = 1;
while(n%P[i]==0){
n/=P[i];
nd++;
}
count*=nd;
if (n==1)break;
}
if (n!=1)count*=2;//the confusing line :D :P .
i will lift the understanding for the reader .
i now look forward to a method more optimized .
#include<stdio.h>
#include<math.h>
int main()
{
int i,n,limit,numberOfDivisors=1;
printf("Enter the number : ");
scanf("%d",&n);
limit=(int)sqrt((double)n);
for(i=2;i<=limit;i++)
if(n%i==0)
{
if(i!=n/i)
numberOfDivisors+=2;
else
numberOfDivisors++;
}
printf("%d\n",numberOfDivisors);
return 0;
}
除了上面的for循环,您还可以使用以下更高效的循环,因为它不需要找到数字的平方根。
for(i=2;i*i<=n;i++)
{
...
}