# 反覆

## 複利投資

 Year Balance 0 \$10,000 1 \$10,500 2 \$11,025 3 \$11,576.25 4 \$12,155.06 5 \$12,762.82

## while 敘述

while (condition)
statement;

while (balance < targetBalance)
{
year++;
double interest = balance * rate / 100;
balance = balance + interest;
}

## File Investment.java

```
/**
A class to monitor the growth of an investment that
accumulates interest at a fixed annual rate
*/
public class Investment
{
/**
Constructs an Investment object from a starting balance and
interest rate.
@param aBalance the starting balanece
@param aRate the interest rate in percent
*/
public Investment(double aBalance, double aRate)
{
balance = aBalance;
rate = aRate;
years = 0;
}

/**
Keeps accumulating interest until a target balance has
been reached.
@param targetBalance the desired balance
*/
public void waitForBalance(double targetBalance)
{
while (balance < targetBalance)
{
years++;
double interest = balance * rate / 100;
balance = balance + interest;
}
}

/**
Gets the current investment balance.
@return the current balance
*/
public double getBalance()
{
return balance;
}

/**
Gets the number of years this investment has accumulated
interest.
@return the number of years since the start of the investment
*/
public int getYears()
{
return years;
}

private double balance;
private double rate;
private int years;
}

```

## File InvestmentTest.java

```
/**
This program computes how long it takes for an investment
to double.
*/
public class InvestmentTest
{
public static void main(String[] args)
{
final double INITIAL_BALANCE = 10000;
final double RATE = 5;
Investment invest = new Investment(INITIAL_BALANCE, RATE);
invest.waitForBalance(2 * INITIAL_BALANCE);
int years = invest.getYears();
System.out.println("The investment doubled after "
+ years + " years");
}
}

```

## while 迴圈流程圖 ## Syntax 6.1. while 敘述

 while (condition)    statement

### 例題:

 ```while (balance < targetBalance) {    year++;    double interest = balance * rate / 100;    balance = balance + interest; }```

## 常見錯誤: 無窮迴圈

while (year < 20)

balance = balance +
balance * rate / 100;
}

while (year > 0)

year++; // oops, meant --
. . .
}

## 常見錯誤: Off-by-1 錯誤

• year = 0;
while (balance < targetBalance)
{
year++;
double interest = balance * rate / 100;
balance = balance + interest;
}

System.out.println("Reached target after "
+ year + " years.");
• year 應從 0 或 1 開始?
• 測試應該用 <<=?

## 避免 Off-by-1 錯誤

• 使用簡單例子試算:
target balance = \$20,000, interest rate 50%
after one year: balance = \$15,000
after two years: balance = \$22,500
因此: year 必須從 0 開始
• interest rate 100%
after one year: balance = \$20,000
迴圈應該停止
因此: 必須使用 <
• 動腦筋, 不要亂猜

## do 敘述

`do    statementwhile (condition);`

`double value;do{   String input = JOptionPane.showInputDialog(      "Please enter a positive number");   value = Integer.parseInt(input);}while (input <= 0);`

## do 迴圈流程圖 ## for 敘述

• for (initialization; condition; update)
statement
• (
• Example:
for (int i = 1; i <= n; i++)
{
double interest = balance * rate / 100;
balance = balance + interest;
}
• Equivalent to
initialization;
while (condition)
{ statement; update; }

## for 迴圈流程圖 ## File Investment.java

```
/**
A class to monitor the growth of an investment that
accumulates interest at a fixed annual rate
*/
public class Investment
{
/**
Constructs an Investment object from a starting balance and
interest rate.
@param aBalance the starting balanece
@param aRate the interest rate in percent
*/
public Investment(double aBalance, double aRate)
{
balance = aBalance;
rate = aRate;
years = 0;
}

/**
Keeps accumulating interest until a target balance has
been reached.
@param targetBalance the desired balance
*/
public void waitForBalance(double targetBalance)
{
while (balance < targetBalance)
{
years++;
double interest = balance * rate / 100;
balance = balance + interest;
}
}

/**
Keeps accumulating interest for a given number of years.
@param n the number of years
*/
public void waitYears(int n)
{
for (int i = 1; i <= n; i++)
{
double interest = balance * rate / 100;
balance = balance + interest;
}
years = years + n;
}

/**
Gets the current investment balance.
@return the current balance
*/
public double getBalance()
{
return balance;
}

/**
Gets the number of years this investment has accumulated
interest.
@return the number of years since the start of the investment
*/
public int getYears()
{
return years;
}

private double balance;
private double rate;
private int years;
}

```

## File InvestmentTest.java

```
/**
This program computes how much an investment grows in
a given number of years.
*/
public class InvestmentTest
{
public static void main(String[] args)
{
final double INITIAL_BALANCE = 10000;
final double RATE = 5;
final int YEARS = 20;
Investment invest = new Investment(INITIAL_BALANCE, RATE);
invest.waitYears(YEARS);
double balance = invest.getBalance();
System.out.println("The balance after " + YEARS +
" years is " + balance);
}
}

```

## Syntax 6.2. for 敘述

 for (initialization; condition; update )    statement

### 例題:

 for (int i = 1; i <= n; i++) {    double interest = balance * rate / 100;    balance = balance + interest; }

### 用途:

To execute an initialization, then keep executing a statement and updating an expression while a condition is true

## 常見錯誤: Semicolons

• 多用了一個半冒號(semicolon)
sum = 0;
for (i = 1; i <= 10; i++);
sum = sum + i;
// sum=11 System.out.println(sum);
• 漏用了一個半冒號
for (i = 1; i <= 10; sum = sum + i++)
System.out.println(sum);

## 6.3 多層迴圈

• 題目: 列出三角形圖型
[]
[][]
[][][]
[][][][]
• 先用一迴圈處理各列
for (int i = 1; i <= n; i++)
{
// make triangle row
}
• 三角形圖型中每一列再用另一迴圈處理
for (int j = 1; j <= i; j++)
r = r + "[]";
r = r + "\n";
• 將後一迴圈套在前一迴圈內 => 多層迴圈

## File Triangle.java

```
/**
This class describes triangle objects that can be displayed
as shapes like this:
[]
[][]
[][][]
*/
public class Triangle
{
/**
Constructs a triangle.
@param aWidth the number of [] in the last row of the triangle.
*/
public Triangle(int aWidth)
{
width = aWidth;
}

/**
Computes a string representing the triangle.
@return a string consisting of [] and newline characters
*/
public String toString()
{
String r = "";
for (int i = 1; i <= width; i++)
{
// make triangle row
for (int j = 1; j <= i; j++)
r = r + "[]";
r = r + "\n";
}
return r;
}

private int width;
}

```

## File TriangleTest.java

```
/**
This program tests the Triangle class.
*/
public class TriangleTest
{
public static void main(String[] args)
{
Triangle small = new Triangle(3);
System.out.println(small.toString());

Triangle large = new Triangle(15);
System.out.println(large.toString());
}
}

```

## 6.4 處理輸入

### 6.4.1 讀取輸入數值

`boolean done = false;while (!done){   String input = read input;   if (end of input indicated)      done = true;   else   {      process input   }}`

### File DataSet.java

```
/**
Computes the average of a set of data values.
*/
public class DataSet
{
/**
Constructs an empty data set.
*/
public DataSet()
{
sum = 0;
count = 0;
maximum = 0;
}

/**
Adds a data value to the data set
@param x a data value
*/
{
sum = sum + x;
if (count == 0 || maximum < x) maximum = x;
count++;
}

/**
Gets the average of the added data.
@return the average or 0 if no data has been added
*/
public double getAverage()
{
if (count == 0) return 0;
else return sum / count;
}

/**
Gets the largest of the added data.
@return the maximum or 0 if no data has been added
*/
public double getMaximum()
{
return maximum;
}

private double sum;
private double maximum;
private int count;
}

```

### File InputTest.java

```
import javax.swing.JOptionPane;

/**
This program computes the average and maximum of a set
of input values.
*/
public class InputTest
{
public static void main(String[] args)
{
DataSet data = new DataSet();

boolean done = false;
while (!done)
{
String input = JOptionPane.showInputDialog("Enter value, Cancel to quit");
if (input == null)
done = true;
else
{
double x = Double.parseDouble(input);
}
}

System.out.println("Average = " + data.getAverage());
System.out.println("Maximum = " + data.getMaximum());
System.exit(0);
}
}

```

### 6.4.2 String Tokenization

• StringTokenizer 將一字串分割成許多語彙單元(token)
• 空白符號(空白, tab, 或換行)預設為語彙單元的分界符號(delimiter)
• "4.3  7  -2" 分割成三個語彙單元:
"4.3", "7", "-2"
• 用法
`StringTokenizer tokenizer    = new StringTokenizer();while (tokenizer.hasMoreTokens()){     String token = tokenizer.nextToken();   process token}`

### File InputTest.java

```
import java.util.StringTokenizer;
import javax.swing.JOptionPane;

/**
This program computes the average and maximum of a set
of input values that are entered on a single line.
*/
public class InputTest
{
public static void main(String[] args)
{
DataSet data = new DataSet();

String input = JOptionPane.showInputDialog("Enter values:");
StringTokenizer tokenizer = new StringTokenizer(input);
while (tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();

double x = Double.parseDouble(token);
}

System.out.println("Average = " + data.getAverage());
System.out.println("Maximum = " + data.getMaximum());
System.exit(0);
}
}

```

### 6.4.3 造訪字串中的字元

• s.charAt(i) 是字串 s 的第 i 個字元
• 用法:
`for (int i = 0; i < s.length(); i++){   char ch = s.charAt(i);   process ch}`
• 例題: 數數字串中言母音(vowel)的個數
`int vowelCount = 0;String vowels = "aeiouy";for (int i = 0; i < s.length(); i++){   char ch = s.charAt(i);   if (vowels.indexOf(ch) >= 0)      vowelCount++;}`
• s.indexOf(ch) 是字元 ch 在字串 s 中第一次出現的位置, 假如 ch 不在 s 中則為 -1

## 6.5 亂數(Random Number)

• 亂數產生器(generator)用法
Random generator = new Random();
int n = generator.nextInt(a);
//
0 <= n < a
double x = generator.nextDouble();
//
0 <= x < 1
• 擲骰子(1 和 6 之間的亂數)
int d = 1 + generator.nextInt(6);

### File Die.java

```
import java.util.Random;

/**
This class models a die that, when cast, lands on a random
face.
*/
public class Die
{
/**
Constructs a die with a given number of sides
@param s the number of sides, e.g. 6 for a normal die
*/
public Die(int s)
{
sides = s;
generator = new Random();
}

/**
Simulates a throw of the die
@return the face of the die
*/
public int cast()
{
return 1 + generator.nextInt(sides);
}

private Random generator;
private int sides;
}

```

### File DieTest.java

```
/**
This program simulates casting a die ten times.
*/
public class DieTest
{
public static void main(String[] args)
{
Die d = new Die(6);
final int TRIES = 10;
for (int i = 1; i <= TRIES; i++)
{
int n = d.cast();
System.out.print(n + " ");
}
System.out.println();
}
}

```

### Buffon Needle Experiment ### Needle Position

• Needle length = 1, distance between lines = 2
• Generate random ylow  between 0 and 2
• Generate random angle a between 0 and 180 degrees
• yhigh  = ylow  + sin( a)
• Hit if yhigh >= 2 ### File Needle.java

```
import java.util.Random;

/**
This class simulates a needle in the Buffon needle experiment.
*/
public class Needle
{
/**
Constructs a needle.
*/
public Needle()
{
hits = 0;
tries = 0;
generator = new Random();
}

/**
Drops the needle on the grid of lines and
remembers whether the needle hit a line.
*/
public void drop()
{
double ylow = 2 * generator.nextDouble();
double angle = 180 * generator.nextDouble();

// compute high point of needle

double yhigh = ylow + Math.sin(Math.toRadians(angle));
if (yhigh >= 2) hits++;
tries++;
}

/**
Gets the number of times the needle hit a line.
@return the hit count
*/
public int getHits()
{
return hits;
}

/**
Gets the total number of times the needle was dropped.
@return the try count
*/
public int getTries()
{
return tries;
}

private Random generator;
private int hits;
private int tries;
}

```

### File NeedleTest.java

```
/**
This program simulates the Buffon needle experiment
and prints the resulting approximations of pi.
*/
public class NeedleTest
{
public static void main(String[] args)
{
Needle n = new Needle();
final int TRIES1 = 10000;
final int TRIES2 = 100000;

for (int i = 1; i <= TRIES1; i++)
n.drop();
System.out.println("Tries / Hits = "
+ (double)n.getTries() / n.getHits());

for (int i = TRIES1 + 1; i <= TRIES2; i++)
n.drop();
System.out.println("Tries / Hits = "
+ (double)n.getTries() / n.getHits());
}
}

```