Transcript 第6 章(2)

1
6.9 Case Study: Random-Number
Generation
• Random-number (隨機數字) generation 有兩個方
式:
– static method random from class Math
• Math.random( )
• Returns doubles in the range 0.0  x < 1.0
– Thru object of class Random from package java.util
• Can produce pseudorandom boolean, byte, float, double,
int, long and Gaussian values
– 如 nextInt()、nextDouble() 等方法(請參見範例)
• Is seeded with the current time of day to generate different
sequences of numbers each time the program executes,種子數
用來決定第 1 個隨機數字的值,第 2個隨機數字的值由第 1個
隨機數字的值決定,之後的值都由前一個值決定
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.7: RandomIntegers.java
2
// Shifted and scaled random integers.
3
import java.util.Random; // program uses class Random
4
5
public class RandomIntegers
6
{
2
Outline
Import class Random from the java.util package
7
public static void main( String args[] )
8
{
Create a Random object
9
Random randomNumbers = new Random(); // random number generator
10
int face; // stores each random integer generated
RandomIntegers
.java
(1 of 2)
11
12
// loop 20 times
13
for ( int counter = 1; counter <= 20; counter++ )
14
{
15
// pick random integer from 1 to 6
16
face = 1 + randomNumbers.nextInt( 6 );
Generate a random die roll
17
18
System.out.printf( "%d
", face ); // display generated value
19
20
// if counter is divisible by 5, start a new line of output
21
if ( counter % 5 == 0 )
22
23
24
System.out.println();
} // end for
} // end main
25 } // end class RandomIntegers
 1992-2007 Pearson Education, Inc. All rights reserved.
1
5
4
3
6
1
6
6
5
2
4
1
5
2
3
4
3
6
4
6
4
5
2
2
6
5
2
2
2
1
2
6
3
2
2
6
2
6
3
1
4
Outline
Two different sets of results
containing integers in the range 1-6
RandomIntegers
.java
(2 of 2)
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.8: RollDie.java
2
3
// Roll a six-sided die 6000 times.
import java.util.Random;
4
Outline
4
5
6
7
8
9
10
11
12
13
14
15
16
public class RollDie
Import class
{
public static void main( String args[] )
Random from the java.util package
RollDie.java
{
Random randomNumbers = new Random(); // random number generator
int
int
int
int
int
int
frequency1
frequency2
frequency3
frequency4
frequency5
frequency6
=
=
=
=
=
=
0;
0;
0;
0;
0;
0;
//
//
//
//
//
//
maintains count of 1s rolled
count of 2s rolled
count of 3s rolled
count of 4s rolled
count of 5s rolled
count of 6s rolled
(1 of 2)
Create a Random object
Declare frequency counters
17
 1992-2007 Pearson Education, Inc. All rights reserved.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
int face; // stores most recently rolled value
5
// summarize results of 6000 rolls of a die
Iterate 6000
for ( int roll = 1; roll <= 6000; roll++ )
{
face = 1 + randomNumbers.nextInt( 6 ); // number from 1 to 6
times
Outline
RollDie.java
// determine roll value 1-6 and increment appropriate counter
switch ( face )
Generate a random
(2 ofdie
2)
{
case 1:
++frequency1; // increment the 1s counter
break;
switch based on the die roll
case 2:
++frequency2; // increment the 2s counter
break;
case 3:
++frequency3; // increment the 3s counter
break;
case 4:
++frequency4; // increment the 4s counter
break;
case 5:
++frequency5; // increment the 5s counter
break;
case 6:
++frequency6; // increment the 6s counter
break; // optional at end of switch
} // end switch
} // end for
roll
 1992-2007 Pearson Education, Inc. All rights reserved.
49
System.out.println( "Face\tFrequency" ); // output headers
50
System.out.printf( "1\t%d\n2\t%d\n3\t%d\n4\t%d\n5\t%d\n6\t%d\n",
51
frequency1, frequency2, frequency3, frequency4,
52
frequency5, frequency6 );
53
6
Outline
} // end main
54 } // end class RollDie
Face
1
2
3
4
5
6
Frequency
982
1001
1015
1005
1009
988
Face
1
2
3
4
5
6
Frequency
1029
994
1017
1007
972
981
Display die roll frequencies
RollDie.java
(3 of 3)
 1992-2007 Pearson Education, Inc. All rights reserved.
7
6.9.1 Generalized Scaling and Shifting of
Random Numbers
• To generate a random number in certain sequence or
range (有規律的數字序列才可以)
– Use the expression
shiftingValue +
differenceBetweenValues *randomNumbers.nextInt( scalingFactor )
where:
• shiftingValue (初值) is the first number in the desired range of
values
• differenceBetweenValues (差值) represents the difference between
consecutive numbers in the sequence
• scalingFactor (個數) specifies how many numbers are in the range
– 例如:介於 3 到 10 間的整數
• 3 + 1 * randomNumbers.nextInt(8)
– 例如:由 7, 14, 21, 28, 35 間隨機產生
• 7 + 7 * randomNumbers.nextInt(5)
– 那怎麼處理沒有規律的數字序列,例如 3, 5, 13, 15,
37
用33,
switch
 1992-2007 Pearson Education, Inc. All rights reserved.
8
練習
•
以 random number 表示以下範圍的整數:
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)
(i)
1n2
1 + r1.nextInt(2)
1  n  100 1 + r1.nextInt(100)
0n9
r1.nextInt(10)
1000  n  1112 1000 + r1.nextInt(13)
-1  n  1
-1 + r1.nextInt(3)
-3  n  11
-3 + r1.nextInt(15)
2, 4, 6, 8, 10
2+2*r1.nextInt(5)
3, 5, 7, 9, 11
3+2*r1.nextInt(5)
6, 10, 14, 18, 22
6 + 4 * r1.nextInt(5)
• 四捨五入到整數
Math.round( x ) or Math.floor( x + 0.5)
• 四捨五入到小數點後第 1 位,請類推四捨五入到小數點後第 n 位
Math.floor( 10 * (x + 0.05) ) / 10.0
 1992-2007 Pearson Education, Inc. All rights reserved.
9
6.9.2 Random-Number Repeatability for
Testing and Debugging
• To get a Random object to generate the same
sequence of random numbers every time the
program executes, seed it with a certain value
– When creating the Random object:
Random randomNumbers = new Random( seedValue );
– Use the setSeed method:
randomNumbers.setSeed( seedValue );
– seedValue should be an argument of type long
 1992-2007 Pearson Education, Inc. All rights reserved.
10
Error-Prevention Tip 6.2
While a program is under development(還在開發中), create the
Random object with a specific seed value to produce a repeatable
(可重覆的) sequence of random numbers each time the program
executes.
If a logic error occurs, fix the error and test the program again
with the same seed value-this allows you to reconstruct the same
sequence of random numbers that caused the error.
Once the logic errors have been removed, create the Random
object without using a seed value, causing the Random object to
generate a new sequence of random numbers each time the
program executes.
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.9: Craps.java
2
// Craps class simulates the dice game craps.
3
import java.util.Random;
11
Outline
Import class Random from the java.util package
4
5
public class Craps
6
{
Craps.java
7
// create random number generator for use in method rollDice
8
private Random randomNumbers = new Random();
9
Create a Random object
10
// enumeration with constants that represent the game status
11
private enum Status { CONTINUE, WON, LOST };
12
13
// constants that represent common rolls of the dice
14
private final static int SNAKE_EYES = 2;
15
private final static int TREY = 3;
16
private final static int SEVEN = 7;
17
private final static int YO_LEVEN = 11;
18
19
private final static int BOX_CARS = 12;
(1 of 4)
Declare an enumeration
Declare constants
 1992-2007 Pearson Education, Inc. All rights reserved.
20
// plays one game of craps
21
public void play()
22
{
12
Outline
23
int myPoint = 0; // point if no win or loss on first roll
24
Status gameStatus; // can contain CONTINUE, WON or LOST
Craps.java
25
26
int sumOfDice = rollDice(); // first roll of the dice
(2 of 4)
27
28
// determine game status and point based on first roll
29
switch ( sumOfDice )
30
{
31
case SEVEN: // win with 7 on first roll
32
case YO_LEVEN: // win with 11 on first roll
33
gameStatus = Status.WON;
34
break;
35
case SNAKE_EYES: // lose with 2 on first roll
36
case TREY: // lose with 3 on first roll
37
case BOX_CARS: // lose with 12 on first roll
38
gameStatus = Status.LOST;
39
break;
40
Player wins with a roll of 7 or 11
Player loses with a roll of 2, 3 or 12
default: // did not win or lose, so remember point
41
gameStatus = Status.CONTINUE; // game is not over
42
myPoint = sumOfDice; // remember the point
43
System.out.printf( "Point is %d\n", myPoint );
44
break; // optional at end of switch
45
46
Call rollDice method
Set and display the point
} // end switch
 1992-2007 Pearson Education, Inc. All rights reserved.
47
// while game is not complete
48
while ( gameStatus == Status.CONTINUE ) // not WON or LOST
49
{
50
13
Outline
Call rollDice method
sumOfDice = rollDice(); // roll dice again
51
Craps.java
52
// determine game status
53
if ( sumOfDice == myPoint ) // win by making point
54
55
gameStatus = Status.WON;
else
56
if ( sumOfDice == SEVEN ) // lose by rolling 7 before point
57
58
(3 of 4)
Player wins by making the point
gameStatus = Status.LOST;
} // end while
Player loses by rolling 7
59
60
// display won or lost message
61
if ( gameStatus == Status.WON )
62
63
64
65
Display outcome
System.out.println( "Player wins" );
else
System.out.println( "Player loses" );
} // end method play
66
 1992-2007 Pearson Education, Inc. All rights reserved.
67
// roll dice, calculate sum and display results
68
public int rollDice()
69
{
14
Declare rollDice method
Outline
70
// pick random die values
71
int die1 = 1 + randomNumbers.nextInt( 6 ); // first die roll
72
int die2 = 1 + randomNumbers.nextInt( 6 ); // second die roll
Craps.java
int sum = die1 + die2; // sum of die values
(4 of 4)
73
74
75
76
// display results of this roll
77
System.out.printf( "Player rolled %d + %d = %d\n",
78
Generate two dice
rolls
die1, die2, sum );
79
80
81
return sum; // return sum of dice
} // end method rollDice
82 } // end class Craps
Display dice rolls and their
sum
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.10: CrapsTest.java
2
// Application to test class Craps.
3
4
public class CrapsTest
5
{
6
public static void main( String args[] )
7
{
8
Craps game = new Craps();
9
game.play(); // play one game of craps
10
15
Outline
CrapsTest.java
(1 of 2)
} // end main
11 } // end class CrapsTest
Player rolled 5 + 6 = 11
Player wins
Player rolled 1 + 2 = 3
Player loses
Player rolled
Point is 9
Player rolled
Player rolled
Player rolled
Player rolled
Player wins
5 + 4 = 9
Player rolled
Point is 8
Player rolled
Player rolled
Player rolled
Player loses
2 + 6 = 8
2
2
4
3
+
+
+
+
2
6
2
6
=
=
=
=
4
8
6
9
5 + 1 = 6
2 + 1 = 3
1 + 6 = 7
 1992-2007 Pearson Education, Inc. All rights reserved.
16
6.10 Case Study: A Game of Chance
(Introducing Enumerations)
• Enumerations
– Programmer-declared types consisting of sets of constants
– enum keyword
– A type name (e.g. Status)
– Enumeration constants (e.g. WON, LOST and CONTINUE)
• cannot be compared against ints
 1992-2007 Pearson Education, Inc. All rights reserved.
17
Good Programming Practice 6.3, 6.4
Use only uppercase letters in the names of
constants. This makes the constants stand out
in a program and reminds the programmer
that enumeration constants are not variables.
Using enumeration constants (like Status.WON,
Status.LOST and Status.CONTINUE) rather than
literal integer values (such as 0, 1 and 2) can make
programs easier to read and maintain.
 1992-2007 Pearson Education, Inc. All rights reserved.
18
6.11 Scope of Declarations (宣告的有效範圍)
• Basic scope rules
– Scope of a parameter declaration (方法參數) is the body of
the method in which appears
– Scope of a local-variable (區域變數) declaration is from the
point of declaration to the end of that block (區塊)
– Scope of a local-variable declaration in the initialization
section of a for header is the rest of the for header and
the body of the for statement
– Scope of a method or field of a class is the entire body of
the class
 1992-2007 Pearson Education, Inc. All rights reserved.
19
6.11 Scope of Declarations (Cont.)
• Shadowing (覆蓋)
– A field is shadowed (or hidden,被覆蓋、被隱藏,不能用)
if a local variable or parameter has the same name as the
field
• This lasts until the local variable or parameter goes out of
scope
 1992-2007 Pearson Education, Inc. All rights reserved.
20
Common Programming Error 6.10
A compilation error occurs when a local variable
is declared more than once in a method.
Use different names for fields and local
variables to help prevent subtle logic errors that
occur when a method is called and a local
variable of the method shadows a field of the
same name in the class. (範例 6-11)
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.11: Scope.java
2
// Scope class demonstrates field and local variable scopes.
21
Outline
3
4
public class Scope
5
{
6
// field that is accessible to all methods of this class
7
private int x = 1;
Scope.java
(1 of 2)
8
9
// method begin creates and initializes local variable x
10
// and calls methods useLocalVariable and useField
11
public void begin()
12
{
13
Shadows field x
int x = 5; // method's local variable x shadows field x
14
15
System.out.printf( "local x in method begin is %d\n", x );
Display value of
local variable x
16
17
useLocalVariable(); // useLocalVariable has local x
18
useField(); // useField uses class Scope's field x
19
useLocalVariable(); // useLocalVariable reinitializes local x
20
21
useField(); // class Scope's field x retains its value
 1992-2007 Pearson Education, Inc. All rights reserved.
22
23
System.out.printf( "\nlocal x in method begin is %d\n", x );
22
Outline
} // end method begin
24
25
// create and initialize local variable x during each call
26
public void useLocalVariable()
27
{
28
Shadows field x
int x = 25; // initialized each time useLocalVariable is called
(2 of 2)
29
30
System.out.printf(
31
"\nlocal x on entering method useLocalVariable is %d\n", x );
32
++x; // modifies this method's local variable x
33
System.out.printf(
34
35
Scope.java
"local x before exiting method useLocalVariable is %d\n", x );
Display value of
local variable x
} // end method useLocalVariable
36
37
// modify class Scope's field x during each call
38
public void useField()
39
{
40
41
System.out.printf(
"\nfield x on entering method useField is %d\n", x );
42
x *= 10; // modifies class Scope's field x
43
System.out.printf(
44
45
Display value of
field x
"field x before exiting method useField is %d\n", x );
} // end method useField
46 } // end class Scope
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.12: ScopeTest.java
2
// Application to test class Scope.
23
Outline
3
4
public class ScopeTest
5
{
6
// application starting point
7
public static void main( String args[] )
8
{
9
Scope testScope = new Scope();
10
testScope.begin();
11
ScopeTest.java
} // end main
12 } // end class ScopeTest
local x in method begin is 5
local x on entering method useLocalVariable is 25
local x before exiting method useLocalVariable is 26
field x on entering method useField is 1
field x before exiting method useField is 10
local x on entering method useLocalVariable is 25
local x before exiting method useLocalVariable is 26
field x on entering method useField is 10
field x before exiting method useField is 100
local x in method begin is 5
 1992-2007 Pearson Education, Inc. All rights reserved.
24
練習
1. 請問 fig06_09_10 中的 Craps.java 程式裡,以下
變數或方法之有效範圍(結果請以 “第 x 列 – 第 y 列”
表示):
變數 randomNumbers
變數 die1
方法 rollDice
方法 play
變數 sumOfDice
2. 請寫 1 個 boolean isPrime(int x) 方法,參數 x 為一正整
數。於測試程式中,請使用者輸入一個正整數 n,以迴圈呼叫
isPrime(2)、… 、isPrime(n) ,以測試由 2 至 n 是否為質
數,並將 2 至 n 中是質數的數字印出來
 1992-2007 Pearson Education, Inc. All rights reserved.
25
6.12 Method Overloading
• Method overloading (多載)
– Multiple methods with the same name, but different types,
number or order of parameters in their parameter lists
– Compiler decides which method is being called by
matching the method call’s argument list to one of the
overloaded methods’ parameter lists
• A method’s name and number, type and order of its
parameters form its signature
– Differences in return type are irrelevant (不相干) in
method overloading
• Overloaded methods can have different return types
• Methods with different return types but the same signature
cause a compilation error
 1992-2007 Pearson Education, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Fig. 6.13: MethodOverload.java
// Overloaded method declarations.
26
Outline
public class MethodOverload
Correctly calls the
{
// test overloaded square methods
public void testOverloadedMethods()
{
System.out.printf( "Square of integer 7 is %d\n", square( 7 ) );
System.out.printf( "Square of double 7.5 is %f\n", square( 7.5 ) );
} // end method testOverloadedMethods
// square method with int argument
Correctly calls the
public int square( int intValue )
{
System.out.printf( "\nCalled square with int argument: %d\n",
intValue );
return intValue * intValue;
} // end method square with int argument
“square of int” method
MethodOverload
.java
“square of double” method
Declaring the “square of
int” method
// square method with double argument
public double square( double doubleValue )
{
System.out.printf( "\nCalled square with double argument: %f\n",
doubleValue );
return doubleValue * doubleValue;
} // end method square with double argument
} // end class MethodOverload
Declaring the “square of
double” method
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.14: MethodOverloadTest.java
2
// Application to test class MethodOverload.
3
4
public class MethodOverloadTest
5
{
6
public static void main( String args[] )
7
{
8
27
Outline
MethodOverload methodOverload = new MethodOverload();
MethodOverloadTest
.java
9
methodOverload.testOverloadedMethods();
10
} // end main
11 } // end class MethodOverloadTest
Called square with int argument: 7
Square of integer 7 is 49
Called square with double argument: 7.500000
Square of double 7.5 is 56.250000
 1992-2007 Pearson Education, Inc. All rights reserved.
1
// Fig. 6.15: MethodOverloadError.java
2
// Overloaded methods with identical signatures
3
4
5
// cause compilation errors, even if return types are different.
6
{
7
8
9
28
Outline
public class MethodOverloadError
MethodOverload
// declaration of method square with int argument
public int square( int x )
{
Error.java
return x * x;
10
11
12
}
13
14
15
16
// second declaration of method square with int argument
// causes compilation error even though return types are different
public double square( int y )
{
Same method signature
17
return y * y;
18
}
19 } // end class MethodOverloadError
MethodOverloadError.java:15: square(int) is already defined in
MethodOverloadError
public double square( int y )
^
Compilation
1 error
error
 1992-2007 Pearson Education, Inc. All rights reserved.
29
Common Programming Error 6.11
Declaring overloaded methods with identical
parameter lists is a compilation error
regardless of whether the return types are
different.
 1992-2007 Pearson Education, Inc. All rights reserved.
練習
30
Ex6_17: 請寫出以下方法的內容:
fillSquare( int size, char fillCharacter )
這方法會畫出以 fillCharacter 填滿之 size * size 的正方形,不需回傳任何
值。並請使用者輸入 size 及 fillCharacter 後,呼叫此方法加以測試。
Ex6_22: 一個數字被稱為 完美數字 (perfect number ) 如果其因數加總的和正
好等於該數,例如:6 的因數有 1、2、3 ,而 6 = 1 + 2 +3,所以 6 是一個
perfect number。請寫以下方法的內容:
String perfect (int n)
這方法會檢查 n 是否為完美數字,如果是則傳回 n 的所有因數的字串,否則
傳回 null 物件。再請寫一應用程式列印出 2 至 1000 中的完美數字,列印時
請將其因數一併印出,以利檢驗。
 1992-2007 Pearson Education, Inc. All rights reserved.
31
練習
Ex6_27:乘法測驗
Ex6_30: 猜數字遊戲 (Guess)
請寫一程式來玩猜數字遊戲 ,每次遊戲程式會產
生一個介於 1 到 100 的正整數,請使用者持續
猜到那個數字為止。
如果使用者猜的答案太大,則回應 “太大”;並請使用者
繼續猜。
2. 如果使用者猜的答案太小,則回應 “太小”;並請使用者
繼續猜。
3. 如果使用者猜對了,則回應 “Bingo”,並問使用者
”要不要再玩?”。
3.1 使用者回答 ”要” 的話,就開始下一新回合,
3.2 使用者回答 ”不要” 的話,就結束程式。
 1992-2007 Pearson Education, Inc. All rights reserved.
(1) Guess2 類別中需含一個 正整數 實體變數 answer
練習 Ex6_30(2) Guess2 類別中要使用 enum 設計一個使用者自訂的資料型態
RESULT 用來設定使用者猜的數字跟答案比較的結果
太大 (TOO_BIG)、
太小 (TOO_SMALL)、
答對 (BINGO)
(3) Guess2 類別的方法:
1. RESULT check(int n):
比較使用者猜的數字跟答案,可能傳回
RESULT.TOO_BIG, RESULT.TOO_SMALL, 或 RESULT.BINGO
2. void newGame( ): 代表使用者的新一回合,須完成以下動作
先將 answer 設定為一個隨機變數,
請使用者輸入一個數字 userGuess,
呼叫 check(userGuess),
檢查結果直到 BINGO 為止,如果不是 BINGO,持續
請使用者輸入一個數字 userGuess,
呼叫 check(userGuess)
問使用者要不要再玩,
要的話,呼叫 newGame() 以開啟下一回合
(4) 另外寫一 PlayGuess 類別來測試 Guess2 類別,其 main 方法需
生成一個 Guess2 物件,並呼叫該物件的 newGame() 方法。
32
 1992-2007 Pearson Education, Inc. All rights reserved.
33
重點提示
if (含 logical operators)
while
for
switch
break, continue
物件導向 (方法、實體變數、static)
Math, Random
enum
overload
argument promotion, type casting
precedence and associativity of operators
 1992-2007 Pearson Education, Inc. All rights reserved.