一.简单的洗牌算法
注意:本次题目中,只有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张牌的核心:创建二维数组。
那么这道题对你来说压力会小很多
做这道题我们要了解到,从每一行的第一个和最后一个都是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();
}
}