数学
1. 判断一个数n是否是质数
质数:大于1的自然数,并且只能被1和它自身整除的数
(1)从2开始除该数直到n-1
bool isPrime_v1(long naturalNum) { if(naturalNum <= 1) { return false; } for(int i=2;i<naturalNum-1;i++) { if((naturalNum % i) == 0) { return false; } } return true; }
(2)循环次数优化
如果n是一个合数,则存在两个非1的数a、b,其中 a≤sqrt(n) b≥sqrt(n)
bool isPrime_v2(long naturalNum) { if(naturalNum <= 1) { return false; } for(int i = 2;i*i<=naturalNum;i++) { if((naturalNum % i) == 0) { return false; } } return true; }
(3)
2. 质因数分解
输入一个long数,返回一个字符串
string factorization(long naturalNum) { ostringstream ostr; long n = 2; while(naturalNum>=n) { while(naturalNum % n != 0) { n++;//不能整除 } ostr<<n<<" "; naturalNum /= n; } return ostr.str(); }
3. 求x和y的最小公倍数与最大 公约数
x*y 等于 最小公倍数*最大公约数
求最大公约数:
(1)质因数分解法
x、y分解成其各自质因数相乘,公共的质因数的乘积就是最大公约数
void multisetRes(int x,multiset<int> &xset) { int n = 2; while(x>=n) { while(x%n != 0) { ++n; } xset.insert(n); x /= n; } } int gcd_v3(int x,int y) { multiset<int> xset,yset; multisetRes(x,xset); multisetRes(y,yset); int res = 1; for(auto i=xset.begin();i!=xset.end();i++) { auto j = yset.find(*i); if(j != yset.end()) { res *= (*i); yset.erase(j); } } return res; }
(2)辗转相除法
用较大的数除以较小的数
①如果余数为0,则较小的数就是最大公约数
②余数不为0,用上一步较小的数(除数)除以此余数(这个余数肯定比那个除数小)
重复。
循环:
int gcd(int x,int y) { x = abs(x); y = abs(y); int z = 0; if(x<y) { //其实这个交换没必要,如果前一个较小的话,经过一次while循环x会变成较大数 z = x; x = y; y = z; } while(x%y != 0) { z = x % y; x = y; y = z; } return y; }
递归:
int gcd2(int x,int y) { x = abs(x); y = abs(y); if(x%y == 0) { return y; } else { return gcd2(y,x%y); } }
(3)更相减损术
①两个正整数x、y,如果都是偶数,则用2约,直到不能约
②较大数减较小数;差与较小数比较,继续用较大的减较小的,直到 减数和差 相等
之前约掉的若干个2与等数的乘积就是最大公约数(也可以不用2去约,直接重复执行②)
int gcd_v2(int x,int y) { x = abs(x); y = abs(y); while(x != y) { if(x<y) { y = y - x; } else { x = x - y; } } return x; //return y; }
递归:
int gcd2_v2(int x,int y) { x = abs(x); y = abs(y); if(x == y) { return x; } else { if(x<y) { return gcd2_v2(x,y-x); } else { return gcd2_v2(y,x-y); } } }
(4)
4. 四舍五入
int rounding(double n) { // int r = n; // r = n-r<0.5?r:r+1; //上面的这种方法不行:如输入3.4999999999999999999999,则由于精确度的关系这个数小数部分在比较时可能大于0.5 int r = n*10; r = r%10<5?(int)n:(int)n+1; return r; }
5.