陣列Array

      在〈陣列Array〉中尚無留言

陣列簡介

當我們要記錄10個學生的分數時, 可能要宣告如下

int score1=100;
int score2=95;
.......
int score10=99;

如此一直重複的宣告, 實在不是聰明的作法, 更何況如果有1000個學生的時候, 那該如何是好.

陣列是一個容器物件, 裏面包含著相同型態的一群數值, 型態可以是原生資料, 也可以是物件. 陣列在建立時, 就必需告知長度. 且建立後長度就不可變更.
int [] score=new score[100];

陣列裏的每一個項目, 叫元素, 每個元素使用索引(index)存取. 第一個元素的索引為0

C/C++ 的陣列可以宣告為 int a[100]; 還是屬於基本資料型態. 但Java不一樣, Java的陣列是物件型態.
在Java中, int [] score 是在宣告score是一個陣列, 至於長度及實際的空間, 由後面的new 來完成

 一維陣列宣告, 實例及初始化

宣告 : type [] array_identifier;
實例 : int []a=new int[5];

上述實例中,會產生一個陣列a, 長度為5。在記憶体中, a的變數存放在stack區。然後產生的5格空間,稱為物件,置於heap中,如下圖所示

請先執行下面的代碼

int []a=new int[5];
a[0]=80;
a[1]=90;
for (int i=0;i<a.length;i++){
   System.out.printf("a[%d]=%d\n", i, a[i]);
}
結果 :
80
90
0
0
0

由上面代碼中,可知如下重要訊息

1. 索引值由 0 開始
2. 裏面的值自動初始化為0
3. 若a[10]=100;會出現ArrayIndexOutOfBoundsException(超出邊界例外)runtime error
4. Compile fails : 編寫程式時有紅色底線
5. runtime error: 執行時發生錯誤,造成程式閃退

實際例子

int[] a=new int[10];//10個元素都會初始化為0
int[] b=new int[]{10,20,30,40,50};//有初始值, 就不能指定長度
int[] c={10,20,30,40,50};//可以不用new
int d[]; //這樣也可以
Object o=new int[10];//可以宣告為Object Shirt[] shirts={new Shirt(), new Shirt(), new Shirt()};

 底下的代碼是常會犯的低級錯誤

Int[] ages;
ages={19,42,92,33,46}; //此時需先new一個長度陣列,再一個一個填入值

陣列若沒有給定初始值, 則裏面的元素會自動初始化為預設值. 若要取得陣列長度可直接使用 .length 屬性, 如 ages.length.
請特別注意, 陣列的長度是屬性, 不需要 (). 字串的長度是方法, 需要 ()
int[] a=new int[50];
String b=”Java”;
a.length; //為屬性, 長度50
b.length();//為方法, 長度為4

陣列與for 迴圈

陣列可以使用for 迴圈一一存取, 如下程式碼

public static void getData(int[] d){
    for (int i=0;i<d.length;i++){
        d[i]=(int)(Math.random()*10000)+1;
    }
}

for-each

陣列或集合, 亦可以使用for-each 的方式進行迴圈處理, 如下程式碼

public static void main(String[] args) {
String []planet={"Mercury", "Venus","Earth", "Mars","Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"};
//原本的寫法
/*
for (int i=0;i<planet.length;i++){
System.out.println(planet[i]);
}
*/

//for-each, 新功能, OCA必考
for (String s: planet){
System.out.println(s);
}
}
結果
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune
Pluto

統計學定律

在一個桶子裏,放入100顆球,編號為 1~100,經多次抽出後,其平均值為 (1+100)/2=50.5

public static void main(String[] args) {
//產生陣列
   int n=10;
   int []a=new int[n];

//產生亂數,放於陣列中
   for (int i=0;i<a.length;i++){
       a[i]=(int)(Math.random()*100)+1;
   }

//計算陣列總和
   int sum=0;
   for (int i=0;i<a.length;i++){
       sum=sum+a[i];
   }

//計算平均值
   System.out.printf("平均值為 : %.2f", (double)sum/n);
}
以上的結果,並不是50.5。這是因為抽樣數太少的原因。如果把 n 改成100,000,就會愈接近50.5了
另外(double)sum/n, 是將sum強制轉換成double, 再進行計算

陣列初始化

一般正常的寫法如下
int []a=new int[10];
a[0]=100;

底下的寫法,並沒有new int[10], 此時實際空間尚未產生, 會出現compile failes

int []b;
b[0]=50;

底下的寫法, new int[]不可填入長度, 系統會自已從後面的數字計算長度

int [] c =new int[]{10,20,30,40,50};

省略new int[]

int [] d={10,20,30,40,50};

[]可以寫在變數的前面或後面

int e[]={10,20,30,40,50};

for-each 與ArrayLists

for-each應用在ArrayList的範例如下

List list=new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
for (String s:list){
    System.out.println(s);
}

命令列參數

在命令列下執指令時 : Java test hello world, 則hello world這二個參數會被main方法裏的args陣列接收
public static void main(String[] args){}

args[0]為hello , args[1]為world

若參數為1 2,則可以使用Integer.parseInt(args[0])轉換

二維陣列

二維陣列的圖型如下,具有x及y 二個維度,橫向(x軸)稱為 row(列),縱向(y軸)稱為column(列)。每一格的座標為(列,行),換算成數學的座標,則為(y, x)

 

宣告方式

使用二個 “[][]” 定義成二個維度,如下所示

int [][]b=new int[3][5];
b[0][0]=100;
b[0][1]=80;

遍訪所有儲存格

需使用巢狀迴圈足一列印,如下

public static void main(String[] args) {
int [][]b=new int[3][5];
b[0][0]=100;
b[0][1]=80;
for(int i=0;i<b.length;i++){
for (int j=0;j<b[i].length;j++){
System.out.printf("%3d ", b[i][j]);
}
System.out.println();
}
}
結果如下:
100 80 0 0 0
0 0 0 0 0
0 0 0 0 0

如果使用for-each遍訪的話,程式碼如下

for (int[] rows:b){
for (int v:rows){
System.out.printf("%3d ", v);
}
System.out.println();
}

觀查以上的二維陣列,每列的長度皆為5,稱為等長二維陣列

非等長二維陣列

如下圖所示,第0列長度為5,第1列長度為3,第2列長度為4。每一列的長度不一樣,此稱為非等長二維陣列

 

產生此種陣列的方式如下代碼

int[][] a=new int[3][];
a[0]=new int[5];
a[1]=new int[3];
a[2]=new int[4];

此時每個陣列的長度都不一樣了。遍訪的方式跟二述的等長二維陣列一模一樣。

初始化

int [][]a={{1,2}, {3,4,5}, {6,7,8,9}};

System.arraycopy

ystem類別提供了static 方法可以用來copy陣列, System.arraycopy(來源, 起始索引, 目的, 開始索引, 複制長度), 如下

int[] a={1,2,3,4,5};
System.arraycopy(array, 2, array, 1, 2);
結果 a 會變為{1,3,4,4,5}

 ArrayList

ArrayList是為了改善陣列不可以動態修改長度而設計的. 其特性跟陣列一樣, 只差別於陣列不可以改變大小, ArrayList會在增加元素時自動變更大小. 但還有一項特別的差異, 就是ArrayList不可以存放原生資料,

ArrayList的方法有add(), get(), remove(), indexOf()

ArrayList myList;
myList=new ArrayList();
myList.add(“John”);
myList.remove(0);
myList.remove(“John”);
System.out.println(myList.size()); //印出長度
System.out.println(myList); //將所有的元素列出

import

ArrayList是java.util的package, 所以需於上方先輸入

import java.util.*;

注意 : String, Math, Integer類別是java.lang的 package, 系統預設會自動import

A two-dimensional array is similar to a ??
A. Shopping list
B. List of chores
C. Matrix
D. Bar chart containing the dimensions for several boxes

Answer : C

 氣泡排序法

規則 : 
1. 假設有n個數(0~n-1)
2. 第 i 個數 (0~n-2),必需跟後面 (i+1~n-1) 比對,如果前面的數比較大,則對調。

public class BubbleSort{
    public static void main(String[] args){
        int n=50000;
        int d[]=new int[n];
        getData(d);
        //printData(d);
        long t1=System.nanoTime();//目前系統時間, 精準到奈秒
        sort(d);
        long t2=System.nanoTime();
        System.out.println("總花費 : "+(t2-t1)/1000.0f+"微秒");
        //printData(d);
    }
    public static void getData(int[] d){
        for (int i=0;i<d.length;i++){
            d[i]=(int)(Math.random()*10000)+1;
        }
    }
    public static void printData(int[]d){
        System.out.println();
        for (int i:d){
            System.out.printf("%d ", i);
        }
    }
    public static void sort(int[]d){
        for (int i=0;i<=d.length-2;i++){
            for (int j=i+1;j<=d.length-1;j++){ if (d[i]>d[j]){
                    int tmp=d[i];
                    d[i]=d[j];
                    d[j]=tmp;
                }
            }
        }
    }
}

顯示結果 : 
總花費 : 3680549.0微秒

河圖洛書

河圖洛書是周文王時代,伏羲氏於洛水發現了一隻烏龜,背部的九宮格有著一組奇怪的點,將其點數橫的加,直的加,斜的加,都是15。因此就命名為河圖洛書,如下圖

 

規則

1. 必需是奇數格
2. 先在最上列,中間格填入1
3. 往右上角移動。如果超出上方邊界,則移到最下方。如果超出右邊界,則移到最左邊
4. 如上右上角有東西,則往左一行,往下二列
5. 如果是在最右上角,則往下降一行。

自然語言法

使用人類懂的語言,去描述出邏輯演算法.

1. n=5, 表示5*5格
2. 產生 5*5的二維陣列
3. x=n/2, y=0, index=1
4. 迴圈
a. 填入index,並將index+1
b. 如果是最右上角:降一列
c. 否則
往右上角移動
如果超出右邊界,移到最左邊
如果超出上邊界,移到最下面
如果右上角已有東西,往左一行,往下二列
5. 將二維陣列印出
public class SquareNumber {
    public static void main(String[] args) {
        int n=7;
        int [][]d=new int[n][n];
        int index=1, x=n/2, y=0;
        while(index<=n*n){
            d[y][x]=index++;
            if (x==n-1 && y==0){
                y=1;
            }
            else{
                x=(x+1)%n;
                y=(y-1+n)%n;
                if (d[y][x]!=0){
                    x--;
                    y+=2;
                }
            }
        }
        for (int[] row:d){
            for (int value:row){
                System.out.printf("%3d ", value);
            }
            System.out.println();
        }
    }
}

執行結果 : 
30 39 48  1 10 19 28 
38 47  7  9 18 27 29 
46  6  8 17 26 35 37 
 5 14 16 25 34 36 45 
13 15 24 33 42 44  4 
21 23 32 41 43  3 12 
22 31 40 49  2 11 20

商品銷售

公司販賣5項商品, 每項商品單價如下

item1 item2 item3 item4 item5
10.8 20.8 15.9 28.6 35.6

公司聘請三位sales, 每位sales單月的銷售數量如下

  item1 item2 item3 item4 item5
sales1 10 5 12 7 9
sales2 12 15 6 32 20
sales3 18 23 43 12 21

請計算如下
1. 每位sales的銷售金額
2. 每項商品的營業額

public class Test {
    public static void main(String[] args) {
        int [][]sales={{10,5,12,7,9},{12,15,6,32,20},{18,23,43,12,21}};
        double []price={10.8,20.8,15.9,28.6,35.6};
        //計算每個營業員的銷售額
        for (int i=0;i<sales.length;i++){
            double total=0;
            for (int j=0;j<sales[i].length;j++){
                total+=sales[i][j]*price[j];
            }
            System.out.printf("sales%d 銷售額 : %.2f\n", i+1, total);
        }
        //計算每項商品營業額
        for (int i=0;i<price.length;i++){
            int total=0;
            for (int j=0;j<sales.length;j++){
                total+=sales[j][i];
            }
            System.out.printf("商品%d 營業額 : %.2f\n", i+1, total*price[i]);
        }
    }
}

天干地支

public static void main(String[] args) {
String[] sky={"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
String[] land={"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
String[] animal={"鼠","牛","虎","免","龍","蛇","馬","羊","猴","雞","狗","豬"};
Date d=new Date();
int yyyy=Integer.parseInt(new SimpleDateFormat("yyyy").format(d));
int yyy=yyyy-1911;
int start=13;
for (int i=0;i<120;i++){
if (yyy-start>=0)
System.out.printf("%s%s 民國%3d年 %s %3d歲\n", sky[i%10], land[i%12], start, animal[i%12], yyy-start+1);
else
System.out.printf("%s%s 民國%3d年 %s \n", sky[i%10], land[i%12], start, animal[i%12]);
start++;
}
}
結果 :
甲子 民國 13年 鼠 97歲
乙丑 民國 14年 牛 96歲
丙寅 民國 15年 虎 95歲
丁卯 民國 16年 免 94歲
戊辰 民國 17年 龍 93歲
己巳 民國 18年 蛇 92歲
庚午 民國 19年 馬 91歲
辛未 民國 20年 羊 90歲
壬申 民國 21年 猴 89歲
癸酉 民國 22年 雞 88歲
甲戌 民國 23年 狗 87歲
乙亥 民國 24年 豬 86歲
丙子 民國 25年 鼠 85歲
丁丑 民國 26年 牛 84歲
戊寅 民國 27年 虎 83歲
己卯 民國 28年 免 82歲
庚辰 民國 29年 龍 81歲
辛巳 民國 30年 蛇 80歲
壬午 民國 31年 馬 79歲
癸未 民國 32年 羊 78歲
甲申 民國 33年 猴 77歲
乙酉 民國 34年 雞 76歲
丙戌 民國 35年 狗 75歲
丁亥 民國 36年 豬 74歲
戊子 民國 37年 鼠 73歲
己丑 民國 38年 牛 72歲
庚寅 民國 39年 虎 71歲
辛卯 民國 40年 免 70歲
壬辰 民國 41年 龍 69歲
癸巳 民國 42年 蛇 68歲
甲午 民國 43年 馬 67歲
乙未 民國 44年 羊 66歲
丙申 民國 45年 猴 65歲
丁酉 民國 46年 雞 64歲
戊戌 民國 47年 狗 63歲
己亥 民國 48年 豬 62歲
庚子 民國 49年 鼠 61歲
辛丑 民國 50年 牛 60歲
壬寅 民國 51年 虎 59歲
癸卯 民國 52年 免 58歲
甲辰 民國 53年 龍 57歲
乙巳 民國 54年 蛇 56歲
丙午 民國 55年 馬 55歲
丁未 民國 56年 羊 54歲
戊申 民國 57年 猴 53歲
己酉 民國 58年 雞 52歲
庚戌 民國 59年 狗 51歲
辛亥 民國 60年 豬 50歲
壬子 民國 61年 鼠 49歲
癸丑 民國 62年 牛 48歲
甲寅 民國 63年 虎 47歲
乙卯 民國 64年 免 46歲
丙辰 民國 65年 龍 45歲
丁巳 民國 66年 蛇 44歲
戊午 民國 67年 馬 43歲
己未 民國 68年 羊 42歲
庚申 民國 69年 猴 41歲
辛酉 民國 70年 雞 40歲
壬戌 民國 71年 狗 39歲
癸亥 民國 72年 豬 38歲
甲子 民國 73年 鼠 37歲
乙丑 民國 74年 牛 36歲
丙寅 民國 75年 虎 35歲
丁卯 民國 76年 免 34歲
戊辰 民國 77年 龍 33歲
己巳 民國 78年 蛇 32歲
庚午 民國 79年 馬 31歲
辛未 民國 80年 羊 30歲
壬申 民國 81年 猴 29歲
癸酉 民國 82年 雞 28歲
甲戌 民國 83年 狗 27歲
乙亥 民國 84年 豬 26歲
丙子 民國 85年 鼠 25歲
丁丑 民國 86年 牛 24歲
戊寅 民國 87年 虎 23歲
己卯 民國 88年 免 22歲
庚辰 民國 89年 龍 21歲
辛巳 民國 90年 蛇 20歲
壬午 民國 91年 馬 19歲
癸未 民國 92年 羊 18歲
甲申 民國 93年 猴 17歲
乙酉 民國 94年 雞 16歲
丙戌 民國 95年 狗 15歲
丁亥 民國 96年 豬 14歲
戊子 民國 97年 鼠 13歲
己丑 民國 98年 牛 12歲
庚寅 民國 99年 虎 11歲
辛卯 民國100年 免 10歲
壬辰 民國101年 龍 9歲
癸巳 民國102年 蛇 8歲
甲午 民國103年 馬 7歲
乙未 民國104年 羊 6歲
丙申 民國105年 猴 5歲
丁酉 民國106年 雞 4歲
戊戌 民國107年 狗 3歲
己亥 民國108年 豬 2歲
庚子 民國109年 鼠 1歲
辛丑 民國110年 牛
壬寅 民國111年 虎
癸卯 民國112年 免
甲辰 民國113年 龍
乙巳 民國114年 蛇
丙午 民國115年 馬
丁未 民國116年 羊
戊申 民國117年 猴
己酉 民國118年 雞
庚戌 民國119年 狗
辛亥 民國120年 豬
壬子 民國121年 鼠
癸丑 民國122年 牛
甲寅 民國123年 虎
乙卯 民國124年 免
丙辰 民國125年 龍
丁巳 民國126年 蛇
戊午 民國127年 馬
己未 民國128年 羊
庚申 民國129年 猴
辛酉 民國130年 雞
壬戌 民國131年 狗
癸亥 民國132年 豬

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *