算法常用数学知识

1.判断质数(试除法)

算法思想:(1).暴力方法是从2枚举到n-1,判断n是否有这个因子,时间复杂度为O(n);
(2).试除法:不需要再枚举到n-1,试想,如果i是n的因子,那么n/i也一定是n的因子,因此我们只需枚举到除二以外最小的因子,如果存在这个因子,那么n必然不是质数。时间复杂度降为O(sqrt(n)).

bool is_prime(int n)
	for(int i = 2; i <= n / i; i ++ )
	{
		if(n < 2) return false;
		if(n % i == 0) return false;
	}
	return true; 

分解质因子比判断质数多一个特判条件,是由于,如果n存在一个比根号n大的质因子i的话,那么这个 n / i 一定在前面已经出现过了,所以如果前面没有出现过一个i使得n % i 等于0,那么肯定不存在那个比根号n大的质因子,所以不需要进行特判,但是分解质因数是要输出所有的质因子,因此最后需要把那个质因子特判进行输出

2.分解质因子(试除法)

质因数为一个数的所有因子中的质数,计算所有质因子的次数
性质:一个合数必然可以由几个质因子相乘得到
算法思想:(1).暴力需要枚举n的所有因子,判断这个因子是否是质数,时间复杂度为O(n)
(2).试除法,每次将n / i,循环中的i必为质数,细节在代码中说明:

//其中i <= n / i;其实意思就是枚举到小于等于根号n的质因子,最后比根号n大的质因子单独判断
for(int i = 2; i <= n / i; i ++ )
{
	int s = 0; //质因数的次数 
	if(n % i == 0)// 循环中的i一定是质数,因为如果是合数,那么这个合数一定也存在质因子,且质因子一定比i小,但是比i小的数在前面的循环中已经除去,因此i一定没有质因子,所以i一定为质数
	{
		// 计算i这个质因子的次数
		while(n % i == 0)
		{
			n /= i;
			s ++;
		}
	}
	printf("%d %d", i ,s);
}
//特殊情况判断
//由于一个数最多有可能存在一个大于sqrt(n)的质因数,但是上面这个循环只能枚举到sqrt(n),因此需要单独判断最后这个质因数
//当循环结束时,如果正常情况下没有大于sqrt(n)的质因数时,最后n / i 的结果为1,也就是n == 1
if(n > 1)
	printf("%d %d",n ,1 ); 
3.试除法求约数(按顺序)
vector<int> get_divisor(int x)
{
	for(int i = 1; i <= x / i; i ++ )
	{
		if(x % i == 0)
		{
			res.push_back(i);
			if(i != x  / i)
				res.push_back(x / i);
		}
	}
	sort(res.begin(), res.end());
	return res;
}

int main()
{
	auto resluts = get_divisor(x);
	for(auto t : results)	printf("%d ", t);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值