数学算法知识编程

news2024/11/16 1:15:39

(1)辗转相除法求最大公约数(gcd)

   辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较小数除较大数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。原理也很简单:设gcd(a,b)表示a与b的最大公约数(a>b),则满足gcd(a,b)=gcd(b,b%a)。以下就是算法步骤:

ab
7248
4824
240
  根据这张表我们可以知道当b=0的时候,左边的24就是a,b的最大公约数。在每一次迭代中(设a为较大数,b为较小数),a为上一轮的b,b=a%b,所以这个函数用递归实现就是
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}

  这是三元运算符(? : )D=a?b:c的意思是先判断条件a。如果a为true,就把b的值赋给D;如果如果a为false,就把c的值赋给D。运用到欧几里得法就是:先判断较小数b是否为0,如果是的话直接返回a;如果不是的话就把b作为较大数,a%b作为较小数传入下一个递归。实现的过程中记住int gcd(int a,int b)中a为较大数,b为较小数就可以了。

(2)拓展欧几里得算法

   我们先介绍一下贝祖定理:即如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b)。拓展欧几里得算法就是把x,y的值计算出来
   当到达递归边界的时候,b==0,a=gcd(a,b) 这时可以观察出来这个式子的一个解:a*1+b * 0=gcd(a,b),x=1,y=0,注意这时的a和b已经不是最开始的那个a和b了,所以我们如果想要求出解x和y,就要回到最开始的模样。因为递归的相邻两层的参数a,b都是满足辗转相除法状态转移方法的,所以我们可以按照公式一层一层计算上去。状态转移公式推导如下:在这里插入图片描述
   这个代码用递归可以实现,代码如下

#include <iostream>
#include <vector> 
#include <math.h>
using namespace std;
int x,y;
void solution(int a,int b)
{
	if(b==0)
	{
		x=1;
		y=0;//递归到了底部,很明显x=1,y=0是一个解 
	}
	else
	{
		solution(b,a%b);
		int temp=y;
		y=x-(a/b)*y;
		x=temp;//递归到了底部以后开始回溯,根据每一层的参是一层一层往上计算 
	}
}
int main()
{
	while(1==1)
	{
		int a,b ;
    	cin>>a>>b;
    	cout<<"要解决的方程是: " <<a<<"x+"<<b<<"y=gcd("<<a<<","<<b<<")\n";
    	solution(a,b);
    	cout<<"方程解为:  x="<<x<<"  y="<<y<<"\n";
	}
    
	return 0;
}

  这段代码主要有两个部分组成:
  ①递归先到底部以后先找出一组原始解:x=1,y=0,并终止递归,中止递归的条件就是b=0。对应代码部分是:

if(b==0)
	{
		x=1;
		y=0;//递归到了底部,很明显x=1,y=0是一个解 
	}

  ②因为方程解x,y的交换操作是在递归调用之后,所要采用的递归写法就是线性递归(非尾递归)的写法。就是调用拓展欧几里得函数以后再按照公式根据下一层递归传来的x,y和自身的参数a,b来执行x,y的转换操作
  线性递归:下一个函数结束以后此函数还有后续,所以必须保存本身的环境以供处理返回值
  代码如下:

        else
  {
		solution(b,a%b);
		int temp=y;
		y=x-(a/b)*y;
		x=temp;//根据每一层的参数是一层一层往上计算 
  }

  这个过程的运行结果如下图所示(以a=72,b=48为例子):
在这里插入图片描述

  运行结果如下:
在这里插入图片描述

(3)分解质因数

  质数:如果一个数的约数只有1和它本身那么这个数就是质数。且质数这个概念是专门针对大于2的自然数的。
  合数:自然数当中除了合数剩下的数就是质数。
  每一个自然数都满足一个唯一分解定理每个大于1的自然数,要么本身就是质数,要么可以写为2个或以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。公式如下:
在这里插入图片描述
  根据这个定理可以编程实现质因数的分解,以下为代码和代码的解释:(以24为例)
  遍历质因数:先写一个i是从2到24的循环,判断i是否可以被24整除。当判断出i可以整除24的时候,就彻底去除这个因子。例如24可以分解为3*2的三次方,所以24要除以2三次。依次类推就可以实现功能。最后要分解的合数就一定可以分解成唯一分解定理分解的形式
  附:要注意循环的次数为:

for(i=2;i<=n;i++)

  因为这个算法是每一次迭代解出一个质因子和对应的次数,所以2到n都有可能是,所以要写一个从2到n的循环(代码优化思路就是大于sqrt(n)的质因数有且只有一个,且次数一定为1)。下面是完整代码:

#include <iostream> 
#include <vector>
using namespace std;
int main ()
{
	int input,i,j;
	vector <int> prime_factor;
	vector <int> power;
	while(1==1)
{
	cout<<"请输入你要分解的数:"; 
	cin>>input;
	int n=input;
	for(i=2;i<=n;i++)
	{
		if(input%i==0)//判断是否可以被整除
		{
			prime_factor.push_back(i);
			int num=0;
			while(input%i==0)//计算出质因子的个数并且把质因子从里面剔除掉
			{
			    num++;
				input/=i;
			}
			power.push_back(num);
		}
	}
	cout<<"这个数可以分解为:"<<"\n" ;
	for(i=0;i<=power.size()-1;i++)
	{
		if(i==power.size()-1)
		{
			for(j=1;j<=power[i];j++)
			{
				if(j==power[i])  cout<<prime_factor[i]<<"\n\n";
				else cout<<prime_factor[i]<<"*";
			}
			
		}
		else
		{
			for(j=1;j<=power[i];j++)
			cout<<prime_factor[i]<<"*";
		}
	}
	prime_factor.clear();
	power.clear();
 }        
    return 0;
}
}

  代码的执行结果为:
在这里插入图片描述

(4)埃氏筛素数法(枚举n以内的素数)

  首先将2到n范围内的整数写下来,其中2是最小的素数。将表中所有的2的倍数划去,表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数。再将表中所有的3的倍数划去……以此类推。代码逻辑就是每一次找到一个素数的时候就把所有该素数的倍数删掉就可以了。核心思想就是:从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的
  埃氏筛素数法的目的就是把所有的1到n内所有满足某个性质的素数倍数除掉。这些素数可以看作一个素数集合X,其中X满足:x属于X,2*x<=n。代码如下:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main ()
{
	
	int i,j;
	while(1==1)
{
	cout<<"请输入您所查询的数的范围:"; 
	vector<bool> array(1000000,false);
	cin>>j;
	for(i=2;i<=j/i;i++)
	{
		if(array[i-1]==false)
		{
			int temp=i+i;
			while(temp<=j)
			{
				array[temp-1]=true;
				temp+=i;
			}
		}
	}
	cout<<j<<"以内的质数为:";
	for(i=0;i<=j-1;i++) 
	{
		if (array[i]==false)
		   cout<<i+1<<"  ";
	}
	cout<<"\n\n";
}
	return 0;
}

运行结果如下:
在这里插入图片描述

(5)线性筛素数法

  在用埃式筛法的同时,同一个数字也许会被筛选多次,比如6先被2筛选一次,再被3筛选一次,这样就浪费了很多不必要的时间。欧拉筛法就是在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。比如说20如果使用埃式筛法会被2和5同时筛掉
  这种算法实现的具体步骤就是:(以n=100为例)
  (1)写一个从2到100的循环,因为这个算法再执行的过程中要记录下质数,这样就可以把2到100的所有质数保存出来。
  (2)对于循环中的任意一个数i,执行以下两个步骤
   (①)判定i是否为质数,如果是质数的话把它保存下来。
   (②)枚举所有比i小的质数组成一个集合X,标记i * j为合数,j属于X。但是一旦出现i mod j==0,就break。(这是关键,可以实现每一个数都被最小质因子筛掉。一旦出现i mod j1=0,那么i * D ( D为大于j1的质数)的最小质因子就是j1。但是如果不加这个限制继续标记i * j2,那么i * j2的最小质因子是j1却被j2标记,就不满足算法的核心要求了。)
   以8为例,首先标记82=16,但是如果没有这个条件,下一个标记83=24,但是显然24的最小质因子是2,所以24不是被它的最小质因子筛选掉的。上述算法的具体代码实现如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
	while(1==1)
 {
    vector <int> prime;
	int N,i,j;
	cout<<"请输入您所要查询的数:" ;
	cin>>N;
	vector <bool> record;
	for(i=1;i<=N;i++) record.push_back(false);//记录哪个数是否被标记 
	for(i=2;i<=N;i++)
	{
		if(record[i-1]==false) prime.push_back(i);
		for(j=0;j<prime.size()&&i*prime[j]<=N;j++)
		{
			int A=i*prime[j];
			record[A-1]=true;
		}
	}
	cout<<N<<"以内的质数为:";
	for(i=0;i<prime.size();i++) cout<<prime[i]<<" ";
	cout<<"\n\n";
	prime.clear();
	record.clear();
 }
	return 0;
}

(6)欧拉函数(小于N且和N互质的正整数的个数)

  就是对于一个正整数N,小于N且和N互质的正整数(包括1)的个数记作φ(n) 。φ(N) 的表达式如下所示:
设 n = p 1 k 1 ∗ p 1 k 2 ∗ p 1 k 2 ∗ . . . . p n k n , p i 是质数, k i 是对应的指数 φ ( n ) = n ∗ ( 1 − 1 p 1 ) ∗ ( 1 − 1 p 2 ) ∗ . . . . . . ( 1 − 1 p n ) 设n=p1^{k1}*p1^{k2}*p1^{k2}*....pn^{kn},p_i是质数,k_i是对应的指数\\\\φ(n)=n*(1-\frac {1} {p1})*(1-\frac {1} {p2})*......(1-\frac {1} {pn}) n=p1k1p1k2p1k2....pnkn,pi是质数,ki是对应的指数φ(n)=n(1p11)(1p21)......(1pn1)
  具体的实现方法就是对一个数进行质因数的分解。如果查出一个质因子,先把这个质因子消除干净,然后进行下列公式的迭代:
r e s u l t = r e s u l t ∗ ( 1 − 1 p n ) r e s u l t 初值为 N result=result*(1-\frac {1} {pn}) \quad result初值为N result=result(1pn1)result初值为N
  代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
	while(1==1)
{
	
	int N,i;
	cout<<"请输入你想要查询的欧拉函数值:";
	cin>>N; 
	int result=N;
	int target=N;
	while(N>1)
	{
		
		for(i=2;i<target;i++)
		{
			if(N%i==0)
			{
				while(N%i==0)  N=N/i;
			    result=result*(i-1)/i;
			}
		}
	}
	cout<<result<<"\n\n";
}	
	return 0;
}

(7)快速幂算法

  所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。
  这个算法是基于以下式子来编程的算法:
( 1 )    a 2 n    m o d    c =    ( a 2 n − 1    m o d    c ) ∗ ( a 2 n − 1    m o d    c )    m o d    c ( 2 )    a 10 = a ( 1010 ) 2 = a 2 3 ∗ a 2 1 ( 3 ) ( ∏ i = 1 n − 1 X i    m o d    c )    ∗ ( X n    m o d    c ) = ( ∏ i = 1 n X i    m o d    c ) ( 2 ) , ( 3 ) 公式就是快速幂算法的实现思路。具体思路就是把原始 式子 a X 分解成( 2 )这样的形式且( 3 )公式是从第一个形如 a 2 n 的因子开始进行迭代,最终可以计算出结果。 (1)\;a^{2^{n}}\;mod \;c=\;(a^{2^{n-1}}\;mod\;c)*(a^{2^{n-1}}\;mod\;c)\;mod\;c\\(2)\;a^{10}=a^{(1010)_2}=a^{2^{3}}*a^{2^{1}}\\(3)(\prod_{i=1}^{n-1}X_i\;mod\;c)\;*(X_n\;mod\;c)=(\prod_{i=1}^{n}X_i\;mod\;c)\\(2),(3)公式就是快速幂算法的实现思路。具体思路就是把原始\\式子a^{X}分解成(2)这样的形式且(3)公式是从第一个形如a^{2^{n}}\\的因子开始进行迭代,最终可以计算出结果。 (1)a2nmodc=(a2n1modc)(a2n1modc)modc(2)a10=a(1010)2=a23a21(3)(i=1n1Ximodc)(Xnmodc)=(i=1nXimodc)(2),(3)公式就是快速幂算法的实现思路。具体思路就是把原始式子aX分解成(2)这样的形式且(3)公式是从第一个形如a2n的因子开始进行迭代,最终可以计算出结果。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
	while(1==1)
  { 
    int A,B,C;
    cout<<"请依次输入3个数:"; 
	cin>>A>>B>>C;
	cout<<"您要计算"<<A<<"的"<<B<<"次方除以"<<C<<"的余数:\n" ;
	int result=1;
	int record=A%C;
	while(B) 
	{
		if(B&1==1) result=(result*x)%C;
		B>>=1;
		record=record*record%C;//迭代更新record,可见公式1
	}
	cout<<result<<"\n\n";
 }
	return 0;
}

  代码的解释:方法就是从B(2进制)从最低位到最高位进行遍历来找到所有是1的位数,从而来把A的B次方化成公式(2)的形式。并且设置了record变量是为了记录每一个 A2n%C 的值来辅助计算。一直到B为0位置(因为此时已经遍历了B的所有位数

(8)容斥原理

  容斥原理是一种重要的组合数学方法,这种方法可以求解任意几个集合的并集,或者求复合事件的概率。我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分数学公式表达如下:具体代码实现自己想办法,不过大概可以通过2进制来记录集合是否被使用过
   集合 X = [ X 1 , X 2 , X 3 . . . . . . X n ] , 则 X 1 , X 2 , X 3 . . . . . . X n 的并集 S 为: S = ∑ 奇数 ( X i ∩ X j ∩ . . . ) − ∑ 偶数 ( X k ∩ X b ∩ . . . ) \;集合X=[X_1,X_2,X_3......X_n],则X_1,X_2,X_3......X_n的并集S为:\\S=\sum_{奇数}(X_i\cap X_j \cap...)-\sum_{偶数}(X_k\cap X_b \cap...) 集合X=[X1,X2,X3......Xn],X1,X2,X3......Xn的并集S为:S=奇数XiXj...偶数XkXb...

(9)高斯消元法

  高斯消元法是求解线性方阵组的一种算法,它也可用来求矩阵的秩,以及求可逆方阵的逆矩阵。它通过逐步消除未知数来将原始线性系统转化为另一个更简单的等价的系统。它的实质是通过初等行变化,将线性方程组的增广矩阵转化为行阶梯矩阵,原理是矩阵进行初等行变换的时候解是不变的。下面是算法的过程:
  (1)已知方程组
x + y + z = 3 2 x + y − z = 2 3 x − y − z = 1 x+y+z=3\\2x+y-z=2\\ 3x-y-z=1\\ x+y+z=32x+yz=23xyz=1
  (2)根据方程式构造增广矩阵
∣ 1 1 1 3 2 1 − 1 2 3 − 1 − 1 1 ∣ \begin{vmatrix} 1 & 1 & 1 &3\\ 2 & 1 & -1 &2\\ 3 & -1 & -1 &1\\ \end{vmatrix} 123111111321
  (3)把增广矩阵的系数矩阵构建成上三角矩阵,具体方法就是:枚举系数矩阵每一列,对于第i列,先将第i行和第i行以下所有行中第i个数绝对值最大的行换到最顶端。(此时这个数为第一个非零元),而后把这个数化为1。通过第三类初等行变换(如下图公式),用当前行将下面所有的列消成0
c j = c j + d ∗ c i ( c i 为第 i 行, c j 为第 j 行, j > i ) c_j=c_j+d*c_i(c_i为第i行,c_j为第j行,j>i) cj=cj+dcici为第i行,cj为第j行,j>i)
  最终可以化为以下形式:
∣ 1   − 1 3 − 1 3 1 3 0 1 − 1 5 4 5 0 0 8 3 8 3 ∣ \begin{vmatrix} 1 & \ - \frac{1}{3} & - \frac{1}{3} & \frac{1}{3}\\ 0 & 1 & - \frac{1}{5} &\frac{4}{5}\\ 0 & 0& \frac{8}{3}&\frac{8}{3}\\ \end{vmatrix} 100 3110315138315438
  枚举完所有列,化简到这一步以后,存在三种情况:
  ①系数矩阵刚好可以化为一个完美的上三角矩阵,也就是不存在零行(一行全部都是0),说明只有一个解,增广矩阵往上推就可以推出所有解。
  ②若存在零行且对应系数的增广系数为0,则代表方差组存在无数个解
  ③若存在零行且对应系数的增广系数不为0,则代表方程组无解
  具体代码思路如下:
  1 根据方程式构造增广矩阵。
  2 写一个循环枚举系数矩阵的所有列,并执行对应行变换把枚举系数矩阵化为上三角,并且同时要设置一个record记录目前非零行的个数。
  3 使用record和n的关系判断最终结果,可以的话可以求出最后的解。代码如下:

(10)组合数

  (1)杨辉三角:
1 1   2   1 1   3   3   1 1   4   6   4   1 很明显第 n 行的数为: C n 0 , C n 1 , C n 2 . . . , C n n − 1 , C n n 且存在递推关系 C n i = C n − 1 i + C n − 1 i − 1 例如第三行的第二个数是 3 ,恰好等于第二行的第一个数 1 加上 第二行的第二个数 2 1\\ 1\:2\:1\\ 1\:3\:3\:1\\ 1\:4\:6\:4\:1\\ 很明显第n行的数为:C_n^0,C_n^1,C_n^2...,C_n^{n-1},C_n^n\\且存在递推关系C_n^i=C_{n-1}^i+C_{n-1}^{i-1}\\例如第三行的第二个数是3,恰好等于第二行的第一个数1加上\\第二行的第二个数2 1121133114641很明显第n行的数为:Cn0,Cn1,Cn2...,Cnn1,Cnn且存在递推关系Cni=Cn1i+Cn1i1例如第三行的第二个数是3,恰好等于第二行的第一个数1加上第二行的第二个数2
  (2)卡特兰数问题(此问题解法太经典,看图可知)
  给定 n 个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列有多少个。
在这里插入图片描述

(11) 质数的判定(朴素法)

  质数的定义就是:公因数只有1和它本身的数,因此要判定一个数N是否为质数,只需判定在区间[2,i]之间不存在N的约数就行(i为N开平方根之后的数)

bool check (int n)
{
  int i;
  bool flag=true;
  for(i=2;i*i<=n;i++)
  {
      if(n%i==0)
	  flag=false;
  }
  return flag;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1420960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

I.MX6ULL_Linux_驱动篇(53)linux USB驱动

I.MX6ULL USB 接口简介 I.MX6ULL 内部集成了两个独立的 USB 控制器&#xff0c;这两个 USB 控制器都支持 OTG 功能。I.MX6ULL 内部 USB 控制器特性如下&#xff1a; ①、有两个 USB2.0 控制器内核分别为 Core0 和 Core1&#xff0c;这两个 Core 分别连接到 OTG1 和OTG2。 ②、…

基于STM32的CAN通信协议选择与实现

基于STM32的控制器区域网络&#xff08;CAN&#xff09;通信协议是一种常见的实时数据通信方案&#xff0c;适用于需要高速、可靠通信的应用场景&#xff0c;比如汽车网络、工业控制系统等。在这里&#xff0c;我们将详细介绍基于STM32的CAN通信协议的选择与实现。 ✅作者简介&…

使用Win32API实现贪吃蛇小游戏

目录 C语言贪吃蛇项目 基本功能 需要的基础内容 Win32API 介绍 控制台程序部分指令 设置控制台窗口的长宽 设置控制台的名字 控制台在屏幕上的坐标位置结构体COORD 检索指定标准设备的句柄&#xff08;标准输入、标准输出或标准错误&#xff09; 光标信息结构体类型CONSOLE_CUR…

excel给数据库初始化/旧数据处理(自动sql拼装)

思路&#xff1a; 首先导出数据到excel编写单条数据操作的sql利用excel CONCATENATE 函数自动生成&#xff0c;每一行数据的操作sql 小技巧:对于需要套娃的字段值&#xff0c;可以加一个临时列同样使用CONCATENATE函数进行sql拼装 案例&#xff1a; 1.临时列:CONCATENATE(C2, …

HBase(docker版)简单部署和HBase shell操作实践

文章目录 说明HBase部署访问HBase Shell常见命令数据定义语言(DDL) 数据操作语言(DML)通用操作访问HBase WebUI 说明 本文适合HBase初学者快速搭建HBase环境&#xff0c;练习常见shell使用本文参考资料 《大数据技术原理和应用》&#xff08;林子雨 编著 第三版&#xff09;zh…

一文彻底搞懂redis数据结构及应用

文章目录 1. Redis介绍2.五种基本类型2.1 String字符串2.2 List列表2.3 Set集合2.4 Zset有序集合2.5 Hash散列 3. 三种基本类型3.1 Bitmap &#xff08;位存储&#xff09;3.2 HyperLogLogs&#xff08;基数统计&#xff09;3.3 geospatial (地理位置) 4. Stream详解4.1 Stream…

NTRU-Based GSW-Like FHE:Faster Blind Rotation

参考文献&#xff1a; [XZD23] Xiang, B., Zhang, J., Deng, Y., Dai, Y., Feng, D. (2023). Fast Blind Rotation for Bootstrapping FHEs. In: Handschuh, H., Lysyanskaya, A. (eds) Advances in Cryptology – CRYPTO 2023. CRYPTO 2023. Lecture Notes in Computer Scien…

C++_list

目录 一、模拟实现list 1、list的基本结构 2、迭代器封装 2.1 正向迭代器 2.2 反向迭代器 3、指定位置插入 4、指定位置删除 5、结语 前言&#xff1a; list是STL(标准模板库)中的八大容器之一&#xff0c;而STL属于C标准库的一部分&#xff0c;因此在C中可以直接使用…

实现扫码登录

扫码登录是如何实现的&#xff1f; 二维码信息里主要包括唯一的二维码ID,过期的时间&#xff0c;还有扫描状态&#xff1a;未扫描、已扫描、已失效。 扫码登录流程 用户打开网站登录页面的时候&#xff0c;浏览器会向二维码服务器发送一个获取登录二维码的请求。二维码服务器收…

雨云VPS搭建幻兽帕鲁服务器,PalWorld开服联机教程(Windows),0基础保姆级教程

雨云VPS用Windows系统搭建幻兽帕鲁私服&#xff0c;PalWorld开服联机教程&#xff0c;零基础保姆级教程&#xff0c;本教程使用一键脚本来搭建幻兽帕鲁服务端&#xff0c;并讲了如何配置游戏参数&#xff0c;如何更新服务端等。 最近这游戏挺火&#xff0c;很多人想跟朋友联机…

顶象点选验证码

要放假了好颓废。。。。 没啥事儿干&#xff0c;就把之前剩余的顶象点选系列的验证码类型看了下。 之前分享了一篇关于这个顶象的滑块的 DX算法还原_dx算法还原_逆向学习之旅-CSDN博客&#xff0c;感兴趣可以去看看。 咱们以文字点选为例&#xff1a; def get_image_arry(s…

Spring Boot如何统计一个Bean中方法的调用次数

目录 实现思路 前置条件 实现步骤 首先我们先自定义一个注解 接下来定义一个切面 需要统计方法上使用该注解 测试 实现思路 通过AOP即可实现&#xff0c;通过AOP对Bean进行代理&#xff0c;在每次执行方法前或者后进行几次计数统计。这个主要就是考虑好如何避免并发情况…

AI绘画:PhotoMaker Win11本地安装记录!

昨天介绍一个叫PhotoMaker的AI绘画开源项目。挺不错的&#xff01; 通过这个项目可以快速制作特定人脸的AI绘画作品&#xff0c;相比传统的技术效果会好很多&#xff0c;效率也高很多。 今天趁热打铁&#xff0c;本地电脑装装看&#xff0c;并且记录&#xff0c;分享一下&#…

城建档案数字化管理系统

城市建设档案数字化管理系统是指将城市建设相关档案纸质化资料转换为数字化形式&#xff0c;并通过信息技术手段进行存储、检索、管理和利用的系统。该系统旨在解决传统纸质档案管理存在的问题&#xff0c;提高档案管理的效率和准确性。 专久智能城市建设档案数字化管理系统主要…

自学C语言-7

第7章 循环控制 生活中总会有许多简单而重复的工作&#xff0c;为完成这些重复性工作&#xff0c;需要花费很多时间。使用循环语句来处理程序开发中简单、重复性的工作是最好不过的了。 本章致力于使读者了解while、do…while和for3种循环结构的特点&#xff0c;以及转移语句的…

Python第三方扩展库Matplotlib

Python第三方扩展库Matplotlib Matplotlib 是第三方库&#xff0c;不是Python安装程序自带的库&#xff0c;需要额外安装&#xff0c;它是Python的一个综合性的绘图库&#xff0c;提供了大量的绘图函数用于创建静态、动态、交互式的图形和数据可视化&#xff0c;可以帮助用户创…

Python实现时间序列分析AR定阶自回归模型(ar_select_order算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 时间序列分析中&#xff0c;AR定阶自回归模型&#xff08;AR order selection&#xff09;是指确定自回…

Springboot使用数据库连接池druid

springboot框架中可以使用druid进行数据库连接池&#xff0c;下面介绍druid在springboot中使用和参数配置介绍。 数据库连接池&#xff08;Druid&#xff09;是一种用于管理数据库连接的机制&#xff0c;其工作原理和常见使用方法如下&#xff1a; 原理&#xff1a;数据库连接…

Android 12 系统开机动画

一、查找Android系统提供的开机动画 在Android系统源码目录下输入 find ./ -name "bootanimation.zip" 如图所示 所输出的路劲即为bootanimation.zip所在路径&#xff0c;每个系统都不一样&#xff0c;建议用命令查找 二、复制到对应目录下 android12\out\target\…

vue使用mpegts.js教程

vue使用mpegts.js教程 最简单好用的H265网页播放器-mpegts.js简介特征受限性 使用步骤安装引入HTML 中添加视频标签video知识扩展 在容器里创建播放器 最简单好用的H265网页播放器-mpegts.js H265是新一代视频编码规范&#xff0c;与H264相比压缩比更高&#xff0c;同样的码率下…