ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角

news2024/11/23 19:49:02

本节课的内容,就让我们来学习一下ArrayList集合的应用,ArrayList的本质就是一个顺序表,那下面一起来学习吧

目录

一、杨辉三角

1.题目详情及链接

2.剖析题目  

3.思路及代码

二、洗牌算法

1.创造牌对象

2.创造一副牌

3.洗牌操作

4.发牌操作


一、杨辉三角

这不是普通的杨辉三角,这是力扣里面的杨辉三角

1.题目详情及链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 

有同学说,这里的题目也看不出跟ArrayList集合有鸡毛关系呀?我说,你别急,继续往下看

看到这里,你急了没有,题目给的类型是什么狗屎?这不就与ArrayList扯上关系了嘛,这到底是什么意思呢?接着往下看

2.剖析题目  

(1)题目的要求是根据参数,生成杨辉三角的前numRows行,并返回存放杨辉三角的空间

比如:numRows=3,就生成杨辉三角的前面3行;如果你用普通的二维数组存储,那就返回该二维数组的地址。

(2)剖析返回值

我们也应该可以猜到,List<List<Integer>>也是表示二维数组的意思

此时还不算完整的二维数组,List只是一个接口,需要实例化对象

(3)我们需要将这些数字放入该二维数组中

3.思路及代码

(1)思路解析

通过面向对象的思想来完成

第一步:分析杨辉三角的规律

题目要求生成杨辉三角的前numRows行,也就是可以一行一行生成

规律是显而易见的,除了第一行,其他每行的第一个元素和最后一个元素的值都是1;从第3行开始,中间的值与前一行的值紧密相连

第二步:创建二维数组并单独完成杨辉三角的第一行

不用担心测试用例一行都没有,1<=numRows<=30

List<List<Integer>> list = new ArrayList<>();
List<Integer> first = new ArrayList<>();
//先设置第一行的元素
first.add(1);
list.add(first);

核心思想:先单独建立一个一维的顺序表,存放好一行的元素,然后再将这个一维的顺序表当成一个元素放入二维的顺序表中,后面也是一样的思想

第三步:存放第二行及后面的元素

for (int i = 1; i < numRows; i++) {//每层循环代表一行
     List<Integer> ret = new ArrayList<>();//定义一个一维数组    
}

我们将在这个循环里面存放完成后续的行,如果只有一行,就不会进入这个循环内

第四步:分析如何将每一行存入

由前面分析知道,第二行开始,第一个和最后一个元素都是1,我们可以在前面和最后面存入1

    for (int i = 1; i < numRows; i++) {//每层循环代表一行
            List<Integer> ret = new ArrayList<>();//定义一个一维数组
            //1.添加第一个元素
            ret.add(1);
            //2.设置中间元素,从第二列开始
           
            //3.添加最后元素
            ret.add(1);
            list.add(ret);//将每一行放入二维数组中
    }

然后中间的元素如何添加?第二行是没有中间元素的,而且中间的元素都是与前一行的元素有着紧密的关系,所以我们也需要考虑好。首先,我们需要从第二个位置开始存放;然后,第几行就说明那一行有多少个元素,就与行号绑定了关系

        for (int i = 1; i < numRows; i++) {//每层循环代表一行
            List<Integer> ret = new ArrayList<>();//定义一个一维数组
            //1.添加第一个元素
            ret.add(1);
            //2.设置中间元素,从第二列开始
            for (int j = 1; j < i; j++) {
                //利用面向对象的思想,拿到元素
                int tmp = list.get(i-1).get(j)+list.get(i-1).get(j-1);
                ret.add(tmp);
            }
            //3.添加最后元素
            ret.add(1);
            list.add(ret);
        }

(2)完整代码

 public List<List<Integer>> generate(int numRows) {
         List<List<Integer>> list = new ArrayList<>();
        List<Integer> first = new ArrayList<>();
        //先设置第一行的元素
        first.add(1);
        list.add(first);
        //从第二行开始
        for (int i = 1; i < numRows; i++) {//每层循环代表一行
            List<Integer> ret = new ArrayList<>();//定义一个一维数组
            //1.添加第一个元素
            ret.add(1);
            //2.设置中间元素,从第二列开始
            for (int j = 1; j < i; j++) {
                int tmp = list.get(i-1).get(j)+list.get(i-1).get(j-1);
                ret.add(tmp);
            }
            //3.添加最后元素
            ret.add(1);
            list.add(ret);
        }

        return list;
}

(3)总结一下思路

第一:将杨辉三角分成两个部分存储(第一行和第一行后面的

第二:存储第一行后面的时候,又分成三部分存储(第一个元素、中间部分元素、最后一个元素)

第三:存储中间部分元素时,通过与前一行的元素的关系进行存储(利用面向对象的思想获得前一行的元素)

二、洗牌算法

其实,洗牌算法就是ArrayList的一种应用,或者运用,没有那么的高大尚,下面简单介绍洗牌算法的一些基本功能和流程

下面是程序运行起来的结果: 

什么是洗牌算法?

(1)使用类和对象的知识定义一个牌对象

(2)创造出一副排序好的牌,存储在ArrayList中(有牌)

(3)然后将这些牌的顺序打乱(洗牌)

(4)将洗乱的牌随机分发给三个人(发牌)

下面开始讲解洗牌算法

1.创造牌对象

 牌这个对象的属性有两个:第一是花色,第二就是号码;然后我们提供一下构造方法,在创建每一张牌的时候就赋值;最后,重写一下toString方法,用来打印牌。

public class Card {
    //用来定义一张牌
    public String suit;//牌的花色
    public int num;//号码

    public Card(String suit, int num) {
        this.suit = suit;
        this.num = num;
    }

    @Override
    public String toString() {
       return suit+num;
    }
}
2.创造一副牌

main函数,用来实例化对象,和调用对象中的方法(创造牌的方法)

public static void main(String[] args) {
        PlayCard game = new PlayCard();

        System.out.println("设置牌:");
        List<Card> cards = game.setCard();
        System.out.println(cards);

}

 创建一个类,用来表示玩牌的游戏,里面存放创建牌、洗牌和发牌的操作

public class PlayCard {
    
    public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组

    //1.设置牌操作
    public List<Card> setCard() {
        List<Card> cards = new ArrayList<>();//定义一个数组,用来存放所有牌
        for (int i = 0; i < 4; i++) {//每次循环代表一个花色
            for (int j = 1; j <=13 ; j++) {//13个号码
                String suit = suits[i];//获得一个花色

                Card card = new Card(suit,j);//定义一个牌对象并赋值

                cards.add(card);//将牌放入一个牌数组中
            }
        }
        return cards;//返回一副牌
    }
}

(1)这是一个带返回值的函数。

(2)第一层循环,代表花色;第二层循环代码号码;每循环一次:拿到一个花色和号码,然后将这两个赋值给牌对象,并将牌放入ArrayList集合中(cards)

(3)最后将这个集合返回(接收返回值就拿到了返回值)

3.洗牌操作

这里先把上一阶段创造牌的操作隐藏,独将洗牌操作

这里洗牌的思想是:(1)从后面遍历这副牌,每张牌都随机与前面某一张牌交换

(2)获得前面随机牌使用产生随机数种子

(3)交换则单独包装成一个方法

public class PlayCard {
    //在这里类里面操作牌:设置牌,洗牌和发牌
    public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组

    //1.设置牌操作
   //这里介绍洗牌操作,所以设置牌的操作就省略了

    //2.洗牌操作
    public void shuffle(List<Card> cards) {
        Random random = new Random();
        for (int i = 51; i > 0; i--) {
            int index  = random.nextInt(i);//随机获取一个牌下标与i下标的牌交换
            swap(cards,i,index);
        }
        //return cards;
    }
    private static void swap(List<Card> cards,int i,int j) {
        //交换两张牌
        Card tmp = cards.get(i);
        cards.set(i,cards.get(j));
        cards.set(j,tmp);
    }

}

4.发牌操作

同样的,我们把前面创造牌和洗牌的操作隐藏起来,单独介绍发牌操作

我们发牌的思路是:(1)有三个人轮流接牌,每次接一张,一共接五轮(2)每个人随机接牌,每拿到一张牌,就从这副牌中删除(3)每个人拿到五张牌,每个人看作一个一维数组;要保存三个人的牌,就需要一个二维数组。

public class PlayCard {
    //在这里类里面操作牌:设置牌,洗牌和发牌
    public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组

    //1.设置牌操作
  
    //2.洗牌操作
  
    //3.发牌操作
    public List<List<Card>> getCard(List<Card> cards) {
        //定义三个对象,存取牌
        List<Card> hand1 =new ArrayList<>();
        List<Card> hand2 =new ArrayList<>();
        List<Card> hand3 =new ArrayList<>();
        //定义一个二维数组,存取三个对象
        List<List<Card>> hand = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);

        //每个人只能拿五张牌
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
              Card card = cards.remove(0);//每次拿到第一张牌,并从数组中删掉
              //放入每个人手中
              hand.get(j).add(card);
            }
        }
        return hand;
    }
}

(1)用三个一维的集合代表三个一维数组 (2)再定义一个集合,存放三个一维集合 (3)第一层循环,每循环一次就是一张牌;第二层循环就是每个人轮流拿牌 (4) hand.get(j)代表第几个人,add(card)代表把这张牌给某个人

完整代码:

public static void main(String[] args) {
        PlayCard game = new PlayCard();

        System.out.println("设置牌:");
        List<Card> cards = game.setCard();
        System.out.println(cards);

        System.out.println("洗牌后:");
        game.shuffle(cards);
        System.out.println(cards);

        System.out.println("发牌:");
        List<List<Card>> hand = game.getCard(cards);
        for (int i = 0; i < 3 ; i++) {
            System.out.println("第"+(i+1)+"个人的牌为:"+hand.get(i));
        }

        System.out.println("剩余的牌为:");
        System.out.println(cards);
    }
public class Card {
    //用来定义一张牌
    public String suit;//牌的花色
    public int num;//号码

    public Card(String suit, int num) {
        this.suit = suit;
        this.num = num;
    }

    @Override
    public String toString() {
       return suit+num;
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;

public class PlayCard {
    //在这里类里面操作牌:设置牌,洗牌和发牌
    public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组

    //1.设置牌操作
    public List<Card> setCard() {
        List<Card> cards = new ArrayList<>();//定义一个数组,用来存放所有牌
        for (int i = 0; i < 4; i++) {//四种花色
            for (int j = 1; j <=13 ; j++) {//13个号码
                String suit = suits[i];//获得一个花色

                Card card = new Card(suit,j);//定义一个牌对象并赋值

                cards.add(card);//将牌放入一个牌数组中
            }
        }
        return cards;//返回一副牌
    }

    //2.洗牌操作
    public void shuffle(List<Card> cards) {
        Random random = new Random();
        for (int i = 51; i > 0; i--) {
            int index  = random.nextInt(i);//随机获取一个牌下标与i下标的牌交换
            swap(cards,i,index);
        }
        //return cards;
    }
    private static void swap(List<Card> cards,int i,int j) {
        //交换两张牌
        Card tmp = cards.get(i);
        cards.set(i,cards.get(j));
        cards.set(j,tmp);
    }

    //3.发牌操作
    public List<List<Card>> getCard(List<Card> cards) {
        //定义三个对象,存取牌
        List<Card> hand1 =new ArrayList<>();
        List<Card> hand2 =new ArrayList<>();
        List<Card> hand3 =new ArrayList<>();
        //定义一个二维数组,存取三个对象
        List<List<Card>> hand = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);

        //每个人只能拿五张牌
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
              Card card = cards.remove(0);//每次拿到第一张牌,并从数组中删掉
              //放入每个人手中
              hand.get(j).add(card);
            }
        }
        return hand;
    }
}

本节的内容就是介绍ArrayList集合的用法,可以当成一维数组,也可以当成二维数组。看到这里本机就结束了,快趁着这个感觉去刷题吧!

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

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

相关文章

大数据笔记(待续)

mysql 缓存技术 数据库和缓存双写数据一致性问题常见的解决方案 常见方案通常情况下&#xff0c;我们使用缓存的主要目的是为了提升查询的性能。大多数情况下&#xff0c;我们是这样使用缓存的&#xff1a; 用户请求过来之后&#xff0c;先查缓存有没有数据&#xff0c;如果有…

学习笔记 -- CAN系统基础

一、CAN物理层 一个双节点CAN网络示意图如下&#xff0c;两颗120Ω终端电阻并联呈现总线电阻60Ω。 A、B两个节点的CAN收发器&#xff08;Transceiver&#xff09;&#xff0c;只负责电平转换。当总线静默时&#xff0c;收发器内部的2.5V电源经15KΩ电阻把CAN-H和CAN-L都拉到2.…

前端(一):HTML+CSS

参考课程&#xff1a;23最新版web前端开发_哔哩哔哩_bilibili 文档&#xff1a;GitHub - codeNiuMa/HTML-md-file: 学习HTML课程时的资料 目录 1 HTML 1.1 骨架 DOCTYPE html标签 head标签 body标签 title标签 meta标签 1.2 标签标题h1 1.3 段落p 1.4 水平线 1.5 图片img 1.6 …

【Android12】Android Framework系列--AMS启动Activity分析

AMS启动Activity分析 通过ActivityManagerService(AMS)提供的方法&#xff0c;可以启动指定的Activity。比如Launcher中点击应用图标后&#xff0c;调用AMS的startActivity函数启动应用。 AMS提供的服务通过IActivityManager.aidl文件定义。 // frameworks/base/core/java/an…

【AI底层逻辑】——数学与机器学习:优雅的智慧之舞

目录 “宝藏网站” 聊聊数学 “华尔兹” “智慧之舞” 后续的章节我们将迎来新的篇章&#xff0c;新的切入点探索AI的奥秘&#xff0c;通过揭示高数、矩阵、概率论等数学知识与机器学习的关系来深入理解AI的奥秘&#xff01; “宝藏网站” 开头先给大家上几个宝藏网站&am…

【离散数学】——期末刷题题库(欧拉图和哈密顿图)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

java中,用函数对象表示策略

简而言之&#xff0c;函数指针的主要用途就是实现策略(Strategy)模式。 Java没有提供函数指针&#xff0c;但是可以用对象引用实现相同的功能。调用对象上的方法通常是执行该对象上某项操作。 在Java中&#xff0c;使用函数对象&#xff08;Function Object&#xff09;表示策…

《数据结构、算法与应用C++语言描述》-机器调度-最长处理时间(LPT)

机器调度 完整可编译运行代码见&#xff1a;Github::Data-Structures-Algorithms-and-Applications/_28LongestProcessingTime 问题描述 一个工厂具有 m台一模一样的机器。我们有n 个任务需要处理。设作业i的处理时间为 t i t_i ti​&#xff0c;这个时间包括把作业放入机器…

Amazon Aurora Limitless Database:数据库管理的全新境界

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 在当今数亿用户、PB级数据和数百万交易的业务环境中&#xff0c;数…

12.14_黑马数据结构与算法笔记Java

目录 120 二叉搜索树 min max 121 二叉搜索树 put 122 二叉搜索树 前任后任1 123 二叉搜索树 前任后任2 124 二叉搜索树 删除1 125 二叉搜索树 删除2 126 二叉搜索树 删除3 127 二叉搜索树 删除 递归1 128 二叉搜索树 删除 递归2 129 二叉搜索树 范围查询 130 二叉搜…

KUKA机器人如何隐藏程序或程序段?

KUKA机器人如何隐藏程序或程序段? 如下图所示,新建一个示例程序进行说明, 如下图所示,如果红框中的动作指令不想让别人看到,想隐藏起来,如何做到? 如下图所示,在想要隐藏的程序或程序段的前后,分别添加 ;fold 和 endfold指令(这里要注意是英文状态下的输入法), 如…

国标GB28181安防监控系统/磁盘阵列EasyCVR(V.3.4)新亮点:免保活功能

TSINGSEE青犀近日发布了EasyCVR安防管理平台的V.3.4版本&#xff0c;其中一大亮点就是很多朋友都在咨询的“免保活”功能&#xff0c;那么&#xff0c;什么是“免保活”功能&#xff1f;又该如何配置呢&#xff1f; 在EasyCVR平台有个【按需直播】按钮&#xff0c;顾名思义&…

如何部署Portainer容器管理工具+cpolar内网穿透实现公网访问管理界面

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…

大象elephant目标检测数据集VOC+YOLO格式2300张

大象是长鼻目象科的哺乳动物&#xff0c;有两个属&#xff0c;是世界上最大的陆生动物。其像柱子一样的四肢和宽厚的脚掌可以稳稳支撑住庞大的身体。巨大的头上长有蒲扇状的大耳朵和长且有弹性的鼻子。象耳上有丰富的血管&#xff0c;可以有效散热。鼻子和上唇合而为一的象鼻由…

YB9225是一种固定工作频率的高效率电流模式升压转换器。

YB9225B 1.2 MHz。峰值5A 电流&#xff0c;升压转换器 概述 &#xff1a; YB9225是一种固定工作频率的高效率电流模式升压转换器。YB9225集成了一个非常低的 Rds-on NMOSFTET&#xff0c;以减少功率损耗和实现高效率。最高效率可达93% 。功率 MOSFET 的峰值电流限制在5 A。1.…

网站使用CDN后无法获取用户真实IP的解决方法

宝塔或Nginx环境 如果你使用的宝塔或Nginx&#xff0c;可以在宝塔面板或Nginx中&#xff0c;找到配置文件增加如下代码后&#xff0c;重载配置或者重启 Nginx 即可&#xff1a; #CDN获取真实ip set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; PHP语言函数方法…

36、什么是池化算法

池化算法也是 CNN 网络中非常常见的算法。 池化这一算法理解起来比较简单,从名字中或许可以看到一些东西:从一个像素池子中选取一些有代表性的像素出来。 常见的池化有最大池化和平均池化。最大池化就是从像素池子中选取最大值出来,而平均池化就是从像素池子中选取平均值出…

HTML---初识CSS

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.CSS概念 CSS是层叠样式表&#xff08;Cascading Style Sheets&#xff09;的缩写。它是一种用于描述HTML文档外观样式的标记语言。通过CSS&#xff0c;开发者可以在不改变HTML标记结构的情况…

机器学习 | 机器学习基础知识

一、机器学习是什么 计算机从数据中学习规律并改善自身进行预测的过程。 二、数据集 1、最常用的公开数据集 2、结构化数据与非结构化数据 三、任务地图 1、分类任务 Classification 已知样本特征判断样本类别二分类、多分类、多标签分类 二分类&#xff1a;垃圾邮件分类、图像…

【数据结构入门精讲 | 第一篇】打开数据结构之门

数据结构与算法是计算机科学中的核心概念&#xff0c;也与现实生活如算法岗息息相关。鉴于全网数据结构文章良莠不齐且集成度不高&#xff0c;故开设本专栏&#xff0c;为初学者提供指引。 目录 基本概念数据结构为何面世算法基本数据类型抽象数据类型使用抽象数据类型的好处 数…