Java 程式設計()  第 二章 一維陣列  上一頁    

 

2-5 專題研討

內容:

  • 2-5-1 範例研討:紀錄最近 30 天收盤價

  • 2-5-2 自我挑戰:股票走勢分析系統

  • 2-5-3 自我挑戰:印製國字收據

  • 2-5-4 自我挑戰:統計滿意度平均值

2-5-1 範例研討:記錄最近 30 天收盤價

A)程式功能:Ex2_6.java

請設計一套程式,除了可以隨時顯示最近 30 天的收盤價之外,也可以輸入每天的收盤價如何。注意,每天輸入收盤價之後,整個陣列會隨著移動,它會拋棄 30  天前收盤價,並擠入最近的收盤價(如圖 2-6),我們希望操作環境如下:

== 歡迎光臨 股票走勢分析系統 ==

(1) 列印 30 日歷史收盤價

(2) 登錄當日收盤價

(3) 離開系統

         請輸入工作選項 =>1

 

== 列印最近 30 日股價==

78.00  72.00  61.00  56.00  87.00 

66.00  74.00  88.00  76.00  58.00 

65.00  57.00  90.00  78.00  67.00 

89.00  56.00  77.00  56.00  87.00 

67.00  80.00  77.00  86.00  67.00 

75.00  86.00  98.00  88.00  78.00 

 

== 歡迎光臨 股票走勢分析系統 ==

(1) 列印 30 日歷史收盤價

(2) 登錄當日收盤價

(3) 離開系統

         請輸入工作選項 =>2

請登錄當日收盤股價 =>90

== 歡迎光臨 股票走勢分析系統 ==

(1) 列印 30 日歷史收盤價

(2) 登錄當日收盤價

(3) 離開系統

         請輸入工作選項 =>1

 

== 列印最近 30 日股價==

90.00  78.00  72.00  61.00  56.00 

87.00  66.00  74.00  88.00  76.00 

58.00  65.00  57.00  90.00  78.00 

67.00  89.00  56.00  77.00  56.00 

87.00  67.00  80.00  77.00  86.00 

67.00  75.00  86.00  98.00  88.00 

 

== 歡迎光臨 股票走勢分析系統 ==

(1) 列印 30 日歷史收盤價

(2) 登錄當日收盤價

(3) 離開系統

         請輸入工作選項 =>

(B) 程式設計技巧

如想隨時得到某股票的歷史平均收盤價,必須紀錄該股票每日收盤價格;一日接一日的交替變化,需要紀錄的資料也可能無限延伸。當然不可能無限紀錄該股票的收盤價,再說太久之前的資料也可能沒有任何意思。但歷史資料記錄太少的話,也可能影響評估股價的正確性。本範例需要 30 日之前股票的收盤價,可利用由一維陣列製作的『佇列器』(Queue)來紀錄。圖 7-1 利用一只 30 個元素的一維陣列,儲存台積電近 30 日收盤價(假設數值);stock[0] 為前一日、stock[1] 為前二日、依此類推,stock[29] 記錄前第 30 日股價。當欲新登錄資料,則所有陣列元素往前移一個位置,原 stock[29] 資料拋棄,新資料填入 stock[0]

2-6 紀錄過去 30 日收盤價

假設某位分析師利用陣列 stock[] = {78, 72, 61, 56, 87, 66, 74, 88, 76, 58, 65, 57, 90, 78, 67, 89, 56, 77, 56, 87, 67, 80, 77, 86, 67, 75, 86, 98, 88, 78}; 儲存台積電最近 30 個交易日的收盤價,其中 stock[0] 為昨日股價,又 stock[29] 是之前第 30 日的收盤價。

 (C) 程式範例

2-7 Ex2_6 程式架構

程式範例如下:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

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

49

50

import java.util.*;

public class Ex2_6{

  static double stock[]={78, 72, 61, 56, 87,

                         66, 74, 88, 76, 58,

                         65, 57, 90, 78, 67,

                         89, 56, 77, 56, 87,

                         67, 80, 77, 86, 67,

                         75, 86, 98, 88, 78};

  public static void main(String args[]) {

      Scanner keyin = new Scanner(System.in);

      double cost;

      int select;

      disp_menu();

      select = keyin.nextInt();

      while(select != 3) {

          switch(select) {

             case 1:

                  disp_stock();

                  break;

             case 2:

                  System.out.printf("請登錄當日收盤股價 =>");

                  cost = keyin.nextDouble();

                  for (int i=(30-1); i>=1; i--)

                      stock[i] = stock[i-1];

                  stock[0] = cost;

                  break;

             default:

                 System.out.printf("輸入錯誤 !! 請重新輸入\n");

          }

          disp_menu();

          select = keyin.nextInt();

      }

   }

   static void disp_menu() {

       System.out.printf("== 歡迎光臨 股票走勢分析系統 ==\n");

       System.out.printf("(1) 列印 30 日歷史收盤價\n");

       System.out.printf("(2) 登錄當日收盤價\n");

       System.out.printf("(3) 離開系統\n");

       System.out.printf("\t 請輸入工作選項 =>");

   }

   static void disp_stock() {             /* 列印 30 日內股價 */

      System.out.printf("\n== 列印最近 30 日股價==\n");   

      for(int i=0; i<stock.length; i++) {

           System.out.printf("%.2f  ", stock[i]);

            if((i+1) % 5 == 0)

               System.out.printf("\n");    //列印五筆, 換行

      }

      System.out.printf("\n");           // 列印完畢, 換行

   }

}

 

2-5-2 自我挑戰:股票走勢分析系統

A)程式功能:PM2_3.java

當股票分析師目標設定哪一股票(如台積電)後,大多會紀錄該股票過去收盤價,再利用資料分析最近該股的走勢,如果今天收盤價高於 1 530 日平均價,則稱為『多頭』走勢;如果高於 15 日但低於 30 日平均線,稱之為『盤整轉向多頭』;低於 15 日又高於 30 日,則稱為『盤整轉向空頭』;如果低於兩者,則為『空頭』走向。假設某位分析師利用陣列 stock[] = {78, 72, 61, 56, 87, 66, 74, 88, 76, 58, 65, 57, 90, 78, 67, 89, 56, 77, 56, 87, 67, 80, 77, 86, 67, 75, 86, 98, 88, 78}; 儲存台積電最近 30 個交易日的收盤價,其中 stock[0] 為昨日股價,又 stock[29] 是之前第 30 日的收盤價。請製作一股票走勢分析系統,且允許分析師增加當天收盤價、列印歷史收盤價、股票走勢如何;期望操作介面如下:

(a) 期望操作介面有 4 個功能選項

D:\Java2_book\chap2>java PM2_4

== 歡迎光臨 股票走勢分析系統 ==

(1) 列印 30 日歷史收盤價

(2) 登錄當日收盤價

(3) 分析目前股票走勢

(4) 離開系統

         請輸入工作選項 =>

(b) 選擇列印 30 日歷史收盤價(選擇 1)操作如下:

         請輸入工作選項 =>1

 

== 列印最近 30 日股價==

78.00  72.00  61.00  56.00  87.00

66.00  74.00  88.00  76.00  58.00

65.00  57.00  90.00  78.00  67.00

89.00  56.00  77.00  56.00  87.00

67.00  80.00  77.00  86.00  67.00

  • 86.00  98.00  88.00  78.00

(C) 選擇登錄當日收盤價(選擇 2)操作如下:

         請輸入工作選項 =>2

請登錄當日收盤股價 =>90

(D) 選擇分析目前股價走勢(選擇 3)操作如下:(空頭走勢)

         請輸入工作選項 =>3

請輸入目前股價 =>50

15 日平均= 73.07, 30 = 75.07

目前是空頭走勢

(E) 選擇分析目前股價走勢(選擇 3)操作如下:(多頭走勢)

         請輸入工作選項 =>3

請輸入目前股價 =>98

15 日平均= 73.07, 30 = 75.07

目前是多頭走勢

(F) 選擇分析目前股價走勢(選擇 3)操作如下:(盤整走勢)

         請輸入工作選項 =>3

請輸入目前股價 =>75

15 日平均= 73.07, 30 = 75.07

目前是盤整轉向多頭走勢

B)製作技巧研討:

如何記錄過去 30 天交易日的收盤價,如圖 2-# 與範例 Ex2_6 分別表示製作方法。另外,計算 15 日平均價,則計算 stock[0] stock[14] 的平均值;30 日平均價是 stock[0] ~ stock[29] 平均值,如此就可判斷該股票的走勢如何。如果目前價格來分析:

(1) 大於 1530 日平均價,則為『多頭』走勢;

(2) 如低於 1530 日兩者的平均價,則為『空頭』走勢;

(3) 如高於 15 日且低於 30 日是『盤整轉向多頭』

(4) 其他(低於 15 日但高於 30)是『盤整轉向空頭』

另一個重點,列印所有資料時,為了所輸出的報表較漂亮,每列印五筆資料後,就需換行。我們就依照該系統所應有的功能,將它分別寫成四個方法,其中 main() 為主程式、disp_menu() 功能是顯示功能選單、cal_ave(k) 為計算股票平均價使用,k 為計算最近天數 (15 30 )disp_stack() 為顯示所有股價的程式,整個類別架構如下圖所示。

虛擬碼提示如下:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

導入輸入套件(import java.util.*;);

主類別範圍 {

宣告靜態陣列並設定初值(static double stock[]={…..}

主程式範圍 {

宣告相關物件與變數;

顯示功能選項(disp_menu());

讀取功能選項(select = keyin.nextInt());

while (select !=4) {

switch(select) {

case 1:顯示 30 日收盤價(disp_stock();

case 2:讀取當日收盤價(cost);

移位陣列(for (int I= 29 ~ 1) stock[I] = stock[I-1];);

當日填入(stock[0] = cost;);

case 3:讀取目前股價(cost);

計算 15 日平均價(ave_15 = cal_ave(15));

計算 30 日平均價(ave_30 = cal_ave(30));

顯示平均價;

if ((cost>ave_15) && (cost>ave_30))

 顯示多頭走勢;

else if  ((cost <ave_15) && (cost <ave_30)

 顯示空頭走勢;

else if ((cost >ave_15) && (cost <ave_30))

 顯示盤整轉向多頭走勢;

if ((cost>ave_15) && (cost>ave_30))

 顯示盤整轉向空頭走勢;

} // switch/case 結束

顯示功能選項(disp_menu());

讀取功能選項(select = keyin.nextInt());

} // while 結束

} // 主方法結束

顯示選單方法範圍(static void disp_menu(){…..}

計算 k 日平均價範圍(static double cal_ave(int k)){

         double sum=0;

         for(int I=0; I<k; I++)

             sum = sum + stock[I];

         return sum/k;

} // cal_ave() 結束

 列印 30 日內所有股價範圍(static void disp_stock(){

        for(int i=0; i<stock.length; i++) {

             System.out.printf(“%.2f  “, stock[i]);

              if(( i+1) % 5 == 0)

                 System.out.printf(“\n”);    //列印五筆, 換行

        }

        System.out.printf(“\n”);           // 列印完畢, 換行

     } // disp_stock 結束

} // 主類別結束

2-5-3 自我挑戰:印製國字收據

(A) 程式功能:PM2_4.java

請製作『真自在遊民收容所』的捐款收據,功能是系統允許輸入捐款人姓名與金額,之後印出收據但捐款數字需由國字印出,期望操作介面如下:

G:\Examples\chap4>java PM2_4

請輸入大德先生/小姐姓名 = >tsnien

請輸入捐款金額 =>345678

列印收據如下:

 

****   真自在遊民收容所   捐款收據 ****

 

     感謝 tsnien 先生/小姐大德贊助

                捐款 345678 元整

 

總計 = 元整

 

**** 四海之內皆兄弟 順祝 平安快樂  ****

B)製作技巧提示:

本範例較困難的地方是數字轉換國字後,如何寫入適當的位置。我們設定一個範圍,比較容易設計列印格式,因此假設捐款最高為 9 千萬餘元(99999999,超過則另開收據);圖 7-2 為本範例列印格式(大多如此)。另外,我們可以利用整數相除得到某一位數(百位、十位、個位),再利用餘數運算,得到取出某一位數後的剩餘值;另選一個陣列(int num[])存放每一位數的數字。讀取輸入捐款金額後(value),除以 1 千萬(10000000)得到千萬位的數字,再利用相同的數經過餘數運算,則扣除千萬位數,得到百萬以下的數值,依此類推則可得到相對位數的數字,並依序存入 num[] 陣列內。同時,選用 chinese[] 陣列存放每種數字的相對應國字,chinese[0] 存『零』(0)、chinese[1] 存『壹』(1...等依此類推。

2-8 國字列印格式

吾人再選用 doll[] 陣列存放列印次序的相對位數文字;則利用 chinese[num[i]] doll[i] 陣列交互列印,其中 i 為列印位數的指標;如此即可得到國字列印,虛擬碼提示如下:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

宣告國字數字陣列(String chinese[] = {"", "", "", "", .., ""});

宣告列印格式陣列(String doll[] = {"", "", "",””, “”, “”, “”, ""}

宣告位數數字陣列(int[] num = new int[9]);

宣告最高數字變數(千萬,base=10000000);

讀取捐款姓名(name);

讀取捐款額(value;

備份捐款額(value1 = value);

取出各個位數的數字:(最高 8 位數)

          for (int i=0; i<8; i++) {     //i=0, 仟萬; i=1, 佰萬; i=2, 拾萬; …

              num[i] = value / base;

              value = value % base;

              base = base /10;

          }

列印捐款人姓名及金額(name, value1);

列印捐款的國字:(最高 8 位數)

          System.out.printf("\n總計 =");

          for(int i=0; i<8; i++)

              System.out.printf(" %s %s", chinese[num[i]], doll[i]);

          System.out.printf(" \n");

2-5-4 自我挑戰:統計滿意度平均值

(A) 程式功能:PM2_5.java

歡樂歌唱比賽邀請了 10 位老師當評審員,每位老師可給予 0~10 分,但記分方法是捨棄最高與最低分數後,再計算其餘 8 位老師的平均分數。期望操作介面,如下:

D:\Java2_book\chap2>javac PM2_5.java

 

D:\Java2_book\chap2>java PM2_5

請輸入第 1 位評審分數(0 ~ 10)=>5

請輸入第 2 位評審分數(0 ~ 10)=>1

請輸入第 3 位評審分數(0 ~ 10)=>6

請輸入第 4 位評審分數(0 ~ 10)=>7

請輸入第 5 位評審分數(0 ~ 10)=>9

請輸入第 6 位評審分數(0 ~ 10)=>9

請輸入第 7 位評審分數(0 ~ 10)=>8

請輸入第 8 位評審分數(0 ~ 10)=>7

請輸入第 9 位評審分數(0 ~ 10)=>6

請輸入第 10 位評審分數(0 ~ 10)=>7

有效評分: 5   6   6   7   7   7   8   9

平均分數為: 6.88

(B) 程式製作技巧

首先產生 10 個元素陣列 a[0]~a[9],分別讀入每位老師的評分後,再利用泡沫排序法,將 a[] 陣列由小到大排序,並捨棄 a[0] a[9]後,再計算分均分數。

(C) 程式提示

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

//PM2_5.java

….

import java.util.Scanner;

public class PM2_5{

    public static void main(String[] args){

           Scanner in = new Scanner(System.in);

           int[] a = new int[10];

          …..

        while (count < 10) {

               System.out.printf("請輸入第 %d 位評審分數(0 ~ 10)=>", count+1);

               a[count] = in.nextInt();

            count++;

        }

         ……..

      }

}

翻轉工作室:粘添壽

 

Java 程式設計(二) 含物件導向

 

 

翻轉電子書系列: