模擬拋硬幣過(guò)程首先,試圖使用Java模擬一個(gè)拋硬幣的過(guò)程。過(guò)程是使用一個(gè)隨機函數隨機的產(chǎn)生正與反,然后進(jìn)行統計。
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();
}
}
成員變量negitive與positve分別統計出現正反的次數,turn表示模擬的輪次。方法tossing()里面包含一個(gè)隨機數0,1產(chǎn)生的過(guò)程,并將結果交給方法getResult()處理用于統計。最后通過(guò)方法showResults()可以顯示統計結果。
下面做個(gè)測試,main()方法中通過(guò)拋200次,可以得到類(lèi)似結果,
Play turns:200
Get negative:105,52.499996%
Get positive:95,47.5%
2.過(guò)程提煉與抽象
上面的代碼可以很好的模擬拋硬幣的場(chǎng)景,但太過(guò)于具體,我試圖將其抽象化。
首先對于一個(gè)隨機過(guò)程的演示,我想到它應該做3件事情,1提供隨機產(chǎn)生器;2進(jìn)行過(guò)程演示;3輸出結果。我把它定義到一個(gè)接口中。
Randomer.java <<interface>>
package zj.code.fun2;
public interface Randomer {
public Seeder getSeed();
public void runToss();
public void showResults();
}
而設想針對拋硬幣的過(guò)程,我使用一個(gè)抽象類(lèi)先部分給出設定隨機數產(chǎn)生器與輪次的概念。當然對于過(guò)程演示(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();
}
好了,現在試圖提供一個(gè)隨機數產(chǎn)生器,這個(gè)產(chǎn)生器設定為基于均等機率產(chǎn)生整型數。產(chǎn)生數的范圍range是可以通過(guò)具體應用設定的。
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.拋硬幣與擲骰子
現在我用上面的結構,再次設計一個(gè)拋硬幣的過(guò)程。它會(huì )繼承抽象類(lèi)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()方法中,再次進(jìn)行測試,輪次還是200??梢缘玫筋?lèi)似的結果為,
Play turns:200
Get negative:99,49.5%
Get positive:101,50.5%
有了上面的結構,我不但可以?huà)佊矌?,我還可以擲骰子。
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,可以得到類(lèi)似的測試結果,
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. 既拋硬幣又擲骰子
現在既要拋硬幣又要擲骰子,我在抽象基類(lèi)Tosser中增加一個(gè)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;
}
}
。。。
下面寫(xiě)一個(gè)測試類(lèi)。
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,可以得到類(lèi)似測試結果為,
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%
本文出自 “
子 孑” 博客,請務(wù)必保留此出處
http://zhangjunhd.blog.51cto.com/113473/58934