天天看點

抛硬币與擲骰子

<b>1.</b><b>模拟抛硬币過程</b><b></b>

<b></b>

首先,試圖使用Java模拟一個抛硬币的過程。過程是使用一個随機函數随機的産生正與反,然後進行統計。

Coin.java

<b>package</b> zj.code.fun1;

<b>import</b> java.util.Random;

<b>public</b> <b>class</b> Coin {

    <b>private</b> <b>int</b> negative=0;

    <b>private</b> <b>int</b> positive=0;

    <b>private</b> <b>int</b> turn;

    <b>public</b> Coin(<b>int</b> turn){

       <b>this</b>.turn=turn;

    }

    <b>public</b> <b>void</b> tossing(){

       Random rand=<b>new</b> Random();

       <b>for</b>(<b>int</b> i=0;i&lt;turn;i++){

           getResult(rand.nextInt(2));

       }

       showResults();

    <b>public</b> <b>void</b> getResult(<b>int</b> i){

       <b>if</b>(i==0)

           negative++;

       <b>else</b> <b>if</b>(i==1)

           positive++;

       <b>else</b>

           System.err.println("Wrong result.");

    <b>public</b> <b>void</b> showResults(){

       System.out.println("Play turns:"+turn);

       System.out.println("Get negative:"+negative+","

              +(<b>float</b>)negative/(<b>float</b>)turn*100+"%");

       System.out.println("Get positive:"+positive+","

              +(<b>float</b>)positive/(<b>float</b>)turn*100+"%");

    <b>public</b> <b>static</b> <b>void</b> main(String[] args) {

       Coin co=<b>new</b> Coin(200);

        co.tossing();

}

成員變量negitive與positve分别統計出現正反的次數,turn表示模拟的輪次。方法tossing()裡面包含一個随機數0,1産生的過程,并将結果交給方法getResult()處理用于統計。最後通過方法showResults()可以顯示統計結果。

下面做個測試,main()方法中通過抛200次,可以得到類似結果,

Play turns:200

Get negative:105,52.499996%

Get positive:95,47.5%

<b>2.</b><b>過程提煉與抽象</b><b></b>

上面的代碼可以很好的模拟抛硬币的場景,但太過于具體,我試圖将其抽象化。

首先對于一個随機過程的示範,我想到它應該做3件事情,1提供随機産生器;2進行過程示範;3輸出結果。我把它定義到一個接口中。

Randomer.java  &lt;&lt;interface&gt;&gt;

<b>package</b> zj.code.fun2;

<b>public</b> <b>interface</b> Randomer {

    <b>public</b> Seeder getSeed();

    <b>public</b> <b>void</b> runToss();

    <b>public</b> <b>void</b> showResults();

而設想針對抛硬币的過程,我使用一個抽象類先部分給出設定随機數産生器與輪次的概念。當然對于過程示範(runToss)與輸出結果(showResults)是具體應用的東西,先不作考慮,繼續抽象它。

Tosser.java &lt;&lt;abstract class&gt;&gt;

<b>public</b> <b>abstract</b> <b>class</b> Tosser <b>implements</b> Randomer{

    <b>protected</b> Seeder curSeed;

    <b>protected</b> <b>int</b> turn;

    <b>public</b> Tosser(Seeder seed,<b>int</b> turn){

       curSeed=seed;

    <b>public</b> Seeder getSeed() {

       <b>return</b> curSeed;

    <b>public</b> <b>void</b> changeSeed(Seeder curSeed) {

       <b>this</b>.curSeed = curSeed;

    <b>public</b> <b>abstract</b> <b>void</b> runToss();

    <b>public</b> <b>abstract</b> <b>void</b> showResults();

好了,現在試圖提供一個随機數産生器,這個産生器設定為基于均等機率産生整型數。産生數的範圍range是可以通過具體應用設定的。

Seeder.java

<b>public</b> <b>class</b> Seeder {

    <b>private</b> <b>int</b> range;

    Random rand=<b>new</b> Random();

    <b>public</b> Seeder(<b>int</b> range){

       <b>this</b>.range=range;

    <b>public</b> <b>int</b> getValue(){

       <b>return</b> rand.nextInt(range);

<b>3.</b><b>抛硬币與擲骰子</b><b></b>

現在我用上面的結構,再次設計一個抛硬币的過程。它會繼承抽象類Tosser。

<b>public</b> <b>class</b> Coin <b>extends</b> Tosser{

    <b>public</b> Coin(<b>int</b> turn) {

       <b>super</b>(<b>new</b> Seeder(2), turn);

    @Override

    <b>public</b> <b>void</b> runToss() {

           <b>int</b> v=curSeed.getValue();

           <b>if</b>(v==0)

              negative++;

           <b>else</b> <b>if</b>(v==1)

              positive++;

           <b>else</b>

              System.err.println("Wrong result.");

    <b>public</b> <b>void</b> showResults() {

       co.runToss();

       co.showResults();

在構造子中,我設定了随機數構造器的range=2。并将runToss()與showResults()的具體邏輯補充完。在main()方法中,再次進行測試,輪次還是200。可以得到類似的結果為,

Get negative:99,49.5%

Get positive:101,50.5%

有了上面的結構,我不但可以抛硬币,我還可以擲骰子。

Dice.java

<b>public</b> <b>class</b> Dice <b>extends</b> Tosser{

    <b>private</b> <b>int</b> ONE=0;

    <b>private</b> <b>int</b> TWO=0;

    <b>private</b> <b>int</b> THREE=0;

    <b>private</b> <b>int</b> FOUR=0;

    <b>private</b> <b>int</b> FIVE=0;

    <b>private</b> <b>int</b> SIX=0;

    <b>public</b> Dice(<b>int</b> turn) {

       <b>super</b>(<b>new</b> Seeder(6), turn);

       <b>for</b> (<b>int</b> i = 0; i &lt; turn; i++) {

           <b>int</b> v = curSeed.getValue();

           <b>switch</b> (v) {

           <b>case</b> 0:

              ONE++;

              <b>break</b>;

           <b>case</b> 1:

              TWO++;

           <b>case</b> 2:

              THREE++;

           <b>case</b> 3:

              FOUR++;

           <b>case</b> 4:

              FIVE++;

           <b>case</b> 5:

              SIX++;

           <b>default</b>:

           }

       System.out.println("Get ONE:"+ONE+","

              +(<b>float</b>)ONE/(<b>float</b>)turn*100+"%");

       System.out.println("Get TWO:"+TWO+","

              +(<b>float</b>)TWO/(<b>float</b>)turn*100+"%");

       System.out.println("Get THREE:"+THREE+","

              +(<b>float</b>)THREE/(<b>float</b>)turn*100+"%");

       System.out.println("Get FOUR:"+FOUR+","

              +(<b>float</b>)FOUR/(<b>float</b>)turn*100+"%");

       System.out.println("Get FIVE:"+FIVE+","

              +(<b>float</b>)FIVE/(<b>float</b>)turn*100+"%");

       System.out.println("Get SIX:"+SIX+","

              +(<b>float</b>)SIX/(<b>float</b>)turn*100+"%");

       Dice di=<b>new</b> Dice(200);

       di.runToss();

       di.showResults();

同樣設定輪次為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%

<b>4. </b><b>既抛硬币又擲骰子</b><b></b>

現在既要抛硬币又要擲骰子,我在抽象基類Tosser中增加一個Simple Factory。

。。。

<b>public</b> <b>final</b> <b>static</b> Randomer getTosserInstance(String type, <b>int</b> turn) {

    <b>if</b> (type.equalsIgnoreCase("coin"))

       <b>return</b> <b>new</b> Coin(turn);

    <b>else</b> <b>if</b> (type.equalsIgnoreCase("dice"))

       <b>return</b> <b>new</b> Dice(turn);

    <b>else</b> {

       System.err.println("Wrong Type.");

       <b>return</b> <b>null</b>;

下面寫一個測試類。

TosserTest.java

<b>public</b> <b>class</b> TosserTest {

       Randomer rand=Tosser.getTosserInstance("coin", 100);

       rand.runToss();

       rand.showResults();

       System.out.println("==================");

       rand=Tosser.getTosserInstance("dice", 100);

既抛硬币又擲骰子,輪次都為100,可以得到類似測試結果為,

Play turns:100

Get negative:52,52.0%

Get positive:48,48.0%

==================

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%

 本文轉自zhangjunhd51CTO部落格,原文連結:http://blog.51cto.com/zhangjunhd/58934,如需轉載請自行聯系原作者