网上朋友聊天,随便出了个简单的题目。对一个正整数(不含0)进行因数分解。要求:
输入:100
输出:2 * 2 * 5 * 5 = 100
输入:13
输出:13 = 13
很简单的一个题目。时间有限,只给十分钟。
很快,被问者给出答案:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int m = 0;
int i = 2;
printf("\n请输入:");
scanf("%d",&m);
for(;i<m;i++)
{
if(m%i == 0)
{
printf("%d",i);
if(m/i!=1)
printf("*");
m=m/i;
i=1;
}
}
return 0;
}
这个代码基本完成了目标。(但输出格式是不对,输入1也有问题)。继而又问,如何优化该代码。使得运算速度增加。
这个问题看似难回答,其实还是比较好回答的。因为这段代码里只有一个循环,无非是如何减少循环的次数。
第一个办法,对于一个给定的整数A, 其平方根为r, r = sqrt(A)。那么,如果被小于r的整数整除,必然产生一个比r大的整数。如果被r大的整数整除,必然产生一个比r小的整数。
所以,没必要从2一直循环到m,只要循环到 r就可以了。如果都没有被整数,那么此数必然是个质数。
第二个办法,质数除了2是偶数之外,没第二个偶数了。所以,在原来r的基础上,又可以少上大约一半的循环。所以这个代码改为:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int m = 0, d;
int i = 2;
printf("\n请输入:");
scanf("%d",&m);
d = m;
while (m >= 1)
{
if(m % i == 0)
{
printf("%d",i);
m= m / i;
if(m != 1)
printf("*");
i = 2;
}
else
{
if (i * i > m)
}
i++;
i |= 0x01;
}
}
printf(" = %d\n", d);
return 0;
}
对于内部含有大质数的合数来说,这个代码循环数会大大减少。比如说:994这个数,循环10次即可用第二种算法分解完毕;用第一种,大约需要循环70多次。所含质数越大,效果越明显。如果把从1到1000000的数全部分解。速度会有明显的差异。
第三种办法,质数的数量是比较稀少的,可以建立一个表,直接除表里的数就可了。不过,这个要事先计算,需要一定的空间存储。也可以在计算过程中动态生成质数表,不过这个不适合对单个整数的分解,适合对一大批数进行分解。
输入:100
输出:2 * 2 * 5 * 5 = 100
输入:13
输出:13 = 13
很简单的一个题目。时间有限,只给十分钟。
很快,被问者给出答案:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int m = 0;
int i = 2;
printf("\n请输入:");
scanf("%d",&m);
for(;i<m;i++)
{
if(m%i == 0)
{
printf("%d",i);
if(m/i!=1)
printf("*");
m=m/i;
i=1;
}
}
return 0;
}
这个代码基本完成了目标。(但输出格式是不对,输入1也有问题)。继而又问,如何优化该代码。使得运算速度增加。
这个问题看似难回答,其实还是比较好回答的。因为这段代码里只有一个循环,无非是如何减少循环的次数。
第一个办法,对于一个给定的整数A, 其平方根为r, r = sqrt(A)。那么,如果被小于r的整数整除,必然产生一个比r大的整数。如果被r大的整数整除,必然产生一个比r小的整数。
所以,没必要从2一直循环到m,只要循环到 r就可以了。如果都没有被整数,那么此数必然是个质数。
第二个办法,质数除了2是偶数之外,没第二个偶数了。所以,在原来r的基础上,又可以少上大约一半的循环。所以这个代码改为:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int m = 0, d;
int i = 2;
printf("\n请输入:");
scanf("%d",&m);
d = m;
while (m >= 1)
{
if(m % i == 0)
{
printf("%d",i);
m= m / i;
if(m != 1)
printf("*");
i = 2;
}
else
{
if (i * i > m)
{
if (m != 1)//感谢weiMMXfighting朋友的指正
printf("%d", m);
}
i++;
i |= 0x01;
}
}
printf(" = %d\n", d);
return 0;
}
对于内部含有大质数的合数来说,这个代码循环数会大大减少。比如说:994这个数,循环10次即可用第二种算法分解完毕;用第一种,大约需要循环70多次。所含质数越大,效果越明显。如果把从1到1000000的数全部分解。速度会有明显的差异。
第三种办法,质数的数量是比较稀少的,可以建立一个表,直接除表里的数就可了。不过,这个要事先计算,需要一定的空间存储。也可以在计算过程中动态生成质数表,不过这个不适合对单个整数的分解,适合对一大批数进行分解。