<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<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 <<interface>>
<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 <<abstract class>>
<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 < 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,如需轉載請自行聯系原作者