当前位置: 首页 > news >正文

【Java】杨辉三角、洗牌算法

一、杨辉三角

给定一个非负数numRows,生成杨辉三角的前 numRows 行。

在杨辉三角中,每个数是它左上方和右上方的数之和

示例:输入:numRows = 5

           输出: [ [1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ]

思路:使用二维数组 的思路,使用列表的思路创建二维数组,定义行和列。

我们说过要用List列表的思路去创建二维数组:

示例:可以往这个列表中添加元素,只不过这个元素是一个个实例化的对象(传递的参数是一个泛型类,那么它也需要明确传递的参数类型,因此需要实例化对象),证明是一个二维数组:

输出结果:

那么,具体如何向这个二维数组存放具体的元素呢?

—— 前面说过,传递的参数是一个泛型类,因此需要实例化对象,但是不可以这样:

那么我们可以单独将列表每个实例化的元素写出来,往这一个个元素中,使用add方法添加元素,然后再将这些实例化的对象的引用传递给列表:

输出结果:

我们也可以通过调试观察:

前面的准备知识学习完后,我们正式开始写杨辉三角:

使用 [i][j] = [i-1][j-1] + [i-1][j-1] 的思路。

写一个方法 generate ,它的返回值是List<LIst<Integer>>,在方法中,我们首先处理第一行,因为杨辉三角的第一行只有一个元素,那就是1,因此,我们先处理第一行,将这一行的元素先添加到列表中;然后从第二行开始,进行求每一个元素(使用前面的公式),由于杨辉三角的每一行的第一个元素和最后一个元素都是1,于是也可以直接添加,从每一行的第二个元素开始求,也就是中间的这些位置:根据公式,需要先求该行的前一行的元素信息,然后利用这些信息进行该行的元素求解;最后返回列表。

public class Test {public static List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayLIst<>();//处理第一行List<Integer> list0 = new ArrayList<>();list0.add(1);ret.add(list0);//从第2行开始 进行求元素for(int i = 1;i < numRows; i++) {//处理第一个元素List<Integer> curRow = new ArrayList<>();curRow.add(1);//中间//从第二个元素开始求元素List<Integer> preRow = ret.get(i-1);//前一行for(int j = 1;j < i; j++) {//[i][j] = [i-1][j-1] + [i-1][j-1] int val1 = preRow.get(j);int val2 = preRow.get(j-1);ret.add(val1 + val2);}            //尾巴curRow.add(1);ret.add(curRow);}return ret;}public static void main(String[] args) {List<List<Integer>> list = new ArrayList<>();List<List<Integer>> ret = generate(4);for(int i = 0;i < ret.size(); i++) {for(int j = 0;j < ret.get(i).size(); j++) {System.out.print(ret.get(i).get(j) + " ");}System.out.println();}}
}

输出结果:

二、洗牌算法

要完成洗牌,有三个步骤:

  • 1.买扑克牌 52张牌
  • 2.洗牌
  • 3.设有3个人,每个人轮流揭5张牌

1.Card类——描述一副牌的组成

首先我们写一个类Card,用来描述买来的一副牌的组成:

public class Card {private String suit;//花色private int rank;//牌面值//构造方法public Card(String suit,int rank) {this.suit = suit;this.rank = rank;} //重写toSTringpublic void toString() {return "{" + suit + rank + "}";}
}

2.CardDemo类——完成买牌、洗牌等操作

然后再写一个类CardDemo,在这个类中,完成买牌、洗牌等一些列事情;一副牌中,包括四种花色,分别是红心、方块、梅花和黑桃,每种花色有13张牌,总计52张牌。

因此,我们可以先定义一个字符串数组,数组内存放四种花色牌,各一张,由于这四种花色是固定不变的,可以写成一个常量数组(final修饰);

然后写一个 buyCard 方法,它的返回值是List<Card>,表示买牌的动作,在这个方法中:先实例化一个Card类对象,然后通过for循环嵌套将各个花色的所有牌放入对象中(每个花色的牌各有13张,一样的牌各有4张),最后通过add方法添加到Card类对象中。

注意:该方法的返回值是一个泛型类,它的参数是一个Card类类型,因此,需要实例化Card类对象,这里每添加一个花色牌就利用Card的构造方法初始化一下suit和rank,最后将这个Card类型引用作为参数传递给泛型类。

public class CardDemo {public static final String[] suits = {"♥","♠","♣","♦"};//买一副牌public List<Card> buyCard() {List<Card> cardList = new ArrayList<>();for(int i = 1;i <= 13; i++) {for(int j = 0;j < 4; j++) {int rank = i;String suit = suits[j];Card card = new Card(suit,rank);cardList.add(card);}}return cardList;}
}

接着写一个 shuffle 方法,表示洗牌的动作,在这个方法中,我们需要做的就是打乱牌的顺序,即洗牌。这里需要用到一个类——Random,这个类中的一个 nextInt 方法,用于生成一个随机数值,该方法的有两种使用方式:

  1. nextInt():生成一个随机的 int 值,范围是所有可能的 int 值
  2. nextInt(int bound):生成一个在 [0, bound) 范围内的随机 int 值,包含 0 但不包含 bound

而我们此时需要用的是第2种方式。

写一个for循环,初始条件从最后一张牌开始,在这个循环中,使用random.nextInt() 方法,每次将随机生成的数值和最后一张牌进行随机交换,比如,有52张牌,它们对应下标是0~51,对这副牌进行洗牌,从最后一张牌开始进入循环,通过random.nextInt(51)生成0~50之间的随机牌,让最后一张牌,即第52张牌与随机的一张牌进行位置交换,接着是通过random.nextInt(50)生成0~49之间的随即牌,再将此时的最后一张牌与随机牌位置交换,直到全部牌交换完成,就完成了洗牌的动作。

注意:循环继续直到i > 0,当i变成0时,循环停止。这是因为当i=0时,只有一个元素 left,不需要交换自己。

而位置交换的动作则写一个 swap 方法来完成:按照之前写swap方法的思路:

  • Card tmp = cardLIst[i];
  • cardList[i] = cardList[j];
  • cardList[j] = tmp;

但是这样写是不行的,cardList引用的类型是List<Card>泛型类,并不是一个数组,不可以使用数组下标运算符[],对于List<Card>类,应该使用 get() 和 set() 方法来代替进行位置交换操作。

public void shuffle(List<Card> cardList) {Random random = new Random();for(int i = cardList.size()-1;i > 0; i--) {int index = random.nextInt(i);swap(cardList,i,index);}
}
public void swap(List<Card> cardList,int i,int j) {Card tmp = cardList.get(i);cardList.set(i,cardList.get(j));cardList.set(j,tmp);
}

最后写一个轮流揭牌的方法 play ,假设有3个人,每个人要揭5张牌,那么每个人的5张牌要如何存放呢?—— 3个人各自实例化一个List泛型类,将各自的牌存放在各自的引用对象中;使用for循环嵌套,进行轮流揭牌,每次揭玩一张牌,牌就会少一张,使用remove方法,每次揭玩一张牌就删除最上面的那张牌,即下标为0的那张牌。

问题:如何将对应的牌放到对应的人手里呢?

—— 使用二维数组

public <List<Card>> play(List<Card> cardList) {List<Card> hand0 = new ArrayList<>();List<Card> hand1 = new ArrayList<>();List<Card> hand2 = new ArrayList<>();List<List<Card>> hand = new ArrayList<>();hand.add(hand0);hand.add(hand1);hand.add(hand2);for(int i = 0;i < 5; i++) {for(int j = 0;j < 3; j++) {Card card = cardList.remove(0);hand.get(j).add(card);//比如:hand.hand0.add(card);}}return hand;
}

3.完整代码

//Card类public class Card {private String suit;private int rank;public Card(String suit,int rank) {this.suit = suit;this.rank = rank;}public void toString() {return "{" + suit + rank + "}";}
}
//CardDemo类public class CardDemo {public static final String[] suits = {"♥","♠","♣","♦"};//买一副牌public List<Card> buyCard() {List<Card> cardList= new ArrayList<>();for(int i = 1;i <= 13; i++) {for(int j = 0;j < 4; j++) {int rank = i;String suit = suits[j];Card card = new Card(suit,rank);cardList.add(card);}}return cardList;}//洗牌public void shuffle(List<Card> cardList) {Random random = new Random();for(int i = cardList.size()-1;i > 0; i--) {int index = random.nextInt(i);swap(cardList,i,index);}}public void swap(List<Card> cardList,int i,int j) {Card tmp = cardList.get(i);cardList.set(i,cardList.get(j));cardList.set(j,tmp);}//3个人,轮流揭5张牌public List<List<Card>> play(List<Card> cardList) {List<Catd> hand0 = new ArrayList<>();List<Card> hand1 = new ArrayList<>();List<Card> hand1 = new ArrayList<>();List<List<Card>> hand = new ArrayList<>();for(int i = 0;i < 5; i++) {for(int j = 0;j < 3; j++) {Card card = cardList.remove(0);hand.get(j).add(card);}}return hand;}
}

4.测试

public class Test {public static void main(String[] args) {CardDemo cardDemo = new CardDemo();//买一副牌System.out.println("洗牌前:");List<Card> cardList = cardDemo.buyCard();System.out.println(cardList);//洗牌System.out.println("洗牌后:");cardDemo.shuffle(cardList);System.out.println(cardList);//3个人轮流揭5张牌System.out.println("抽牌:");List<List<Card>> ret = cardDemo.play(cardList);for(int i = 0;i < ret,size(); i++) {System.out.println("第"+(i+1)+"个人的牌:"+ret.get(i));}System.out.println("剩下的牌:");System.out.println(cardList);}
}

输出结果:

http://www.dtcms.com/a/441711.html

相关文章:

  • 密码学中的Salt
  • 嵌入式硬件——基于IMX6ULL的GPT(通用定时器)实现
  • 东莞 营销网站建设互动网站如何做
  • 【pytest】使用 marker 向 fixture 传递数据
  • 从0死磕全栈之Next.js 中间件(Middleware)详解与实战
  • 用个人电脑做服务器建网站天门市基础建设网站
  • 分布式专题——26 BIO、NIO编程与直接内存、零拷贝深入辨析
  • Redisson分布式限流
  • 计算机网络-应用层协议原理
  • 分布式文件存储系统FastDFS(入门)
  • 电机控制-PMSM无感FOC控制(五)相电流检测及重构 — 单电阻采样
  • C语言底层学习(4.数据在内存中的存储)
  • 虚幻引擎UE5专用服务器游戏开发-33 在上半身播放组合蒙太奇
  • 织梦网站栏目访问目录做网站建设哪家效益快
  • 『数据结构』消失的数字
  • 鹤山网站建设易搜互联湖南seo
  • ORB_SLAM2原理及代码解析:Tracking::CreateInitialMapMonocular() 函数
  • 【Linux】System V —— 基于建造者模式的信号量
  • VScode-ESP-IDF工程函数定义无法跳转且无注释提示
  • 最新的网站建设软件标书制作员工作内容
  • JAVA SE 基础语法 —— C / 运算符
  • SSM餐饮管理系统uto0o《开发全资源(程序 / 源码 / 数据库)+ 万言论文(文末)+ 系统界面》
  • 上饶市建设厅网站中国最新消息新冠疫苗最新消息
  • 安徽省建设银行网站关于网站建设的意见
  • 免费域名建站青岛网站有限公司
  • 广东泰通建设有限公司网站东莞人才网58
  • 什么是wap网站甘家口网站建设
  • 网站接电话中国关键词官网
  • 广州车陂网站建设公司wordpress如何修改博客模板
  • 沈阳谷歌网站建设金湖建设局网站