面试官问小灰:如何用程序判断质数?
Posted 程序员小灰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官问小灰:如何用程序判断质数?相关的知识,希望对你有一定的参考价值。
质数(Prime number),又称素数,指在大于 的自然数中,除了 和该数自身外,无法被其他自然数整除的数(也可定义为只有 与该数本身两个正因数的数)。
如何快速判断某个数是否为质数?如何再给定区间内筛出所有的质数?
以上两个问题是大厂面试官常常喜欢考察的。本文采用多种思路,对以上两个问题进行简析。
本文所有的函数参数均默认为自然数。
文章所涉及的代码使用C++语言,使用的缺省源如下:
# include <cstdio>
# include <ciso646>
namespace Main {
namespace Source {
typedef short unsigned int hu;
typedef unsigned int uint;
typedef long long unsigned int llu;
}
using namespace Source;
static inline const void main() {}
}
signed int main() { Main::main(); return 0; }
问题1:素数判断
判断一个非负整数 是否为质数。
解决方案 1.1
根据定义,可以写出如下代码:
static inline const bool isprime(const uint a) {
if (a == 0 or a == 1) return false;
for (register uint i(2); i < a; ++i) if (not(a % i)) return false;
return true;
}
时间复杂度 ,空间复杂度 , 内约可以解决 的问题。
解决方案 1.2
考虑优化。
我们观察一下一个合数 会被哪个数筛掉。可列出下表(记为表 1):
筛掉 的数 | |
---|---|
4 | 2 |
6 | 2 |
8 | 2 |
9 | 3 |
10 | 2 |
12 | 2 |
14 | 2 |
15 | 3 |
16 | 2 |
18 | 2 |
20 | 2 |
21 | 3 |
22 | 2 |
24 | 2 |
25 | 5 |
26 | 2 |
(左侧为 ,右侧为筛掉 的数。)
核心代码:
static inline const uint mpf(const uint c) { for (register uint i(2); i < c; ++i) if (not(c % i)) return i; return 0; }
发现筛掉 的数都较小,我们想到,如果在一个比较小的范围内没有 的约数,那是否可以判断 是质数呢?
于是,我们考虑找到一个合数 的最小非 因数的上限。
设 为一个合数,令 为 的最小非 因数,令 ,显然 。
由于 为合数,故 ,故 ,而 为 的最小非 因数,故 。
故 , 。
所以,若 为合数,则 必定有一个不大于 的因数;若 中没有 的因数,则 为质数( 除外)。
所以枚举到 即可。
static inline const bool isprime(const llu a) {
if (a == 0 or a == 1) return false;
for (register uint i(2); 1ull * i * i <= a; ++i) if (not(a % i)) return false;
return true;
}
时间复杂度 ,空间复杂度 , 内约可以解决
女朋友问小灰:什么是数据仓库?什么是数据湖?什么是智能湖仓?