程序需求如下:
一个Java Servlet程序,每天有多个人去运行,程序主体会先产生一个随机数A,然后再产生一个随机数B(假设A和B都是3位的正整数,如:A=010,B=321)
如果A=B,那么则表示这个人中奖。
    我利用JAVA 的java.util.Randow类来产生上面的随机数。A和B相等的可能性还是会有的。但是我无法确保一天内必然有一次A=B。
假设这一天只有一次运行,我如何保证?我的产生随机数的方法如下:
    private String gen4Digital(){
        Random random = new Random();
        String s = String.valueOf(random.nextInt(5))   +  String.valueOf( random.nextInt(2) ) 
         + String.valueOf( random.nextInt(2) );
        return s;
    }以上算法会产生 A=41,B=32 等随机数,这些随机数的百位的可能的数字是0~4,十位的可能的数字是0~1,个位的可能的数字是0~1,

解决方案 »

  1.   

    给你一个思路
    一、你首先将运行后产生的数据存放在一个Application的常量数组中或文件中,假设是intvalue[];
    二、你在该天的最后几秒钟运行一下结果判断程序,像这样:
           int length = intvalue.length;//每天产生的数组大小
          int result = (int)(Math.random()*length);//为了生成数组的下标
           String awardNumber = intvalue[result];//中奖的号码
    三、第二天公布结果--------------------------------
    仅是一种思路,仅供参考
      

  2.   

    谢谢各位,没想到CSDN的上面的Tx都这么热心。高手也很多。
    看来确实没有办法保证每天必然有一次A=B.那么我就随机数的位数降低到2位,而且十位的可能的数字是0~1,个位的可能的数字是0~1,这样大大提高了中奖率。(即使是这样仍然不能保证每天必然有A=B,呵呵,干脆,每天第一个运行的人直接中奖得了,这个就不属于技术范畴的东西了:)但是我仍想知道的是 像我上面的程序中
    A= gen4Digital()
    B=  gen4Digital()
    println(A.equals(B))的概率是多少?
    如何写程序来得出这个概率?谢一个循环来运行吗?
      

  3.   

    for example
    private String A;
    boolean win = false;
    Caleander luckTime; //设置一个幸运时间private void init() {
        A = gen4Digital();
        Calendar c = Calendar.getInstance();
        int year = c.get(Calender.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DATE);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        int second = c.get(Calendar.SECOND);
        Random random = new Random(); 
        int ranHour = random.nextInt(24-hour);
        int ranMinute = random.nextInt(59-Minute);
        int ranSecond = c.get(59-second);
        luckTime = new GregorianCalendar(year, month, day, ranHour, ranMinute, ranSecond); //如果一天中没人中,就设一个幸运时间
        win = false;
    }private String getLuckNum() {
        if (Calendar.getInstance().get(Calendar.Date) != luckTime.get(Calendar.DATE)) { //换了新的一天了
            init();
        }    String num = gen4Digital();
        if (win) { //如果一天中有人中奖了
            while (num.equals(A)) { //同一天中不再产生中奖号
                num = gen4Digital();
            }
        } else { //如果一天中还没人中奖
            Calendar c = Calendar.getInstace();
            if (c.after(luckTime)) { //第一个超越幸运时间的人
                num = A;
            }
        }
        if (num.equals(A)) win = true; //已经产生中奖号    return num;
    }private String gen4Digital(){ 
        Random random = new Random(); 
        String s = String.valueOf(random.nextInt(5)) + String.valueOf(random.nextInt(2)) + String.valueOf(random.nextInt(2)); 
        return s; 
      

  4.   

    这个仍然可以用类似抽牌算法的方法来实现
    不过可以称之为“奖池算法”吧即是说,有一个奖池,里面有N个带唯一编号的纸条,每个人登录的时候,都会从奖池里抽出一个纸条,这个纸条抽出后,奖池里就没有这个编号了(这点很重要)。
    每隔24小时,公布一个编号,谁抽出的纸条是这个编号,谁就中奖了,同时如果没有任何人抽到这个编号,即意味着没有人中奖。
    之后,所有人都把纸条扔回奖池,重新开始新的一个轮次。具体思路是:
    1.在Server端要有一个全局的数组(用array表示)里面放有0~N这N个数,用来表示奖池,这N个数不一定非得是0~N这几个自然数,可以是随机生成的,比如101,223之类,但要保证唯一性,即不可重复
    2.在Server端要有一个全局的Application变量(用value表示)用以标志中奖的编号,每隔24小时用取随机数的方法更新一次,取到的值应该是array[Random(n)]的值
    3.当第一个人登录的时候,会取到一个值,这个值用Array[Random(n)]表示,假设这个值为x,所在序号为i,则当这个值被取出后应该互换Array[n]与Array[i]的位置,即模拟纸条被抽出这个过程
    4.当第二个人登录的时候,取到的值就应该不在包括array最末尾的那个值了,也即从Array[Random(n-1)]中取值,假设序号为j,这个值被取出后,就要互换Array[n-1]与Array[j]的位置
    5.以此类推,当N个人登录后则array中所有的纸条就都被取走了,为了避免这种情况,可以把奖池的纸条数设多一些,比如有10个人,就设纸条数为100个等等。
    6.之后,取到值的人,就可以用这个值(这样可以确保是唯一值)与vlaue进行比对,相等的,即为中奖,由于确保了value每隔24小时更新一次,同时奖池array每隔24小时重置一次,所以这样就可以确保每天只会有一个人中奖。
      

  5.   

    这个仍然可以用类似抽牌算法的方法来实现
    不过可以称之为“奖池算法”吧即是说,有一个奖池,里面有N个带唯一编号的纸条,每个人登录的时候,都会从奖池里抽出一个纸条,这个纸条抽出后,奖池里就没有这个编号了(这点很重要)。
    每隔24小时,公布一个编号,谁抽出的纸条是这个编号,谁就中奖了,同时如果没有任何人抽到这个编号,即意味着没有人中奖。
    之后,所有人都把纸条扔回奖池,重新开始新的一个轮次。具体思路是:
    1.在Server端要有一个全局的数组(用array表示)里面放有0~N这N个数,用来表示奖池,这N个数不一定非得是0~N这几个自然数,可以是随机生成的,比如101,223之类,但要保证唯一性,即不可重复
    2.在Server端要有一个全局的Application变量(用value表示)用以标志中奖的编号,每隔24小时用取随机数的方法更新一次,取到的值应该是array[Random(n)]的值
    3.当第一个人登录的时候,会取到一个值,这个值用Array[Random(n)]表示,假设这个值为x,所在序号为i,则当这个值被取出后应该互换Array[n]与Array[i]的位置,即模拟纸条被抽出这个过程
    4.当第二个人登录的时候,取到的值就应该不在包括array最末尾的那个值了,也即从Array[Random(n-1)]中取值,假设序号为j,这个值被取出后,就要互换Array[n-1]与Array[j]的位置
    5.以此类推,当N个人登录后则array中所有的纸条就都被取走了,为了避免这种情况,可以把奖池的纸条数设多一些,比如有10个人,就设纸条数为100个等等。
    6.之后,取到值的人,就可以用这个值(这样可以确保是唯一值)与vlaue进行比对,相等的,即为中奖,由于确保了value每隔24小时更新一次,同时奖池array每隔24小时重置一次,所以这样就可以确保每天只会有一个人中奖。
      

  6.   

    但是我仍想知道的是   像我上面的程序中 
    A=   gen4Digital() 
    B=     gen4Digital() 
    println(A.equals(B))的概率是多少? 
    如何写程序来得出这个概率?谢一个循环来运行吗? 
    -----------------------------
    概率是 1/5 * 1/2 * 1/2
      

  7.   

    talent_marquis 的思路不对,我是即抽即开,不是等每天结束后摇奖.
    qybao,我说错了,我是指我运行1000次,A=B的话就计数一次,那么总计数和1000的商就是概率。我写了程序来运行,概率很低。
    佩服qybao的代码编写能力,但是您的程序仍然无法保证每天必中。假设你的这个幸运时间设得很晚,还是不行啊。写了一段程序,来测试概率,发现概率总是在0~5之间。而且下面的程序中不用Thread.sleep()方法的话,概率总是100%.import java.util.Random;public class Test extends Thread{
    public void run()
    {
         int count = 0;
            
    for(int i=0;i<10;i++){
    String a = gen4Digital();
    System.out.print(",a=" + a );
    try {
    this.sleep(1*1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    String b = gen4Digital();
    System.out.print(",b=" + b );
    if( a.equals(b)){
    count++;
    System.out.print( ",count=" + count );
    }
    }
    System.out.println(count);
    System.out.println(  count/10 );
    }

        private  static String gen4Digital(){
            Random random = new Random();
            String s = String.valueOf(random.nextInt(5))   +  String.valueOf( random.nextInt(2) );
                  //+ String.valueOf(random.nextInt(2) );//  +   String.valueOf(random.nextInt(9));
            return s;
        }

        public static void main(String[] args){
         Test test = new Test();
         test.start();
        }
    }    
      

  8.   

    talent_marquis   的思路不对,我是即抽即开,不是等每天结束后摇奖. 
    --------------------我的思路随时可以开奖啊只要将步骤3调整为:
    3.当第一个人登录的时候,会取到一个值,这个值用Array[Random(n)]表示,假设这个值为x,所在序号为i,则当这个值被取出后应该互换Array[n]与Array[i]的位置,即模拟纸条被抽出这个过程,将他取到的值与value比对,如果相等,则通知他中奖
    后面以此类推就可以了
    直到最后第N个人抽完为止不管什么时候通知中奖都是可以的,只要确保在第一个人登录前,随机数value已经取到,同时array这个数组已经重置好即可。
      

  9.   

    talent_marquis       的思路不对,我是即抽即开,不是等每天结束后摇奖.   
    -------------------- 我的思路随时可以开奖啊 只要将步骤3调整为: 
    3.当第一个人登录的时候,会取到一个值,这个值用Array[Random(n)]表示,假设这个值为x,所在序号为i,则当这个值被取出后应该互换Array[n]与Array[i]的位置,即模拟纸条被抽出这个过程,将他取到的值与value比对,如果相等,则通知他中奖
    后面以此类推就可以了 
    直到最后第N个人抽完为止 不管什么时候通知中奖都是可以的,只要确保在第一个人登录前,随机数value已经取到,同时array这个数组已经重置好即可。
      

  10.   

    提示:
    在 Random 的构造器里面有另外一个方法Random(int seed);
    如果seed 相同, Random 会产生相同的随机序列哦!所以,如果seed 与日期相关,则能保证一天生成相同的序列!重复的几率吗? 我不知道喽!