常见算法和Lambda

news2024/11/15 23:35:50

常见算法和Lambda

文章目录

  • 常见算法和Lambda
    • 常见算法
      • 查找算法
        • 基本查找(顺序查找)
        • 二分查找/折半查找
        • 插值查找
        • 斐波那契查找
        • 分块查找
        • 扩展的分块查找(无规律的数据)
    • 常见排序算法
      • 冒泡排序
      • 选择排序
      • 插入排序
      • 快速排序
        • 递归
        • 快速排序
    • Arrays
    • Lambda表达式
      • 函数式编程

常见算法

查找算法

基本查找(顺序查找)

核心:从0索引开始挨个往后查找

  • 需求定义:一个方法利用基本查找,查找某个元素是否存在
  • 数据如下:{131,127,147,81,103,23,7,79}
package com.example.demo;

public class Text{
    public static void main(String[] args) {
       int [] arr = {131,127,147,81,103,23,7,79};
       int number = 81;
        System.out.println(basicSearch(arr,number));

    }

    private static boolean basicSearch(int[] arr, int number) {
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == number){
                return true;
            }
        }
        return false;
    }
}
  • 需求:定义一个方法利用基本查找,查询某个元素在数组中的索引
  • 要求:不需要考虑数组中元素是否重复
package com.example.demo;

public class Text{
    public static void main(String[] args) {
       int [] arr = {131,127,147,81,103,23,7,79};
       int number = 81;
       System.out.println(basicSearch(arr,number));
    }

    private static int basicSearch(int[] arr, int number) {
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }
}
  • 需求:定义一个方法利用基本查找,查询某个元素在数组中的索引
  • 要求:需要考虑数组中元素有重复的可能性
package com.example.demo;

import java.util.ArrayList;

public class Text{
    public static void main(String[] args) {
       int [] arr = {131,127,147,81,103,23,7,79,81};
       int number = 81;
       System.out.println(basicSearch(arr,number));
    }

    private static ArrayList<Integer> basicSearch(int[] arr, int number) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == number){
                list.add(i);
            }
        }
        return list;
    }
}
二分查找/折半查找

前提条件:数组中的数据必须是有序的

核心思想:每次排除一半的查找范围

  • min和max表示当前要查找的范围
  • mid是在min和max中间的
  • 如果要查找的元素在mid的左边,缩小范围时,min不变,max等于mid减一
  • 如果要查找的元素在mid的右边,缩小范围,max不变,min等于mid加一
package com.example.demo;

public class Text{
    public static void main(String[] args) {
//        需求:定义一个方法利用二分查找,查询某个元素在数组中的索引
//        数据如下:{7,23,79,81,103,127,131,147}
       int [] arr = {7,23,79,81,103,127,131,147};
       System.out.println(binarySearch(arr,131));
    }

    private static int binarySearch(int[] arr, int number) {
//       1.定义两个变量记录要查找的范围
        int min = 0;
        int max = arr.length-1;

//        2.利用循环不断地去找要查找的数据
        while (true){
            if(min > max){
                return -1;
            }

//            3.找到min和max的中间位置
            int mid = (min + max)/2;
//            4.拿着mid指向的元素跟要查找的元素进行比较
            if (arr[mid] > number){
                //4.1 number在mid的左边
                // min不变,max = min -1;
                max = mid - 1;
            }else if(arr[mid] < number){
                //4.2 number子啊mid的右边
                //max不变,min = mid + 1
                min = mid + 1;
            }else{
                //4.3 number跟mid指向的元素一样
                //找到了
                return mid;
            }
        }

    }
}

1720164211486

插值查找

数组中的值,分布比较均匀。

1720164511201

斐波那契查找

1720164773883

1720164896413

分块查找
  • 前一块中的最大数据,小于后一块中所有的数据(块内无序,块间有序)
  • 块数数量一般等于数字的个数开根号。比如:16个数字一般分为4块左右

核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找。

package com.example.demo;

public class Text{
    public static void main(String[] args) {
        int[] arr = {16,5,9,12,21,18,32,23,37,26,45,34,50,48,61,52,73,66};

        //创建三个的块对象
        Block b1 = new Block(21,0,5);
        Block b2 = new Block(45,6,11);
        Block b3 = new Block(73,12,17);

//        定义数组用来管理三个块的对象(索引表)
        Block[] blockArr = {b1,b2,b3};

//        定义一个变量用来记录要查找的元素
        int number = 30;

//        调用方法,传递索引表,数组,要查找的元素
        int index = getIndex(blockArr,arr,number);
        
//        打印
        System.out.println(index);

    }

//    利用分块查找的原理,查询number的索引
//    1.确定number在索引表的位置
    private static int getIndex(Block[] blockArr, int[] arr, int number) {
        //1.确定number是在哪一块中的
        int indexBlock = findIndexBlock(blockArr,number);

        if(indexBlock == -1){
            //表示number不在数组当中
            return -1;
        }

//        2.获取这一块的起始索引和结束索引
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();

//        3.遍历
        for (int i = startIndex; i <= endIndex; i++) {
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }

//    定义一个方法,用来确定number在哪一块
    public static int findIndexBlock(Block[] blockArr,int number){
        //从0索引开始遍历blockArr,如果number小于max,那么就表示number是在这一块当中的。
        for (int i = 0; i < blockArr.length; i++) {
            if(number <= blockArr[i].getMax()){
                return i;
            }
        }
        return -1;
    }

}

class Block{
    private int max;
    private int startIndex;
    private int endIndex;

    public Block() {
    }

    public Block(int max, int startIndex, int endIndex) {
        this.max = max;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }

    @Override
    public String toString() {
        return "Block{" +
                "max=" + max +
                ", startIndex=" + startIndex +
                ", endIndex=" + endIndex +
                '}';
    }
}
扩展的分块查找(无规律的数据)

1720168388226

package com.example.demo;

public class Text{
    public static void main(String[] args) {
        int[] arr = {27,22,30,40,36,13,19,16,20,7,10,43,50,48};

        //创建三个的块对象
        Block b1 = new Block(22,40,0,4);
        Block b2 = new Block(13,20,5,8);
        Block b3 = new Block(7,10,9,10);
        Block b4 = new Block(43,50,11,13);

//        定义数组用来管理三个块的对象(索引表)
        Block[] blockArr = {b1,b2,b3,b4};

//        定义一个变量用来记录要查找的元素
        int number = 48;

//        调用方法,传递索引表,数组,要查找的元素
        int index = getIndex(blockArr,arr,number);

//        打印
        System.out.println(index);

    }

//    利用分块查找的原理,查询number的索引
//    1.确定number在索引表的位置
    private static int getIndex(Block[] blockArr, int[] arr, int number) {
        //1.确定number是在哪一块中的
        int indexBlock = findIndexBlock(blockArr,number);

        if(indexBlock == -1){
            //表示number不在数组当中
            return -1;
        }

//        2.获取这一块的起始索引和结束索引
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();

//        3.遍历
        for (int i = startIndex; i <= endIndex; i++) {
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }

//    定义一个方法,用来确定number在哪一块
    public static int findIndexBlock(Block[] blockArr,int number){
        //从0索引开始遍历blockArr,如果number小于max,大于min,那么就表示number是在这一块当中的。
        for (int i = 0;i < blockArr.length; i++) {
            if(number <= blockArr[i].getMax() && number >= blockArr[i].getMin()){
                return i;
            }
        }
        return -1;
    }

}

class Block{
    private int max;

    private int min;
    private int startIndex;
    private int endIndex;

    public Block() {
    }

    public Block(int min,int max, int startIndex, int endIndex) {
        this.min = min;
        this.max = max;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    public int getMin() {
        return min;
    }

    public void setMin(int min) {
        this.min = min;
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }

    @Override
    public String toString() {
        return "Block{" +
                "max=" + max +
                ", min=" + min +
                ", startIndex=" + startIndex +
                ", endIndex=" + endIndex +
                '}';
    }
}

常见排序算法

冒泡排序

  • 相邻的数据两两比较,小的放前面,大的放后面。
  • 第一轮循环结束,最大值已经找到,在数组的最右边。第二轮可以少循环一次,后面以此类推。
  • 如果数组中有n个数据,总共我们只要执行n-1轮的代码就可以。
package com.example.demo;

public class Text {
    public static void main(String[] args) {
//        1.定义数组
        int[] arr = {2,4,5,3,1};

//        2.利用冒泡排序将数组的数据变成1,2,3,4,5
//        外循环:表示我要执行多少轮,如果有n个数据,那么执行n-1轮
        for (int i = 0; i < arr.length-1; i++) {
//            内循环:每一轮中我如何比较数据并找到当前的最大值
            //-1:为了防止索引越界
            //-i:提高效率,每一轮执行的次数应该比上一轮少一次。
            for (int j = 0; j < arr.length-1 - i; j++) {
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i] + " ");
        }
    }
}

选择排序

  • 从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较,小的放前面,大的放后面,以此类推。
  • 第一轮结束后,最小的数据已经确定
package com.example.demo;

public class Text {
    public static void main(String[] args) {
//        1.定义数组
        int[] arr = {2, 4, 5, 3, 1};

//        2.利用选择排序让数组变成1 2 3 4 5
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] > arr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

插入排序

  • 将0索引的元素到N索引的元素看做是有序的,把N+1索引的元素到最后一个当成是无序的。
  • 遍历无序的数据,将遍历的元素插入有序序列中适当的位置,如遇到相同数据,插在后面。
  • N的范围:0~最大索引
package com.example.demo;

public class Text {
    public static void main(String[] args) {
//        1.定义数组
        int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

//        2.找到无序的那一组数组是从哪个索引开始的
        int startIndex= -1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > arr[i+1] ){
                startIndex = i + 1;
                break;
            }
        }

//        3.遍历从startIndex开始到最后一个元素,依次得到无序的那一组数据中的每一个元素
        for (int i = startIndex; i < arr.length; i++) {
//            记录当前要插入数据的索引
            int j = i;
            while (j > 0 && arr[j] < arr[j-1]){
//                交换位置
                int temp = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = temp;
                j--;
            }
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

快速排序

递归

方法中调用方法本身的现象

注意点:递归一定要有出口,否则就会出现内存溢出

作用:把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算

package com.example.demo;

public class Text {
    public static void main(String[] args) {
        //求1~100之间的和
        System.out.println(getSum(100));
    }
    public static int getSum(int number){
        if(number == 1){
            return 1;
        }

//        如果number不是1?
        return number + getSum(number-1);
    }
}
package com.example.demo;

public class Text {
    //求5的阶乘
    public static void main(String[] args) {
        System.out.println(getFactorial(5));
    }
    public static int getFactorial(int number){
        if(number == 1){
            return 1;
        }
//        如果number不是1?
        return number * getFactorial(number-1);
    }
}
快速排序

第一轮:把0索引的数字作为基准数,确定基准数在数组中正确的位置。

比基准数小的全部在左边,比基准数大的全部在右边。

package com.example.demo;

public class Text {
    public static void main(String[] args) {
        int[] arr = {6,1,2,7,9,3,4,5,10,8};
        quickSort(arr,0,arr.length-1);

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    public static void quickSort(int[] arr,int i,int j){
//        定义两个变量记录要查找的范围
        int start= i;
        int end = j;

        if(start > end){
            return;
        }

//        记录基准数
        int baseNumber = arr[i];
//        利用循环找到要交换的数字
        while (start != end) {
//            利用end,从后往前开始找,找比基准数小的数字
            while (true){
                if(end <= start || arr[end] < baseNumber){
                    break;
                }
                end--;
            }
//            利用start,从前往后找,找比基准数大的数字
            while (true){
                if(end <= start || arr[start] > baseNumber){
                    break;
                }
                start++;
            }
//            把end和start指向的元素进行交换
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
//    当start和end直系那个了同一个元素的时候,那么上面的循环就会结束
//    表示已经找到了基准数在数组中应存入的位置
//    基准数归位
        int temp = arr[i];
        arr[i] = arr[start];
        arr[start] = temp;

//        确定6左边的范围,重复刚刚所做的事情
        quickSort(arr,i,start-1);
//        确定6右边的范围,重复刚刚所做的事情
        quickSort(arr,start+1,j);
    }


}

1720173652777

Arrays

操作数组的工具类

1720174919002

1720175136896

1720175208004

1720175250562

1720175475272

1720175524323

1720175695912

1720175851349

Lambda表达式

函数式编程

是一种思想特点。函数式编程思想忽略面向对象的复杂语法,强调做什么,而不是谁去做。

1720176866498

1720176984576

1720177474422
1720177720800

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

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

相关文章

在Apache HTTP服务器上配置 TLS加密

安装mod_ssl软件包 [rootlocalhost conf.d]# dnf install mod_ssl -y此时查看监听端口多了一个443端口 自己构造证书 [rootlocalhost conf.d]# cd /etc/pki/tls/certs/ [rootlocalhost certs]# openssl genrsa > jiami.key [rootlocalhost certs]# openssl req -utf8 -n…

Pycharm远程连接GPU(内容:下载安装Pycharm、GPU租借、配置SSH、将代码同步到镜像、命令行操控远程镜像、配置远程GPU解释器)

目录 windows下载安装pycharmGPU租借网站AutoDlfeaturize好易智算 GPU租借GPU选择选择镜像充值 然后创建镜像创建成功 复制SSH登录信息 远程进入镜像 在Pycharm中进行ssh连接新建SFTP配置SSH复制ssh根据复制的信息填写ssh配置测试连接 将代码同步到远程镜像上设置mappings将本地…

React 省市查询组件完整代码

目录 一、地区文件 二、Antd配合使用 三、实现效果 一、地区文件 下载地址&#xff1a;全国省市区数据_JSON格式_SQL格式 export const chinaArea {0: {1: 北京,2: 天津,3: 河北省,4: 山西省,5: 内蒙古自治区,6: 辽宁省,7: 吉林省,8: 黑龙江省,9: 上海,10: 江苏省,11: 浙…

计算机出现找不到msvcp140.dll无法继续执行代码怎么办?推荐7个有效解决方法

在日常使用电脑过程中会经常遇到各式各样的问题&#xff0c;比如msvcp140.dll丢失或找不到msvcp140.dll文件是最常见的问题之一&#xff0c;那么遇到这个问题要怎么解决呢&#xff1f;msvcp140.dll到底是什么&#xff1f;为什么会出现msvcp140.dll丢失问题&#xff1f;今天给大…

原生事件监听及组件内置事件处理

监听事件 我们可以使用 v-on 指令 (简写为 ) 来监听 DOM 事件&#xff0c;并在事件触发时执行对应的 JavaScript。用法&#xff1a;v-on:click“handler” 或 click“handler”。 事件处理器 (handler) 的值可以是&#xff1a; 内联事件处理器&#xff1a;事件被触发时执行的…

《QT从基础到进阶·四十三》QPlugin插件多线程问题和只有插件dll没有头文件和lib文件时调用插件中的方法

1、插件和多线程问题&#xff1a; 创建插件对象不能放到多线程执行&#xff0c;不然报错&#xff1a;ASSERT failure in QWidget: "Widgets must be created in the GUlthread. //不能放在多线程执行 QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName))…

单选多选提交问卷,代码示例

&#xff45;&#xff4c;&#xff45;&#xff4d;&#xff45;&#xff4e;&#xff54;中 需要对接口返回的数据进行分析。多选问题使用checkbox&#xff0c;单选题使用radio。 多选时可以绑定&#xff4d;&#xff49;&#xff4e;&#xff0f;&#xff4d;&#xff41;&am…

Transformer前置知识:Seq2Seq模型

Seq2Seq model Seq2Seq&#xff08;Sequence to Sequence&#xff09;模型是一类用于将一个序列转换为另一个序列的深度学习模型&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;如机器翻译、文本摘要、对话生成等。Seq2Seq模型由编码器&#…

搭建互联网医院实战:从源码到在线问诊APP的全流程开发

今天&#xff0c;笔者将讲述在线问诊APP的全流程开发&#xff0c;帮助开发者理解和掌握搭建互联网医院的核心技术和步骤。 一、需求分析与设计 需求分析包括明确目标用户、功能需求、性能需求等。设计阶段则包括系统架构设计、数据库设计和前后端界面设计等。 1.目标用户&…

统计是一门艺术(非参数假设检验)

1.定义 当总体分布未知&#xff0c;那么就需要一种与分布具体数学形式无关的统计推断方法&#xff0c;称为非参数方法 只能利用样本中的一般信息包括位置和次序关系等 稳健性强 2.符号检验 考虑问题&#xff1a; 小样本情况&#xff1a; 以概率为1/2的二项分布是对称的 两…

ASP.NET Core----基础学习01----HelloWorld---创建Blank空项目

文章目录 1. 创建新项目--方式一&#xff1a; blank2. 程序各文件介绍&#xff08;Project name &#xff1a;ASP.Net_Blank&#xff09;&#xff08;1&#xff09;launchSettings.json 启动方式的配置文件&#xff08;2&#xff09;appsettings.json 基础配置file参数的读取&a…

昇思25天学习打卡营第08天 | 模型训练

昇思25天学习打卡营第08天 | 模型训练 文章目录 昇思25天学习打卡营第08天 | 模型训练超参数损失函数优化器优化过程 训练与评估总结打卡 模型训练一般遵循四个步骤&#xff1a; 构建数据集定义神经网络模型定义超参数、损失函数和优化器输入数据集进行训练和评估 构建数据集和…

Git 运用小知识

1.Git添加未完善代码的解决方法 1.1 Git只是提交未推送 把未完善的代码提交到本地仓库 只需点击撤销提交&#xff0c;提交的未完善代码会被撤回 代码显示未提交状态 1.2 Git提交并推送 把未完善的代码提交并推送到远程仓库 点击【未完善提交并推送】的结点选择还原提交&#x…

前端面试题20(防抖函数)

在前端开发中&#xff0c;防抖&#xff08;debounce&#xff09;函数是一种常见的优化技术&#xff0c;用于控制函数的执行频率&#xff0c;避免在短时间内重复调用同一函数。这在处理如用户输入、窗口尺寸变化或鼠标移动等高频事件时特别有用&#xff0c;可以显著提升应用程序…

最小权顶点覆盖问题-优先队列分支限界法-C++

问题描述: 给定一个赋权无向图 G(V,E)&#xff0c;每个顶点 v∈V 都有一个权值 w(v)。如果 U⊆V&#xff0c;U⊆V&#xff0c;且对任意(u,v)∈E 有 u∈U 或 v∈U&#xff0c;就称 U 为图 G 的一个顶点覆盖。G 的最小权顶点覆盖是指 G 中所含顶点权之和最小的顶点覆盖。对于给定…

AttackGen:一款基于LLM的网络安全事件响应测试工具

关于AttackGen AttackGen是一款功能强大的网络安全事件响应测试工具&#xff0c;该工具利用了大语言模型和MITRE ATT&CK框架的强大功能&#xff0c;并且能够根据研究人员选择的威胁行为组织以及自己组织的详细信息生成定制化的事件响应场景。 功能介绍 1、根据所选的威胁行…

springboot项目多模块工程==1搭建

1、新建父工程 采用springboot工程作为父工程搭建方便依赖选择&#xff0c;在这个基础上进行maven的pom父子模块结构调整。该工程选择mave进行依赖管理 2、springboot 版本及相关依赖选择 3、删除工程目录src,并修改pom 由于该父工程只作为依赖的统一管理&#xff0c;因此将…

Python实战训练(方程与拟合曲线)

1.方程 求e^x-派&#xff08;3.14&#xff09;的解 用二分法来求解&#xff0c;先简单算出解所在的区间&#xff0c;然后用迭代法求逼近解&#xff0c;一般不能得到精准的解&#xff0c;所以设置一个能满足自己进度的标准来判断解是否满足 这里打印出解x0是因为在递归过程中…

CentOS 7安装Elasticsearch7.7.0和Kibana

一. 准备安装包 elasticsearch和kibana&#xff1a;官网历史版本找到并下载&#xff08;https://www.elastic.co/cn/downloads/past-releases#elasticsearch&#xff09;ik分词器&#xff1a;GitHub下载&#xff08;https://github.com/infinilabs/analysis-ik/releases/tag/v…

3.js - 裁剪平面(clipIntersection:交集、并集)

看图 代码 // ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import …