前言
2025年3月 开始找 Internship 了。笔试的时候遇到了一些问题,是 before 自己 can do 的但是忘记了更好的方法,于是笔试完后将 significant 内容记录在 Blog 中,供自己日后考古。
1. 质数(Prime Number)
对于质数没有什么好说的,definition is 因数 only 自己 和 1 的数。那么如何快速判断一个数是否是质数则是一个很好的问题,下面是几条 Theorem:
- 一个正整数 N \mathbf N N,其因数不会超过 N \sqrt \mathbf N N
- 超过 3 3 3 的质数,都在 6 6 6 的倍数附近,即满足 6 k ± 1 6k \pm 1 6k±1
有了这两个 公理 之后我们可以得到一个复杂度为 O ( n ) O(\sqrt n) O(n) ,rather than O ( n ) O(n) O(n) 的算法。
/* tell whether a number is prime
* parameter 0 : a positive integer
* return value : if is prime return true else return false
*/
bool IsPrime(int nNum) {
//eliminate some condition
if (nNum <= 1)
return false;
if (nNum == 2 || nNum == 3)
return true;
// all the even number except 2 are not prime
if (nNum % 2 == 0)
return false;
// check if it is 6k+1 or 6k-1
if ((nNum + 1) % 6 != 0 && (nNum - 1) % 6 != 0)
return false;
int nSquare = sqrt(nNum);
// retrive all the number from 3 to sqrt(n)
for (int i = 3; i <= nSquare; i++) {
if (nNum % i == 0)
return false;
}
// attention the number less than 9 will return true directly, because loop start from 3
return true;
}
2. 最大公约数(Greatest Common Division)
最大公约数的求法采用 辗转相除法,其算法如下:
/* calculate the greatest common division of a and b
* parameter 0 : a positive integer
* parameter 1 : another positive integer
* return value : the greatest common division
*/
int gcd(int a, int b) {
// make the a > b
if(b > a) {
// exchange the value a and b
a ^= b, b ^= a, a ^= b;
}
int nRemainder = a % b;
while(nRemainder) {
a = b;
b = nRemainder;
nRemainder = a % b;
}
return b;
}
3.所有因数
在 1. 质数 中介绍的理论可以在这里用上,即只需要遍历到 n \sqrt \mathbf n n 就能够得到所有因数。
/* get all the factors of an integer
* parameter 0 : an integer
* return value : a vector save all factors of nNum
*/
vector<int> Factors(int nNum) {
vector<int> vecRet;
int nSqrt = sqrt(nNum);
for (int i = 1; i <= nSqrt; i++) {
if (nNum % i == 0) {
vecRet.push_back(i);
if(i != nNum / i)
vecRet.push_back(nNum / i);
}
}
sort(vecRet.begin(), vecRet.end());
return vecRet;
}