这里有个自己无聊用Java写的双色球生成器。
本来运行正常的。
后来发现生成的号码中有重复的数字。就加入了check(int[] i)方法。
该方法本来想要实现的功能是,冒泡法检查数组中是否有重复的元素,若有则重新生成。
但是加入之后整个程序就无限执行了。
我想知道为什么会这样,以及怎样改进代码以达到本来的目的。
不胜感激。完整源码如下import java.math.*;
import java.util.Scanner;public class LotteryGenerator {
    static int randomInt(int x){
        int ret;
        do{
            double getran = (10000*Math.random());
            ret = (int)getran;
        }while(ret>x || ret==0);
        return ret;
    }
    static void run(int[] x,int[] y){
        int i;
        for(i=0;i<x.length;i++){
            x[i] = randomInt(33);
        }
        y[0] = randomInt(16);
    }
    static void print(int[] x,int[] y,int z){
        int length;
        System.out.println("模拟开奖结果 " + z);
        System.out.print("红球是:");
        for(length=0;length<x.length;length++){
            System.out.print(x[length] + " ");
        }
        System.out.println();
        System.out.print("蓝球是:");
        System.out.println(y[0]);
        System.out.println("=====================");
    }
    static boolean check(int[] x){
        boolean isIlleg = false;
        int i=0,j=0;
        for(i=0;i<x.length;i++){
            for(j=0;j<x.length;j++){
                if(x[i] == x[j]){
                    isIlleg = true;
                }
            }
        }
        return isIlleg;
    }
    static int input(){
        Scanner s = new Scanner(System.in);
        int i=0;
        System.out.print("请输入开奖注数:");
        i = s.nextInt();
        System.out.println("=====================");
        return i;
    }
    public static void main(String[] args) {
        int[] general = new int[6];
        int[] special = new int[1];
        int i = input();
        for(int c=0;c<i;c++){
            do{
                run(general,special);
            }while(check(general));
            java.util.Arrays.sort(general);
            print(general,special,(c+1));
        }
    }
}

解决方案 »

  1.   

    如果把main()方法里的do{
                    run(general,special);
                }while(check(general));
    改成run(general,special);
    程序就正常执行。只是没有去重功能了,输出的彩票一定几率会出现重复数字。大大们可以尽量按着原来的源码修改么?小弟新人,改动太大会看不懂……请见谅。
      

  2.   


      static boolean check(int[] x){
            boolean isIlleg = false;
            int i=0,j=0;
            for(i=0;i<x.length;i++){
                for(j=0;j<x.length;j++){
                    if(x[i] == x[j]){
                        isIlleg = true;
                    }
                }
            }
            return isIlleg;
        }
    这段代码逻辑与问题。
    改一下:
        static boolean check(int[] x){
            boolean isIlleg = false;
            int i=0,j=0;
            for(i=0;i<x.length-1;i++){ //循环数组长-1。
       if(isIlleg){ //有重复,中断。
    break;
        }
                for(j=i+1;j<x.length;j++){ //从上层循环的下一个数开始。
                    if(x[i] == x[j]){
                        isIlleg = true;
        break; //检测有重复,中断内层循环。
                    }
                }        }
            return isIlleg;
        }
      

  3.   

    check方法里面有个明显的bug。双层循环,遍历同一个数组,下角标(i和j)会存在相同的时候,这个时候,进入if语句,返回true。也就是说,楼主的check方法,怎么调用,都会返回true,造成主调函数中while循环变成了死循环,程序无法正常退出。正确的逻辑,应该是在check方法体里面,双层循环中的if条件中,排除i和j相等的情况。
    比如:if(x[i] == x[j] && i!=j){...}
      

  4.   

    check 方法的问题,楼主再研究一下冒泡排序吧。冒泡排序可不是这么写的。
      

  5.   

    当然,很明显,双层循环中,我们会发现,这种比较,存在重复比较的情况。
    举个例子,如果数组有5个数字,当i=1,j=3时的比较情况,与i=3,j=1时的相同。
    所以,除了4楼的更改方案,还有一个方案也是可行的。不用更改if条件,只要更改内层循环的初试值即可。
    使得内存循环的初始值,总是比外层初始值大1,这样,可以避免重复比较的情况发生。
    也就是楼主所谓的"冒泡检查"吧。例如:
            for(i=0;i<x.length;i++){
                for(j=i+1;j<x.length;j++){
                    if(x[i] == x[j]){
                        isIlleg = true;
                    }
                }
            }
      

  6.   

    最后,生成随机数,可以参考Random类,没必要搞个那么复杂的方法。
      

  7.   

    4楼已经给出正解,还有两个问题
    1.楼主用的太多的循环,有的不必要如:
     static int randomInt(int x){
            int ret;
            do{
                double getran = (10000*Math.random());
                ret = (int)getran;
            }while(ret>x || ret==0);
            return ret;
        }
    可改成:
        static int randomInt(int x){
            double getran = (10000*Math.random());
            return (int)getran%(x-1)+1;
        }
    2. 蓝色球是可以跟红球相同么?好像不行吧,楼主也没有进行判断。
      

  8.   

    给分吧
    //import java.math.*;
    import java.util.Scanner;public class LotteryGenerator {
    static int randomInt(int x) {
    int ret;
    do {
    double getran = (10000 * Math.random());
    ret = (int) getran;
    } while (ret > x || ret == 0);
    return ret;
    } static void run(int[] x, int[] y) {
    int i;
    for (i = 0; i < x.length; i++) {
    x[i] = randomInt(33);
    }
    y[0] = randomInt(16);
    } static void print(int[] x, int[] y, int z) {
    int length;
    System.out.println("模拟开奖结果 " + z);
    System.out.print("红球是:");
    for (length = 0; length < x.length; length++) {
    System.out.print(x[length] + " ");
    }
    System.out.println();
    System.out.print("蓝球是:");
    System.out.println(y[0]);
    System.out.println("=====================");
    } static boolean check(int[] x) {
    boolean isIlleg = false;
    int i = 0, j = 0;
    for (i = 0; i < x.length; i++) {
    for (j = 0; j < x.length; j++) {
    if(j==i){
    continue;
    }
    if (x[i] == x[j]) {
    isIlleg = true;
    }
    }
    }
    return isIlleg;
    } static int input() {
    Scanner s = new Scanner(System.in);
    int i = 0;
    System.out.print("请输入开奖注数:");
    i = s.nextInt();
    System.out.println("=====================");
    return i;
    } public static void main(String[] args) {
    int[] general = new int[6];
    int[] special = new int[1];
    int i = input();
    for (int c = 0; c < i; c++) {
    do {
    run(general, special);
    } while (check(general));
    // run(general, special);
    java.util.Arrays.sort(general);
    print(general, special, (c + 1));
    }
    }
    }
      

  9.   

    死循环那个很好解决,两个数只需要比较一次就够了;
    java提供了专门的Random类满足lz的需求
    static int randomInt(int x) {
    Random r = new Random();
    return r.nextInt(x) + 1;//此方法返回0<=且<x之间的整数
    }static boolean check(int[] x) {
    boolean isIlleg = false;
    int i = 0, j = 0;
    for (i = 0; i < x.length; i++) {
    for (j = i + 1; j < x.length; j++) {
    if (x[i] == x[j]) {
    isIlleg = true;
    }
    }
    }
    return isIlleg;
    }
      

  10.   

    将int[]改为Set,省掉所有的循环和判断。
      

  11.   

    恕小弟才学疏浅,对Java的Set暂时没有深入过。。
      

  12.   


    Random r = new Random();
    这句貌似会报错
    不知Random类是那个包里的,Math么?
      

  13.   

    看来哈!check()里面有很大的问题!x[i]==x[j]很矛盾肯定一直是true 所以是死循环