分享

抛硬币与掷骰子-,子孑-51CTO技术博客

 yao2007 2010-12-14
模拟抛硬币过程
首先,试图使用Java模拟一个抛硬币的过程。过程是使用一个随机函数随机的产生正与反,然后进行统计。
Coin.java
package zj.code.fun1;
import java.util.Random;
public class Coin {
    private int negative=0;
    private int positive=0;
    private int turn;
   
    public Coin(int turn){
       this.turn=turn;
    }
   
    public void tossing(){
       Random rand=new Random();
       for(int i=0;i<turn;i++){
           getResult(rand.nextInt(2));
       }
       showResults();
    }
   
    public void getResult(int i){
       if(i==0)
           negative++;
       else if(i==1)
           positive++;
       else
           System.err.println("Wrong result.");
    }
   
    public void showResults(){
       System.out.println("Play turns:"+turn);
       System.out.println("Get negative:"+negative+","
              +(float)negative/(float)turn*100+"%");
       System.out.println("Get positive:"+positive+","
              +(float)positive/(float)turn*100+"%");
    }
   
    public static void main(String[] args) {
       Coin co=new Coin(200);
        co.tossing();
    }
}
成员变量negitivepositve分别统计出现正反的次数,turn表示模拟的轮次。方法tossing()里面包含一个随机数01产生的过程,并将结果交给方法getResult()处理用于统计。最后通过方法showResults()可以显示统计结果。
下面做个测试,main()方法中通过抛200次,可以得到类似结果,
Play turns:200
Get negative:105,52.499996%
Get positive:95,47.5%
2.过程提炼与抽象
上面的代码可以很好的模拟抛硬币的场景,但太过于具体,我试图将其抽象化。
首先对于一个随机过程的演示,我想到它应该做3件事情,1提供随机产生器;2进行过程演示;3输出结果。我把它定义到一个接口中。
Randomer.java  <<interface>>
package zj.code.fun2;
public interface Randomer {
    public Seeder getSeed();
   
    public void runToss();
   
    public void showResults();
}
而设想针对抛硬币的过程,我使用一个抽象类先部分给出设定随机数产生器与轮次的概念。当然对于过程演示(runToss)与输出结果(showResults)是具体应用的东西,先不作考虑,继续抽象它。
Tosser.java <<abstract class>>
package zj.code.fun2;
public abstract class Tosser implements Randomer{
    protected Seeder curSeed;
    protected int turn;
 
    public Tosser(Seeder seed,int turn){
       curSeed=seed;
       this.turn=turn;
    }
   
    public Seeder getSeed() {
       return curSeed;
    }
 
    public void changeSeed(Seeder curSeed) {
       this.curSeed = curSeed;
    }
   
    public abstract void runToss();
   
    public abstract void showResults();
}
好了,现在试图提供一个随机数产生器,这个产生器设定为基于均等机率产生整型数。产生数的范围range是可以通过具体应用设定的。
Seeder.java
package zj.code.fun2;
import java.util.Random;
public class Seeder {
    private int range;
    Random rand=new Random();
   
    public Seeder(int range){
       this.range=range;
    }
 
    public int getValue(){
       return rand.nextInt(range);
    }
}
3.抛硬币与掷骰子
现在我用上面的结构,再次设计一个抛硬币的过程。它会继承抽象类Tosser
Coin.java
package zj.code.fun2;
 
public class Coin extends Tosser{
    private int negative=0;
    private int positive=0;
   
    public Coin(int turn) {
       super(new Seeder(2), turn);
    }
 
    @Override
    public void runToss() {
       for(int i=0;i<turn;i++){
           int v=curSeed.getValue();
           if(v==0)
              negative++;
           else if(v==1)
              positive++;
           else
              System.err.println("Wrong result.");
       }
    }
 
    @Override
    public void showResults() {
       System.out.println("Play turns:"+turn);
       System.out.println("Get negative:"+negative+","
              +(float)negative/(float)turn*100+"%");
       System.out.println("Get positive:"+positive+","
              +(float)positive/(float)turn*100+"%");
    }
   
    public static void main(String[] args) {
       Coin co=new Coin(200);
       co.runToss();
       co.showResults();
    }
}
在构造子中,我设定了随机数构造器的range=2。并将runToss()与showResults()的具体逻辑补充完。在main()方法中,再次进行测试,轮次还是200。可以得到类似的结果为,
Play turns:200
Get negative:99,49.5%
Get positive:101,50.5%
有了上面的结构,我不但可以抛硬币,我还可以掷骰子。
Dice.java
package zj.code.fun2;
public class Dice extends Tosser{
    private int ONE=0;
    private int TWO=0;
    private int THREE=0;
    private int FOUR=0;
    private int FIVE=0;
    private int SIX=0;
 
    public Dice(int turn) {
       super(new Seeder(6), turn);
    }
    @Override
    public void runToss() {
       for (int i = 0; i < turn; i++) {
           int v = curSeed.getValue();
           switch (v) {
           case 0:
              ONE++;
              break;
           case 1:
              TWO++;
              break;
           case 2:
              THREE++;
              break;
           case 3:
              FOUR++;
              break;
           case 4:
              FIVE++;
              break;
           case 5:
              SIX++;
              break;
           default:
              System.err.println("Wrong result.");
           }
       }
    }
 
    @Override
    public void showResults() {
       System.out.println("Play turns:"+turn);
       System.out.println("Get ONE:"+ONE+","
              +(float)ONE/(float)turn*100+"%");
       System.out.println("Get TWO:"+TWO+","
              +(float)TWO/(float)turn*100+"%");
       System.out.println("Get THREE:"+THREE+","
              +(float)THREE/(float)turn*100+"%");
       System.out.println("Get FOUR:"+FOUR+","
              +(float)FOUR/(float)turn*100+"%");
       System.out.println("Get FIVE:"+FIVE+","
              +(float)FIVE/(float)turn*100+"%");
       System.out.println("Get SIX:"+SIX+","
              +(float)SIX/(float)turn*100+"%");
    }
 
    public static void main(String[] args) {
       Dice di=new Dice(200);
       di.runToss();
       di.showResults();
    }
}
同样设定轮次为200,可以得到类似的测试结果,
Play turns:200
Get ONE:32,16.0%
Get TWO:29,14.5%
Get THREE:36,18.0%
Get FOUR:36,18.0%
Get FIVE:24,12.0%
Get SIX:43,21.5%
4. 既抛硬币又掷骰子
现在既要抛硬币又要掷骰子,我在抽象基类Tosser中增加一个Simple Factory
Tosser.java <<abstract class>>
。。。
public final static Randomer getTosserInstance(String type, int turn) {
    if (type.equalsIgnoreCase("coin"))
       return new Coin(turn);
    else if (type.equalsIgnoreCase("dice"))
       return new Dice(turn);
    else {
       System.err.println("Wrong Type.");
       return null;
    }
}
。。。
下面写一个测试类。
TosserTest.java
package zj.code.fun2;
public class TosserTest {
    public static void main(String[] args) {
       Randomer rand=Tosser.getTosserInstance("coin", 100);
       rand.runToss();
       rand.showResults();
       System.out.println("==================");
       rand=Tosser.getTosserInstance("dice", 100);
       rand.runToss();
       rand.showResults();
    }
}
既抛硬币又掷骰子,轮次都为100,可以得到类似测试结果为,
Play turns:100
Get negative:52,52.0%
Get positive:48,48.0%
==================
Play turns:100
Get ONE:17,17.0%
Get TWO:20,20.0%
Get THREE:17,17.0%
Get FOUR:18,18.0%
Get FIVE:12,12.0%
Get SIX:16,16.0%
 

本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/58934

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多