数论--整除&素数
这一篇里的符号如未详细说明则都是整数。
带余除法#
小学时候我们学过加减乘除,我们知道两个整数相加、减、乘得到的结果都是整数,只有除法不一定。那时候我们还没学过小数,我们的解决办法是使用余数。
比如:5/2=2...1
,读作五除以2等于2余1
。
这里面五是被除数,二是除数,结果中的二是商,省略号后面的一是余数。
我们把它用一般化的式子表示,这也是带余除法定理。
除和除以#
直到大二我也没分清除和除以的关系,导致我第一次看这章的时候云里雾里的。
除和除以都是谓语,代表一个动作,除的主语要是除数,而除以的主语要是被除数。
例如上面的例子,你可以说是五除以二或者二除五,你不能说是二除以五,那样就反了。
整除符号#
假如a除以b的余数为零,也就是说满足a=bc
的关系,那么就说明a能被b整除,记作b|a
。
如果无法整除记作
一些性质#
- 若,那么
- 若那么
- 若,那么对所有都有
素数#
如果一个数只能被1和它本身整除,这个数就是素数,否则就是合数。1既不是素数也不是合数。
2是素数里唯一一个偶数,也是最小的素数。其他偶数都可以被2整除。
最小因数#
我们发现,一个数的最小因数一定是一个素数(除了1)。我们不妨列出几个数看看。
4 - 1,2,4
6 - 1,2,3,6
8 - 1,2,4,8
9 - 1,3,9
12 - 1,2,3,4,6,12
我们可以看到这些因数里除了1和它本身外,最小的都是素数。
证明一下。用反证法吧。
商拆分#
一个合数肯定能拆成若干个素数的乘积。
假如a是和数,一定能找出一个纯素数数列乘积为a。
这个证明方式和上面的差不多,不证明了。其实也非常容易想出来。
举个例子
寻找1-N之间的素数#
学编程语言的时侯我们大家基本上都写过这个程序。大部分是这样写的:
void get_prime_nums_traditional(){
prime_nums.push_back(2);
for (int i = 3; i <= N; i++) {
int j=2;
for (; j <= i-1; j++) {
if (i % j==0)
break;
}
if (j==i)
prime_nums.push_back(i);
}
}
这个写法没错,而且在教学中是一个很经典的双循环示例。但是我们学了数论之后可就不能这么写了。我们已经探究了素数的很多性质,就应该写出更快速高效的代码。
上面的代码把3~n中的所有数遍历一遍,并且使用一个内循环,再把2到当前数i减1的所有数和i做余数运算,如果在2~i-1中有任何一个数字能整除i,就证明它不是素数。如果没找到整除的数字就是素数。
我们大可不必如此费力。
判断是否是素数#
假设给我们一个数a,我们怎么判断它是否是素数?
我们知道,这个数肯定能写成的形式,假设那么就一定有,因为b大于根号a了c也一定大于根号a,两个大于根号a的数相乘一定大于a。
我们还知道一个合数的最小因数一定是素数,所以我们只需要遍历之间的每一个素数,用这个素数去除a,判断是否能整除,如果能,就证明这个数不是素数,如果都不能整除,就证明这个数是素数。
快在哪?#
- 缩小搜索边界,从变成了
- 内循环不用遍历每个正数,而只需要遍历素数列表,遍历的次数又少了
实现代码#
bool is_prime(int inputNum){
for (int i = 0; i < prime_nums.size() && prime_nums[i] <= sqrt(inputNum); i++){
if (inputNum%prime_nums[i]==0)
return 0;
}
return 1;
}
void get_prime_nums(){
prime_nums.push_back(2);
for (int i = 3; i <= N; i++) {
if (is_prime(i))
prime_nums.push_back(i);
}
}
快了多少#
生成1~100以内的素数,在内循环里添加一个计数器查看内循环执行了多少次。
Traditional : 1133 times
New Algorithm : 181 times
未改进的算法执行了1133次内循环,心算法只执行了181次。
时空互换#
其实对于这个问题,采用时空互换的办法会更好。也就是空间换时间。
因为我们计算机中的数据类型大小是有限制的,比如int类型会有一个能表示的最大值。我们在编写代码时把这个范围内的所有素数都硬编码进程序,这样即可达到O(1)
的时间复杂度。
作者:Yudoge
出处:https://www.cnblogs.com/lilpig/p/13760859.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎按协议规定转载,方便的话,发个站内信给我嗷~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)