算法中的数学思想
2017-03-28 23:17
225 查看
最近接触了一些数学思想,感觉特别好用,在时间复杂度还有代码的简洁性方面都有很大的帮助。
不多说,给出我的一些代码。
1.最大公约数
gcd(a,b)为最大公约数,一般用辗转相除法。相应的最小公倍数lcd(a,b)=a*b/gcd(a,b),用欧几里得算法加上递归,会使代码变的简洁。
2.素数筛选
一般来说,判断一个数是否为素数较为简单,但是判断一个连续区间内的素数一个个判断时间上就会增加很多,而进行适当处理就可以有效的解决这一点。
3.二分快速幂
对于a的b次幂,可以用每次对半的方式,会使时间复杂度低很多。直接给出代码,比较好理解。
4.矩阵快速幂
矩阵快速幂用来实现递推是很方便快速的,如在斐波那契数列的应用上,用二分矩阵快速幂的方法是很快的。
5.全排列
全排列可以算是一个算法问题,一般c语言用递归去实现它,但是在c++中可以用更方便的方法实现。
不多说,给出我的一些代码。
1.最大公约数
gcd(a,b)为最大公约数,一般用辗转相除法。相应的最小公倍数lcd(a,b)=a*b/gcd(a,b),用欧几里得算法加上递归,会使代码变的简洁。
int gcd(int x,int y) { if(y==0) return x; else return gcd(y,x%y); }
2.素数筛选
一般来说,判断一个数是否为素数较为简单,但是判断一个连续区间内的素数一个个判断时间上就会增加很多,而进行适当处理就可以有效的解决这一点。
//判断一个数是否为素数 //要include<math.h> bool prime(int x) { int i; for(i=2;i<=sqrt(x);i++) { if(x%i==0) return false; } return true; } //判断一段区间2-n内的素数 for(int i=2;i<=n;i++) prime[i]=1; //先让全部都为素数,在进行筛选 for(int i=2;i<=n;i++) { for(j=i*2;j<=n;j+=i) { prime[i]=0; } } //这样的时间复杂度为NlogN //更简洁的版本,只对素数的倍数进行筛选。因为合数一定可以被他的素数因子筛选掉,初始也可以从i*i开始。 for(int i=2;i<=n;i++) prime[i]=1; for(int i=2;i*i<n;i++) { for(j=i*i;j<n;j+=i) { prime[j]=0; } }
3.二分快速幂
对于a的b次幂,可以用每次对半的方式,会使时间复杂度低很多。直接给出代码,比较好理解。
int powab(int x,int y) //求x的y次幂 { int temp=y,ans=1; for(;y;y/=2) { if(y&1) //判断是否为奇数 { ans*=temp%mod; //因为比较大,都给取了余数,y最后一定会为1的,然后返回ans。 } temp=temp*temp%mod; } } //再给出个递归版本的 int powab(int x,int y) { if(y==0) return 1%mod; int temp=powab(x,y/2); temp=temp*temp%mod; if(b&1) { temp=temp*a%mod; } return temp; }
4.矩阵快速幂
矩阵快速幂用来实现递推是很方便快速的,如在斐波那契数列的应用上,用二分矩阵快速幂的方法是很快的。
int n; //让所有矩阵都为n*n typedef struct matrix jz; struct matrix { int a[100][100]; }; jz matrix_mul(jz A,jz B,int mod) //矩阵相乘 { jz C; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { C.a[i][j]=0; for(int k=0;k<n;k++) { C.a[i][j]+=A.a[i][k]*B.a[k][j]%mod; } } } return C; } jz unit() //返回一个单位矩阵 { jz A; for(int i=0;i<n) { for(int j=0;j<n;j++) { if(i==j) A.a[i][j]=1; else A.a[i][j]=0; } } return A; } jz matrix_pow(jz A,int n,int mod) //矩阵的幂,用到前面的二分快速幂 { jz temp=a,res=unit(); for(;n;n/=2) { if(n&1) { res=matrix_mul(res,temp,mod); } temp=matrix_mul(temp,temp,mod); } return res; }
5.全排列
全排列可以算是一个算法问题,一般c语言用递归去实现它,但是在c++中可以用更方便的方法实现。
//全排列的一般递归算法 #include<stdio.h> int a[4]={1,2,3,4}; void swap(int * x,int * y) { int temp; temp=*x; *x=*y; *y=temp; } void permutatian(int x[],int n,int len) { int i,j; if(n==len) { for(i=0;i<n;i++) printf("%d",x[i]); printf("\n"); return ; } for(i=n;i<len;i++) { swap(&x ,&x[i]); permutatian(x,n+1,len); swap(&x ,&x[i]); } } int main() { permutatian(a,0,4); return 0; }
//c++简洁版 #include<stdio.h> #include<algorithm> using namespace std; int main() { int a[4]={1,2,3,4}; do { for(int i=0;i<4;i++) { printf("%d",a[i]); } printf("\n"); } while(std::next_permutation(a,a+4));//或者这一句为while(next_permutation(a,a+4)); return 0; }
相关文章推荐
- C/C++面试之算法系列--如何利用数学思想解1/2/5组合问题
- 编程语言,算法,思想,数学建模,数学思想
- 数学思想和算法
- C/C++面试之算法系列--如何利用数学思想解1/2/5组合问题
- Number Sequence 无算法,靠思想 数学题
- 转型AI产品经理,原来不需要学那么深的算法和数学模型
- 逻辑回归算法背后的数学
- 全排列的算法思想和实现
- java工具-IntelliJ和数学思想对编程
- 算法并非数学
- 游戏开发中的数学和物理算法(6):圆和球的碰撞检测
- 深入解析堆排序的算法思想及Java代码的实现演示
- 1.2算法的作用二分思想(猜价格游戏)清屏操作
- 普林斯顿公开课 算法1-3:数学模型
- 算法之枚举思想
- 100层楼,两个会坏的杯子,测从哪层开始坏【算法思想】
- 算法之分治思想
- 51Nod-算法马拉松23 B 谷歌的恐龙 [概率期望]【数学】
- 关于使用二分思想算法的时间复杂度的计算
- 第三节 数学算法解决C语言问题