常用小算法和高效API(持续更新中)

刷题中常见和高效API小算法(持续更新)

一.求最大公约数

1.辗转相除法(欧几里德算法)

非递归实现

public static int solve(int m, int n) {
        int result = 0;
        while (n != 0) {
            result = m % n;
            m = n;
            n = result;
        }
        return m;
 
 
    }

递归实现

static int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}

2.更相减损术

public static int gcd(int m, int n) {
        while (m != n) {
            if (m > n)
                m -= n;
            else
                n -= m;
        }
        return m;
 
 
    }

二.求最小公倍数

private static int lcm(int m, int n) {
        int M = m;
        int N = n;
        while(true){
            if((m = m % n) == 0){
                return M*N/n;
            }
            if((n = n % m ) == 0){
                return M*N/m;
            }
        }
    }

//或者利用gcd()求lcm
static int lcm(int m,int n){
	return m*n/gcd(m,n);
}

递归求全排列

//递归求1-9的全排列

public static void main(String args[]){
		int []arr={1,2,3,4,5,6,7,8,9};
		f(arr,0);
}
private static void f(int[] arr, int k) {//arr为需要求全排列的序列数组,k为递归的层数也是判断退出的条件
		if(k==9){
			//check(arr);此处可以为得到全排列后进行的操作函数,如打印
			return;
		}
		for(int i=k;i<arr.length;i++){
			//将第i位和第k位交换
			int t=arr[i];
			arr[i]=arr[k];
			arr[k]=t;
			//下一层
			f(arr,k+1);
			//回溯(换回来)
			t=arr[i];
			arr[i]=arr[k];
			arr[k]=t;
		}
	}

StreamTokenizer(输入,在相同足够大的输入情况下,相比普通Scanner对象输入,速度近快了3倍)

针对于对时间严格的题的输入,JAVA解题一般用Scanner类来进行输入,但对时间要求严格的题,可能会超时,这个时候就需要StreamTokenizer,搭配BufferedReader,以及PrintWriter实在是居家旅行杀人灭口必备良药,那么怎样的题需要用到这两个“乖乖”呢,如果不是今天我刷了这道题,我也不知道还有这么两个东西。
没错就是这种看起来很简单的题
就是这种看起来很简单的题,实则暗藏杀机,我都觉得是测评姬的问题(手动狗头),c++代码两个循环能过,为什么java两个循环不能过????
C++代码Java代码

StreamTokenizer可以获取输入流并将其分析为Token(标记),StreamTokenizer的nextToken方法读取下一个标记 ,具体查看API,总之这个类的作用就是套上缓冲流,提高输入的效率,那么怎么提高输出的效率呢,就是下一个"乖乖"了

PrintWriter(输出)

PrintWriter可用来作为文件的输出,套上System.out也可做控制台输出,具体用法和System.out大致一样,但是就是比System.out快,实测有效,当时我在提交下面代码的时候,使用了StreamTokenizer,故意不用PrintWriter,而用System.out,运行超时,换成了PrintWriter,答案正确,艹(是一种植物),常用方法
(1)print(String str):向文件写入一个字符串。

(2)print(char[] ch):向文件写入一个字符数组。

(3)print(char c):向文件写入一个字符。

(4)print(int i):向文件写入一个int型值。

(5)print(long l):向文件写入一个long型值。

(6)print(float f):向文件写入一个float型值。

(7)print(double d):向文件写入一个double型值。

(8)print(boolean b):向文件写入一个boolean型值。

具体查看API.

Java能AC的代码

import java.io.*;
import java.util.Scanner;

public class xm_2{
    public static void main(String[] args) throws IOException {
        //Scanner sc=new Scanner(System.in);
        StreamTokenizer st =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
        //int n=sc.nextInt();
        st.nextToken();//开始解析,准备读入
        int n=(int)st.nval;//读入一个数字标记
        String s[]=new String[n];
        for(int i=0;i<n;i++){
            st.nextToken();//每次读入前都需要这个语句
            s[i]=st.sval;//读入文字标记
        }
        for(int i=0;i<n;i++){
            for(int j=n-1;j>=0;j--){
                //System.out.print(s[j].charAt(i));
                out.print(s[j].charAt(i));
            }
            out.println();
        }
        out.flush();
    }
}

我要为Java报不平,如果有大佬知道为什么Java正常使用两个循环会超时,而C++不会超时,欢迎交流

任意进制转换

当数字为十进制的时候认为是 int (或者long,BigInteger…)是个数字类型。
当数字为其他进制的时候则被认为 是String 类型

由任意进制为十进制

调用JavaAPI中的XXX.parseXXX方法,可将相应数据类型上的数据转换为对应的十进制数,如:

//将16进制的数转换为10进制的数
public static void Main(String []args){
	String s = "A";
	int num = Integer.parseInt(s,16);
	System.out.println(num);
}

同理也可转换其他进制的数,及其他类型的数据,如long,double等。

由十进制转换为任意进制的数

调用API中的toString方法,第一个参数是要转换的数字,第二个参数是要转换成为的进制。

public static void Main(String []args){
	int num = 8;
	String s = Integer.toString(num,2);
	System.out.println(s);
}

或者调用包装类中的toxxxString方法,如

10进制转化其他进制 对应的方法,参数:n(原10进制数据),r(进制), 返回值
10进制转2进制 Integer.toBinaryString(n); 一个二进制字符串.
10进制转8进制 Integer.toOctalString(n); 一个八进制字符串
10进制转16进制 Integer.toHexString(n); 一个16进制字符串
10进制转 r 进制 Integer.toString(100, 16); 一个r进制字符串

附:
Integer.bitCount(int n); //返回n在二进制下中1的个数,返回int

求素数打表

Eratosthenes筛法(据说能跑1e6的数据)

埃拉托斯特尼筛法,简称埃氏筛,埃筛。这是一种简单且历史悠久的筛法,用来找出一定范围内所有的素数。所使用的原理是从2开始,将每个素数的各个倍数,标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。此为这个筛法和试除法不同的关键之处,后者是以素数来测试每个待测数能否被整除。
给出要筛数值的范围n,找出根号n以内的素数p1,p2,…,pk。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去……虽然它能处理1e6的数据,已经非常优秀了,但是还是有劣势,那就是已经筛选过的数可能会被再筛选一遍
在这里插入图片描述

static boolean bis[] =  new boolean[(int)1e6];//在这里我规定为true表示素数.
static void aiShai(int n){//计算2-n之间有多少素数
	Arrays.fill(bis,true);//初始化为全是true,一开始都是素数,然后再筛去不是素数的数,将其置为false
	for(int i = 2;i*i<=n;i++){
		if(bis[i]){//如果这个素是素数
			for(int j=i*i;i<=n;j+=i){
				//j 从 i * i 而不是从 i + i开始,因为 i*(2~ i-1)在 2~i-1时都已经被筛去,所以从i * i开始,这是一个小优化。
				bis[j]=false;//将素数的倍数全部设为false,即不是素数
			}
		}
	}
}

欧拉筛法(线性筛)(据说能跑1e7的数据)

在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

static boolean vis[] = new boolean[(int)1e6];
static int prime[] = new int[(int)1e6];
static int cnt = 0;//个数
static void eulerSieve(int n){
		Arrays.fill(vis,true);
        for (int i = 2;i*i<=n;i++){
            if (vis[i]){ //不是目前找到的素数的倍数
                prime[cnt++]=i; //找到素数
                for (int j=0;j<cnt&&i*prime[j]<=n;j++){
                    vis[i*prime[j]]=false;//找到的素数的倍数不访问
                    if(i%prime[j]==0){//关键
                        break;
                    }
                }
            }
        }
    }

对于visit[i*prime[j]] = 1 的解释: 这里不是用i的倍数来消去合数,而是把 prime里面纪录的素数,升序来当做要消去合数的最小素因子。

对于 i%prime[j] == 0 就break的解释 :当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。
举个例子 :i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。因为欧拉筛法的原理便是通过最小素因子来消除。

具体可以看看这篇文章

唯一分解定理(算数基本定理)

在这里插入图片描述

约数个数定理

在这里插入图片描述

扩展欧几里得算法

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要用Python编写一个AI算法,首先需要搭建一个基础的AI框架,包括定义问题,收集数据,构建模型,训练模型,评估模型,优化模型,部署模型和监控模型。接着,可以使用Python编写AI算法,比如机器学习、深度学习等算法。 ### 回答2: 使用Python编写AI算法需要遵循以下几个步骤: 1. 定义问题:明确AI算法需要解决的问题,并收集相关数据。 2. 数据准备:将收集到的数据进行清洗和预处理,如去除噪声、填补缺失值等。 3. 特征提取:从原始数据提取有用的特征。可以使用统计学方法、自然语言处理方法、图像处理方法等。 4. 算法选择:根据问题的特性选择合适的算法,如决策树、神经网络、SVM等。 5. 模型训练:用准备好的数据集来训练AI模型,通过优化模型参数使其能够在给定数据上取得最好的性能。 6. 模型评估:使用其他数据集对训练好的模型进行评估,评估模型的性能、精确度和召回率等指标。 7. 模型调优:根据评估结果对模型进行调优,如调整模型参数、增加训练集样本等。 8. 模型应用:使用训练好的模型进行实际应用,对新数据进行预测、分类、聚类等任务。 9. 性能监控:持续监控模型的性能,对模型进行更新和改进,适应新的场景和数据。 10. 部署:将AI算法部署到相应的平台或系统,使其能够实时运行和服务。 Python作为一种强大的编程语言,可通过使用各种库和框架来简化和加速AI算法开发过程,如TensorFlow、Keras、Scikit-learn等。这些库提供了许多现成的AI算法实现,以及数据处理、模型评估和调优等功能。通过阅读相关文档和实践项目,我们可以更好地理解和掌握如何使用Python编写AI算法。 ### 回答3: 要用Python编写一个AI算法,首先需要了解Python的基本语法和AI的基本原理。接下来,可以按照以下步骤来实现: 1. 导入必要的Python库:首先,需要导入一些常用的Python库,如NumPy、Pandas和Scikit-learn等。这些库提供了很多AI算法的实现和支持。 2. 数据准备:根据实际情况,收集和准备所需的数据集。例如,可以使用Pandas库来加载和处理数据。 3. 特征选择和预处理:根据实际需求,可以使用特征选择算法来选择最相关的特征,或者使用数据预处理技术来处理缺失值、离群值或标准化数据。 4. 算法选择和实现:根据问题类型,选择合适的AI算法,如决策树、支持向量机、神经网络等。然后,使用Scikit-learn等库提供的API来实现所选算法。 5. 模型训练和评估:使用训练数据对AI模型进行训练,并使用测试数据对其进行评估。可以使用交叉验证等技术来评估模型的性能。 6. 参数调优:通过调整算法的参数来优化模型的性能。可以使用网格搜索等技术来自动搜索最佳参数。 7. 模型保存和部署:在满足预期性能要求的情况下,将训练好的模型保存下来,并将其部署到实际应用。 8. 持续优化:根据实际的应用和反馈,对模型进行持续优化和改进,以提高准确性和效率。 总结起来,编写一个AI算法的过程包括数据准备、特征选择和预处理、算法选择和实现、模型训练和评估、参数调优、模型保存和部署、以及持续优化等步骤。Python提供了丰富的库和API,使得编写AI算法变得相对简单和高效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值