常见算法和Lambda

常见算法和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 + 1min = 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;}@Overridepublic 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;}@Overridepublic 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 5for (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.mzph.cn/web/41005.shtml

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

相关文章

SpringBoot新手快速入门系列教程二:MySql5.7.44的免安装版本下载和配置,以及简单的Mysql生存指令指南。

我们要如何选择MySql 目前主流的Mysql有5.0、8.0、9.0 主要区别 MySQL 5.0 发布年份&#xff1a;2005年特性&#xff1a; 基础事务支持存储过程、触发器、视图基础存储引擎&#xff08;如MyISAM、InnoDB&#xff09;外键支持基本的全文搜索性能和扩展性&#xff1a; 相对较…

2024年江苏省研究生数学建模竞赛B题火箭烟幕弹运用策略优化论文和代码分析

经过不懈的努力&#xff0c; 2024年江苏省研究生数学建模竞赛B题火箭烟幕弹运用策略优化论文和代码已完成&#xff0c;代码为B题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模…

[学习笔记]SQL学习笔记(连载中。。。)

学习视频&#xff1a;【数据库】SQL 3小时快速入门 #数据库教程 #SQL教程 #MySQL教程 #database#Python连接数据库 目录 1.SQL的基础知识1.1.表(table)和键(key)1.2.外键、联合主键 2.MySQL安装&#xff08;略&#xff0c;请自行参考视频&#xff09;3.基本的MySQL语法3.1.规…

进程控制-fork函数

一个进程&#xff0c;包括代码、数据和分配给进程的资源。 fork &#xff08;&#xff09;函数通过系统调用创建一个与原来进程几乎完全相同的进程&#xff0c;也就是两个进程可以做完全相同的事&#xff0c;但如果初始参数或者传入的变量不同&#xff0c;两个进程也可以做不同…

DatawhaleAI夏令营2024 Task2

#AI夏令营 #Datawhale #夏令营 赛题解析一、Baseline详解1.1 环境配置1.2 数据处理任务理解2.3 prompt设计2.4 数据抽取 二、完整代码总结 赛题解析 赛事背景 在数字化时代&#xff0c;企业积累了大量对话数据&#xff0c;这些数据不仅是交流记录&#xff0c;还隐藏着宝贵的信…

【鸿蒙学习笔记】@Link装饰器:父子双向同步

官方文档&#xff1a;Link装饰器&#xff1a;父子双向同步 目录标题 [Q&A] Link装饰器作用 [Q&A] Link装饰器特点样例&#xff1a;简单类型样例&#xff1a;数组类型样例&#xff1a;Map类型样例&#xff1a;Set类型样例&#xff1a;联合类型 [Q&A] Link装饰器作用…

信号与系统-实验6-离散时间系统的 Z 域分析

一、实验目的 1、掌握 z 变换及其性质&#xff1b;了解常用序列的 z 变换、逆 z 变换&#xff1b; 2、掌握利用 MATLAB 的符号运算实现 z 变换&#xff1b; 3、掌握利用 MATLAB 绘制离散系统零、极点图的方法&#xff1b; 4、掌握利用 MATLAB 分析离散系统零、极点的方法&a…

字符串中的注意事项

在比较早的C/C版本中&#xff0c;经常可以看到推荐使用gets函数来进行整行字符串的输入&#xff0c;就像下面这样的简单写法即可输入一整行&#xff1a; C gets(str);但是当输入的字符串长度超过数组长度上限MAX_LEN时&#xff0c;gets函数会把超出的部分也一并读进来&#x…

MySQL基础篇(二)字符集以及校验规则

在MySQL基础篇&#xff08;一&#xff09;中&#xff0c;我们知道了如何创建数据库&#xff0c;这篇文章带大家了解创建的一些细节。 红色框&#xff1a;可省略&#xff0c;作用如果存在相同的数据库名称&#xff0c;就不会再创建&#xff0c;反之&#xff0c;创建。 蓝色框&…

uniapp 封装请求

新建request文件夹 下新建index.js 和index.js 或者创建units文件放入index.js 和api文件夹放入index.js(api.js)//看公司规范 1. index.js // 全局请求封装 // const base_url http://localhost:8080/devapi var base_url process.env.NODE_ENV development ? http://…

可用于多个微信管理的神器

以下仅是多微信聚合聊天管理界面&#xff1a; 可以在一个页面上同时收发多个微信的消息&#xff0c;可以添加好友&#xff0c;通过好友请求。 可以修改昵称&#xff0c;不受字数限制。 可以将常用图片&#xff0c;文件等放入素材库&#xff0c;方便聊天时查找和发送。 可以设置…

速盾:cdn 缓存图片

现如今&#xff0c;互联网已经成为我们日常生活中不可或缺的一部分。在我们使用互联网时&#xff0c;经常会遇到图片加载缓慢、文章打开慢等问题。为了解决这些问题&#xff0c;CDN&#xff08;内容分发网络&#xff09;应运而生。CDN 是一种通过将数据缓存在世界各地的服务器上…

集群环境下,调用半数以上节点进行数据同步的实现

核心实现是使用CountDownLatch来实现的&#xff0c;先取集群节点总数一半以上数量的CountDownLatch 再发送请求调用其他节点&#xff0c;在这个过程中对于正常响应的节点进行latch.countDown(); 最后再统计数量是否为0再决定是否抛异常 // 请求参数final String content jso…

Java:封装

文章目录 一、概念二、实现三、测试四、总结 一、概念 在面向对象编程中&#xff0c; 封装从字面上来理解就是包装的意思&#xff0c;特点就是信息隐藏&#xff0c;防止该类的代码和数据被外部类的代码随机访问。 封装的优点&#xff1a; 良好的封装能够减少耦合。 统一接口…

搜索旋转数组

题目链接 搜索旋转数组 题目描述 注意点 数组已被旋转过很多次数组元素原先是按升序排列的若有多个相同元素&#xff0c;返回索引值最小的一个 解答思路 首先需要知道的是&#xff0c;本题数组中的旋转多次只是将头部的某些元素移动到尾部&#xff0c;所以不论怎么旋转&am…

uni-app怎样使用组件

在uni-app中使用组件&#xff0c;主要遵循以下几个步骤&#xff1a; 创建组件文件&#xff1a;在UniApp项目中创建一个新的组件&#xff0c;通常将组件文件保存在components文件夹下。如果components文件夹不存在&#xff0c;需要先创建它。然后在components文件夹下创建一个新…

Pycharm python解释器 unsupported python 3.1 解决

Pycharm 环境 unsupported python 3.1解决 1. 问题重现2. 原因分析3. 解决方法 1. 问题重现 之前使用Pycharm 2024.1.1的时候&#xff0c;环境配置的Python 3.11.9&#xff0c;现在改成使用Pycharm 2020.2.2&#xff0c;结果Python解释器显示“unsupported python 3.1”&#…

Java ORM框架FastMybatis踩坑

Java ORM框架FastmyBatis踩坑 问题&#xff1a;使用了FastmyBatis的saveOrUpdate方法&#xff0c;明明设置了主键的值且表中存在&#xff0c;但是依然执行insert操作。导致Duplicate PK。 原因&#xff1a;使用了其他第三方包的注解指定表的主键&#xff0c;没有按照FastmyBat…

低音炮内存卡格式化后无法播放音乐文件

试了多次 不支持ntfs不支持exfat 仅支持fat32 FAT32与exFAT的区别主要体现在来源、单个文件限制、适用情况以及兼容性方面。12 来源&#xff1a; FAT32是Windows平台的传统文件格式&#xff0c;首次在Windows 95第二版中引入&#xff0c;旨在取代FAT16&#xff0c;具有良好的…

自动驾驶中的逆透视变换(Inverse Perspective Mapping,IPM)详解

前言 IPM(Inverse Perspective Mapping,逆透视变换)图的历史可以追溯到计算机视觉和图像处理领域的发展。逆透视变换是一种用于消除图像中透视效应的技术,使得原本由于透视产生的形变得以纠正,进而更准确地描述和理解图像中的场景。比如在行车中的车道线检测,泊车中的常见…