题目要求:
此外红色球号不能重复
因为对类的运用还不熟悉,所以全都写到同一个类里了。印象中是要输出和逻辑业务分离的,但是感觉还不太会分离,所以显得逻辑有点混乱,没有转化到面向对象编程思想上。除了主方法,还写了其他六个方法。
public static int menu()//显示菜单
public static int buyBalls (int[] balls )//买彩票,返回买多少注
public static int[] randomBalls(boolean isBuy)//生成随机中奖码
public static boolean isRepeat(int[] arr,int key)//判重复元素
public static int judgePrize(int[] buyBalls,int[] prizeBalls)//判断是否中奖,返回中奖等级
public static void printPrize(int prize,int num)//输出中奖信息
1、主方法中用了死循环+强制退出的方法
public static void main(String[] args) {
boolean flagCase = true;//是否退出
boolean isBuy = false;//是否已买
int num = 0;//买num注
int[] balls = new int[7];
while (flagCase) {
int choose = menu();
switch (choose) {
case 1:
num = buyBalls (balls);
isBuy = true;
break;
case 2:
if (isBuy) {
int[] prizeBalls = randomBalls(isBuy);//生成中奖码
int prize = judgePrize(balls, prizeBalls);//判断中奖等级
System.out.print("自己买的彩票号为:");
for (int i : balls) {
System.out.print(i+"\t");
}
System.out.print("\n当期的中奖票号为: ");
for (int i : prizeBalls) {
System.out.print(i+"\t");
}
printPrize(prize, num);
} else {
System.out.println("您还未购买彩票,请先购买彩票。");
}
break;
case 3: flagCase = false;return;
default:System.out.println("输入错误。");
}
}
}
2、public static int menu()//显示菜单
这里遇到了个问题,扫描器不能关闭,报了个warning,如果关掉扫描器的话,会报一个
Exception in thread “main” java.util.NoSuchElementException
试了一下,在main方法最后关闭或者在menu中关闭都不可以。
错误原因是:无论定义多上个Scanner对象,都是共享一个常量流的,(System.in这应该是一个常量流)一旦关闭了就不能够再使用
@SuppressWarnings("resource")
public static int menu() {
System.out.println("*****欢迎进入双色球彩票系统*****");
System.out.println("\t1、购买彩票");
System.out.println("\t2、查看开奖");
System.out.println("\t3、退出");
System.out.println("*************************");
System.out.print("请选择菜单:");
Scanner scan = new Scanner(System.in);
int choose = scan.nextInt();
return choose;
}
3、public static int buyBalls (int[] balls )//买彩票,返回买多少注
先判断,合法输入才将数据录入数组中。
//买彩票,返回买多少注
public static int buyBalls (int[] balls ) {
System.out.println("【双色球彩票系统 > 购买彩票】");
Arrays.fill(balls,0);//重置数组,再次购买前清零
System.out.println("您需要下多少注?:");
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
int red = -1,blue = -1;
int i = 0;//记录当前数组索引,输入不正确时不改变
//红球判合法、重
do {
System.out.println("输入了6个红色球号<数字为1-33>,第【"+(i+1)+"】个红色球号为:");
red = scan.nextInt();
if (red>0 && red<34) {
if (isRepeat(balls,red)) {//重复时跳出
System.out.println("输入了重复的数字,请再次输入第【"+(i+1)+"】个值:");
} else {
balls[i] = red;
i++;
}
} else {
System.out.println("输入了超出范围的数字,请再次输入第【"+(i+1)+"】个值:");
}
}while(i < 6);
//蓝球判合法
System.out.println("请输入1个蓝色球号<数字为1-16>:");
blue = scan.nextInt();
if (blue > 0 && blue < 17) {
balls[6] = blue;
}
System.out.print("您一共买"+num+"注,共需支付【"+(2*num)+"】元。");
System.out.println("选的号是:"+Arrays.toString(balls));
return num;
}
4、public static int[] randomBalls(boolean isBuy)//生成随机中奖码
这里用了Math.random()方法生成[0.0-1.0)之间的double类型随机数
对于生成[m,n]之间的随机数 (int)(Math.random()*(n-m+1) + m);
//生成随机中奖码
public static int[] randomBalls(boolean isBuy) {
int[] prizeBalls = new int[7];
if (isBuy) {
//生成中奖码
int red = -1;
int i = 0;//记录当前数组索引,输入不正确时不改变
do {
red = (int)( Math.random()*33+1);//1-33的随机数
if (!isRepeat(prizeBalls, red)) {//不重复时,赋值
prizeBalls[i] = red;
i++;
}
}while(i < 6);
prizeBalls[6] = (int)( Math.random()*15+1);//1-16的随机数
} else {
System.out.println("您还没有买彩票,请下注:");
}
return prizeBalls;
}
5、public static boolean isRepeat(int[] arr,int key)//判重复元素
//判重复元素
public static boolean isRepeat(int[] arr,int key) {
boolean flag = false;//默认不重复
for (int i : arr) {
if (i == key) {
flag = true;
break;
}
}
return flag;
}
6、public static int judgePrize(int[] buyBalls,int[] prizeBalls)//判断是否中奖,返回中奖等级
为了不改变球号的位置,复制到了新的数组。Arrays.copyOf(int[] original, int newLength) ,返回一个新的数组,length用来指定新数组的长度,需要时,空位补零。
方便比较相等,先将数组排序了。sort(int[] a, int fromIndex, int toIndex) ,指定范围内的数组进行排序了,这里只对红色球排序。
这个判断重复的数的方法记得之前算法中讲过,但是想不起来了。网上搜了搜也没发现,甚至有点怀疑写的对不对。
//判断是否中奖,返回中奖等级
public static int judgePrize(int[] buyBalls,int[] prizeBalls) {
int[] arr1 = Arrays.copyOf(prizeBalls, prizeBalls.length);
int[] arr2 = Arrays.copyOf(buyBalls, buyBalls.length);
Arrays.sort(arr1, 0, 7);//升序,[0,7)
Arrays.sort(arr2, 0, 7);//升序,[0,7)
int iequal = 0;//红球相等的个数
int i1 = 0;//记录arr1的下标
/*
* 以中奖码arr1为参照,用买的码arr2的值去比对
*/
//只判断红球
for(int i = 0;i < arr2.length-1;i++) {
for (int j = i1;j < arr1.length-1;j++) {
//如果arr2[i]比arr1[j]小,那它比j之后每个数都小,不用再比较
if (arr2[i] < arr1[j]) {
break;
} else if(arr2[i] == arr1[j]) {
iequal++;
break;
} else {
//如果arr2[i]>arr1[j],那么必有arr2[i+1]>arr1[j],所以j不用从头开始比较,记录下标位置
i1 = j;
}
}
}
boolean blue = arr1[6]==arr2[6];
int prize = 0;//记录中奖等级
if (iequal == 6 && blue) {
prize = 1;
} else if (iequal == 6) {
prize = 2;
} else if (iequal == 5 && blue) {
prize = 3;
} else if (iequal == 5 || (iequal == 4 && blue)) {
prize = 4;
} else if (iequal == 4 || (iequal == 3 && blue)){
prize = 5;
} else if (blue) {
prize = 6;
} else {
prize = 0;
}
return prize;
}
7、public static void printPrize(int prize,int num)//输出中奖信息
public static void printPrize(int prize,int num) {
switch(prize) {
case 1 :
System.out.println("\n恭喜您,中一等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
case 2 :
System.out.println("\n恭喜您,中二等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
case 3 :
System.out.println("\n恭喜您,中三等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
case 4 :
System.out.println("\n恭喜您,中四等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
case 5 :
System.out.println("\n恭喜您,中五等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
case 6 :
System.out.println("\n恭喜您,中六等奖,共下"+num+"注,投资"+(num*2)+"元");
break;
default:
System.out.println("\n抱歉,您没中奖");
}
}
第五个方法中写到的判断两组数中是否有相等的值,感觉不太对还希望有大神来指点一二,不胜感激。