素数判断最简写法是遍历2到sqrt(n),特判n<2返回false、n==2返回true;常见错误包括将1误判为素数、忽略2的特判,以及用i*i<=n可能溢出。

判断一个数是不是素数,最简写法长什么样
直接用 sqrt(n) 降复杂度,别暴力试到 n-1。C++ 标准库没现成函数,得自己写,但不用递归、不用筛法——练习场景下,单次判断就该轻量。
常见错误是:把 1 当素数,或漏掉 2 的特判;还有人用 i * i 却忽略 <code>i * i 溢出(尤其 int 大数时)。
n 直接返回 <code>false-
n == 2返回true,n % 2 == 0返回false - 只试奇数因子,从
3到sqrt(n)(用(long long)i * i 避溢出)
为什么用 sqrt(n) 而不是 n/2
因为如果 n 有大于 sqrt(n) 的因子,那它一定对应一个小于 sqrt(n) 的配对因子。试到 sqrt(n) 就够了,省掉近一半时间。
用 n/2 不错,但没必要;更糟的是有人写 i —— 那是 O(n),<code>n=1e6 就卡住,而 sqrt(n) 是 O(√n),1e6 只试 1000 次。
立即学习“C++免费学习笔记(深入)”;
-
sqrt(n)在<cmath></cmath>里,但浮点误差可能让边界错位,推荐用整数比较:(long long)i * i - 对
int类型,n最大到2e9左右,i最大到 ~46340,i*i不会超int,但保险起见还是转long long
输入是负数或 0 怎么办
素数定义只针对大于 1 的正整数,所以 n 一律不是素数。别纠结“负数有没有素数”,数学上不定义,代码里直接拦住。
容易踩的坑是:没检查输入范围,用户输个 -5 或 0,程序进循环,i 从 2 开始试,结果逻辑错乱甚至死循环(比如用 i 且 <code>n 为负)。
- 开头加一句:
if (n - 如果函数参数是
unsigned int,那0和1还是要单独处理,不能依赖类型自动过滤
想批量判断多个数?别现场重算 sqrt
单个数判断没问题,但如果要判断一串数(比如 1000 个),每个都调 sqrt 或反复算 i*i 其实不差多少;真要优化,重点不在这里,而在避免重复调用——比如你反复判断同一个数,就该缓存结果。
不过练习阶段,先写对再谈优化。真正影响性能的是误用 vector<bool></bool> 做筛法却只用一次,或者为了“看起来高级”硬套埃氏筛,反而更慢。
- 多次调用?传参前先
if (n 快速过滤 - 真要筛区间 [2, N],才考虑埃氏筛;N 小于 1e5 时,单次判断比建筛更快
- 别用
double sqrt_n = sqrt(n);再用i —— 浮点精度可能导致 <code>i多跑一轮或少跑一轮
事情说清了就结束。最常被忽略的其实是 1 和 2 的边界处理,以及 i*i 溢出——这两处一错,小样例过,大数就崩。











