java:关于ArrayList顺序表的运用

一.简单的洗牌算法

注意:本次题目中,只有52张牌,不包括大小鬼。

这道题目只有简单的2个字,洗牌。

那么想要完成好它,我们就得先想想它的构成

并根据它的构成定义好不同的类,再将之组成起来。

洗牌洗牌,我们必须先有牌吧,然后才能洗。

所以我决定先定义一个Card类,表示每一张牌。

那么每一张牌都有花色点数这2个元素,也就是Card类中的2个成员变量

public class Card {
    String suit;
    int rank;
    public Card(int rank,String suit){
        this.suit = suit;
        this.rank=rank;
    }
    @Override
    public String toString() {
        return "{"+ suit +"," +rank +"}";
    }
}

在定义好我们的Card类之后,想想每一个Card类是不是就代表着一张牌,一个牌组有52张牌。

我们接下来的思路就是创建一个牌组。

一个牌组,也就是逻辑结构连起来的52个元素,那么我们可以自然得想到用数组来存放它。

由于我们想要对牌组进行洗牌,普通的数组肯定不行,因为我们需要对数组写各种操作方法,一一

实现太麻烦了,此时就会想到java中的ArrayList已经帮我们实现了这些方法,并且可以直接用。

我们把牌组定义成一个Cards类

public class Cards {
       public static String[] suits={"♥","♠","♣","♦"};//扑克牌中一共有四种花色
       //我们先要有一副扑克牌
     public List<Card> buyCards(){//创建一个实现了List接口以Card为元素的顺序表
            List<Card> cardList = new ArrayList<>();
         for (int i = 0; i < 4; i++) {
             for (int j = 1; j <=13 ; j++) {
                  String suit = suits[i];
                  int rank = j;
                 Card card = new Card(rank,suit);
                 cardList.add(card);
             }
         }

         return cardList;
     }

已经有牌了,接下来我们要如何洗牌呢?

可以想到的是我们的Random这个可以产生随机数的方法

这个用法是这样的:

 Random random = new Random();
 int rankIndex = random.nextInt();

random.nextInt()的返回值是int类型,用int类型的变量来进行接收。

我们可以往random.nextInt()括号里面写入int类型的值,假设为c。

那么接收的变量是处于小于c大于等于0这个区间里面的。

我们既然想要改变一张牌在牌组的顺序,那么这张牌会与别的牌进行交换。

在数组中怎么交换呢?答案是利用它的下标,有了下标才能访问到对应的牌。

   public void shuffle(List<Card> card){
         Random random = new Random();
         for (int i =card.size()-1; i>0 ; i--) {
              int rankIndex = random.nextInt(i);
             swap(card,i,rankIndex);
         }
     }

     public void swap(List<Card> card, int i, int j){

         Card tmp = card.get(i);
         card.set(i,card.get(j));
         card.set(j,tmp);

         //tmp = i;平时我们写的交换就是这样,上面的是牌组的换牌操作
         //i=j;
         //j=tmp;
     }

接着我们想让3个人每一个人抓5张牌。

我们首先要先把三个人实例化出来,既然是用手抓牌,将其定义为hand1、2、3

         List<Card> hand1 = new ArrayList<>();
         List<Card> hand2 = new ArrayList<>();
         List<Card> hand3 = new ArrayList<>();

hand1行里表示的是第一个人抽的五张牌,以此类推。·

我们脑子里的结构应该是这样子的。

hand1[0]hand1[1]hand1[2]hand1[3]hand1[4]
hand2[0]hand2[1]hand2[2]hand2[3]hand2[4]
hand3[0]hand3[1]hand3[2]hand3[3]hand3[4]

一下子就有了方向:二维数组

一步一步往下想,我们的List<Card>  hand1 = new ArrayList<>();中的每一个元素都存放着Card类

型的数据,那我们可以让hand1的每一个元素存放一个顺序表吗?

具体写法:

List<List<Integer>> ret = new ArrayList<>();

解决了这个问题,我们就可以写出代码了。

public void catchCards(List<Card> cardList){//设计为三个人抓五张牌
         List<Card> hand1 = new ArrayList<>();
         List<Card> hand2 = new ArrayList<>();
         List<Card> hand3 = new ArrayList<>();

         List<List<Card>> hands = new ArrayList<>();

         hands.add(hand1);
         hands.add(hand2);
         hands.add(hand3);

         for (int i = 0; i < 5; i++) {

             for (int j = 0; j < 3; j++) {
                 Card card = cardList.remove(0);
                 List<Card> tmpHand = hands.get(j);
                 tmpHand.add(card);
             }

         }
         System.out.println("第一个人抓的牌"+hand1);
         System.out.println("第二个人抓的牌"+hand2);
         System.out.println("第三个人抓的牌"+hand3);

     }

最后把Cards类的代码整合起来:

public class Cards {
       public static String[] suits={"♥","♠","♣","♦"};//扑克牌中一共有四种花色
       //我们先要有一副扑克牌
     public List<Card> buyCards(){//创建一个实现了List接口以Card为元素的顺序表
            List<Card> cardList = new ArrayList<>();
         for (int i = 0; i < 4; i++) {
             for (int j = 1; j <=13 ; j++) {
                  String suit = suits[i];
                  int rank = j;
                 Card card = new Card(rank,suit);
                 cardList.add(card);
             }
         }

         return cardList;
     }
     public void shuffle(List<Card> card){
         Random random = new Random();
         for (int i =card.size()-1; i>0 ; i--) {
              int rankIndex = random.nextInt(i);
             swap(card,i,rankIndex);
         }
     }

     public void swap(List<Card> card, int i, int j){

         Card tmp = card.get(i);
         card.set(i,card.get(j));
         card.set(j,tmp);

         //tmp = i;平时我们写的交换就是这样,上面的是牌组的换牌操作
         //i=j;
         //j=tmp;
     }

     public void catchCards(List<Card> cardList){//设计为三个人抓五张牌
         List<Card> hand1 = new ArrayList<>();
         List<Card> hand2 = new ArrayList<>();
         List<Card> hand3 = new ArrayList<>();

         List<List<Card>> hands = new ArrayList<>();

         hands.add(hand1);
         hands.add(hand2);
         hands.add(hand3);

         for (int i = 0; i < 5; i++) {

             for (int j = 0; j < 3; j++) {
                 Card card = cardList.remove(0);
                 List<Card> tmpHand = hands.get(j);
                 tmpHand.add(card);
             }

         }
         System.out.println("第一个人抓的牌"+hand1);
         System.out.println("第二个人抓的牌"+hand2);
         System.out.println("第三个人抓的牌"+hand3);

     }

}

再创建一个测试类测试一下:

public class TestCard {
    public static void main(String[] args) {
        Cards cards = new Cards();
        List<Card> cardList = cards.buyCards();
        //System.out.println(cardList);
        cards.shuffle(cardList);
        cards.catchCards(cardList);
    }
}

二.杨辉三角

如果你也理解了像上一题中让3个人每一个人抓5张牌的核心:创建二维数组。

那么这道题对你来说压力会小很多

链接:118. 杨辉三角 - 力扣(LeetCode)

做这道题我们要了解到,从每一行的第一个和最后一个都是1,从第三行的第2个元素到倒数第二个

元素开始,这些元素都等于上一行上一列和上一行前一列的元素和。

此题在idea上的代码为:

public class Test {
    public static void TestTriangle() {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        List<List<Integer>> ret = new ArrayList<>();
        List<Integer> cur = new ArrayList<>();
        cur.add(1);
        ret.add(cur);
        for (int i = 1; i < n; i++) {//注意,我们是从第二行开始的
            List<Integer> curRow = new ArrayList<>();
            curRow.add(1);
            for (int j = 1; j<i; j++) {
                List<Integer> prevRow = ret.get(i - 1);//得到上一行
                curRow.add(prevRow.get(j-1)+prevRow.get(j));
            }
            curRow.add(1);
            ret.add(curRow);
        }
        for (List<Integer> x://这里我采用for:each的形式打印
             ret) {
            System.out.println(x);
        }
    }

    public static void main(String[] args) {
        TestTriangle();
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值