2009年2月12日 星期四

Java小練習(16)--關於字串

題目要求: 撰寫一個名為Dog的class,並使其含有兩個公開的String : name以及says。在main()中分產生兩個Dog的物件,並將其命名為"spot",says值為"Ruff!"、以及"scruff",says值為"Wuff!"。印出他們的name以及says。 接著產生Dog的reference並且將他指派到表示spot的物件,分別使用"=="以及".equels()"來比降所有的reference。 ------------- code starts ------------------
public class Dog {

   public String name;
   public String says;

   public static void main(String[] args) {
       Dog d1 = new Dog();
       d1.name = "spot";
       d1.says = "Ruff!";

       Dog d2 = new Dog();
       d2.name = "scruffy";
       d2.says = "Wurf!";

       System.out.println("第1隻狗叫" + d1.name + ";而且他說:" + d1.says);
       System.out.println("第2隻狗叫" + d2.name + ";而且他說:" + d2.says);
       System.out.println("----------");

       System.out.println("把第2隻狗的名字指定給第1隻狗");
       d1.name = d2.name;
       System.out.println("第1隻狗叫" +d1.name);
       System.out.println("第2隻狗叫" +d2.name);
       System.out.println("兩隻狗物件的位置是否相同:" +(d1 == d2));
       System.out.println("兩隻狗名字的位置是否相同:"+(d1.name == d2.name));
       System.out.println("兩隻狗名字的內容是否相同:"+(d1.name).equals(d2.name));
       System.out.println("兩隻狗說話的內容是否相同:"+(d1.says).equals(d2.says));
       System.out.println("--------------------------");

       System.out.println("把第2隻狗整個物件指定給第1隻狗");
       d1 = d2;
       System.out.println("第1隻狗叫" +d1.name);
       System.out.println("第2隻狗叫" +d2.name);
       System.out.println("兩隻狗物件的位置是否相同:" +(d1 == d2));
       System.out.println("兩隻狗名字的位置是否相同:"+(d1.name == d2.name));
       System.out.println("兩隻狗名字的內容是否相同:"+(d1.name).equals(d2.name));
       System.out.println("兩隻狗說話的內容是否相同:"+(d1.says).equals(d2.says));

   }
}
------------- code ends ------------------ 雖然java傳值的方式是pass-by-value,對於基本型別來說容易理解,對於類別型別來說感覺上卻是pass-by-references。 不過我們可以這樣理解:java物件的pass-by-value是指記憶體的參考位置的值,所以傳遞的是reference的位置的值。很多程式設計師都說java的pass-by-value是強詞奪理,不過我們就聽聽吧!

2009年2月10日 星期二

Java小練習(15)--break與continue練習

break與continue搭配label來控制迴圈是很有趣的方法,我經常用他來判斷自己的想法正不正確。 我作一個巢狀迴圈,外迴圈跑6次,內迴圈跑4次,加入continue跟break來看看會發生甚麼有趣的事情。 --------- example 1 -----------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");             continue L1;
          L2:
          for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");              }             System.out.println();         }     } }
--------- example 1 ends ----------- continue放在第一層for迴圈的結果,會導致L2完全沒機會被執行到,執行結果是:
i=1        i=2        i=3        i=4        i=5        i=6
--------- example 2 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");             break L1;
          L2:
          for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");              }             System.out.println();         }     } }
--------- example 2 ends --------- break放在第一層for迴圈的結果,會導致L2完全沒機會被執行到,執行結果是:
i=1
然而我們無法在這個地方放置break L2或continue L2,她會顯示找不到L2個標籤。 --------- example 3 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 continue L2;
          }
          System.out.println();
      }
  }
}
--------- example 3 ends ---------
i=1        j=1        j=2        j=3        j=4     
i=2        j=1        j=2        j=3        j=4     
i=3        j=1        j=2        j=3        j=4     
i=4        j=1        j=2        j=3        j=4     
i=5        j=1        j=2        j=3        j=4     
i=6        j=1        j=2        j=3        j=4  
跑出來的結果可想而知,會跟沒有continue是一樣的,因為她本來就會重複作。 那麼如果是continue L1會如何呢? --------- example 4 ----------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.println("\t"); //換行以方便顯示
              continue L1;
          }
          System.out.println();
      }
  }
}
--------- example 4 ends ---------
i=1        j=1     
i=2        j=1     
i=3        j=1     
i=4        j=1     
i=5        j=1     
i=6        j=1
內迴圈作一次之後沒機會作第二次就跑到外迴圈了,所以苦命的內迴圈用永都只能作第一次。 --------- example 5 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 break L2;
          }
          System.out.println();
      }
  }
}
--------- example 5 ends --------- break會脫離所標示的迴圈:即內迴圈,因此內迴圈永遠只能作一次。example 4跟5是一樣的結局。
i=1        j=1     
i=2        j=1     
i=3        j=1     
i=4        j=1     
i=5        j=1     
i=6        j=1
--------- example 6 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 break L1;
          }
          System.out.println();
      }
  }
}
--------- example 6 ends --------- break會跳離標籤所示的迴圈:即外迴圈,因此只做一次就結束了。
i=1        j=1
很好玩吧!

Java小練習(14)--二維陣列

從練習13,我們作一個轉換:請印出下列表格:
28916981251
324196100364
361225121499
4002561446416
可以發現這是練習13順時針旋轉90度。但是我們從1~400給值必須從 [0][4]->[1][4]->[2][4]->[3][4]->換列 [0][3]->[1][3]->[2][3]->[3][3]->換列 [0][2]->[1][2]->[2][2]->[3][2]->換列 [0][1]->[1][1]->[2][1]->[3][1]->換列 [0][0]->[1][0]->[2][0]->[3][0]-> end 值給定之後,就可以依序列印。 ------------ code starts --------------------------
public class ArrayAssign2 {

    public static void main(String[] args) {
        int[][] bb = new int[4][5]; //建立一個4x5陣列

        int num = 1;
        for (int col = bb[0].length - 1; col >= 0; col--) {
            for (int row = 0; row < bb.length; row++) {
                bb[row][col] = (int) Math.pow(num, 2);
                num++;
            }
        }
        for (int row = 0; row < bb.length; row++) {
            for (int col = 0; col < bb[0].length; col++) {
                System.out.print(bb[row][col]);
                System.out.print("\t");
            }
            System.out.println();
        }

    }
}
------------------- code ends ---------------------------------------

Java小練習(13)--二維陣列

利用迴圈印出如下的排列:
12916
25364964
81100121144
169196225256
289324361400
由上表可以觀察出每個數字分別是由陣列[0][0]到[4][3]依序填入1~20的平方。只要我們能依序填入1~20,就有辦法填入他們的平方。 -------------- code starts -----------------------
public class ArrayAssign1 {

    public static void main(String[] args) {
        int[][] aa = new int[5][4]; //建立一個5x4陣列

        int num = 1;
        for (int r = 0; r < aa.length; r++) {
            for (int c = 0; c < aa[0].length; c++) {
                //利用兩個for迴圈把值一個一個塞進去
                //再利用Math.pow()來作平方計算
                aa[r][c] = (int)Math.pow(num, 2);
                System.out.print(aa[r][c]);
                System.out.print("\t");
                num++;
            }
            System.out.println();
        }
    }
}
------------------ code ends --------------------------

2009年2月9日 星期一

Java小練習(12)--二維陣列

根據Java小練習(11),我們用兩個一維陣列來完成。如果我們把程式碼改寫成一個二維陣列,寫法會比較靈活!
public class ArrayTest3 {

    public static void main(String[] args) {
        //data[月份][銷售業績],12x2的陣列
        int[][] data = { {1, 16}, {2, 15}, {3, 13}, {4, 11}, {5, 10}, {6, 10},
                                {7, 8}, {8, 7}, {9, 4}, {10, 3}, {11, 1}, {12, 0} };

        System.out.println("Microsoft vista九十七年度銷售業績");
        System.out.println("月份\t業績");
        System.out.println("---------------------------------");

        for (int m = 0; m < data.length; m++) {//列印月份
            System.out.print("data[m][0]");
            System.out.print("\t");
            for (int star =1; star<=data[m][1]; star++){//列印業績的*號
                System.out.print("*");
            }
            System.out.println(); //*號印完換列
        }
        //for 迴圈結束,列印總數
        System.out.println("----------------------------------");
        int sum = 0;
        for (int i=0; i< data.length; i++){
            sum += data[i][1];
        }
        System.out.println("the total is:" +sum+"萬元");
    }
}

Java小練習(11)

題目要求:印出如下表格:
Microsoft vista九十七年度銷售業績
    月份     業績
    ------  ------------------------------------------
    1
    2         ********
    3         *******
    4         *************
    5         *********
    6         ************
    7         **********
    8         ********
    9         **************
    10        *************
    11        **************
    12        ***************
   ----------------------------------------------------
    銷售金額:??百萬元
-------- code starts ---------
public class ArrayTest2 {

    public static void main(String[] args) {
        //month ->代表月份
        int[] month = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        //data     ->代表銷售業績金額
        int[] data = {16, 15, 13, 11, 10, 10, 8, 7, 4, 3, 1, 0};

        System.out.println("Microsoft vista九十七年度銷售業績");
        System.out.println("月份\t業績");
        System.out.println("---------------------------------");
        //印出月份與業績
        for (int i = 0; i < month.length; i++) {
            System.out.print(month[i]);
            System.out.print("\t");
            //以下為列出*的迴圈,印初次數為data[i]
            for (int j = 1; j <= data[i]; j++) {
                System.out.print("*");
            }
            System.out.println();
        }

        System.out.println("----------------------------------");
        int sum = 0;
        for (int k = 0; k < data.length; k++) {
            sum = data[k] + sum;
        }
        System.out.println("總金額:" + sum + "百萬元");
    }
}

2009年2月8日 星期日

Java小練習(10) -- 亂數小練習

題目要求1:產生六個相鄰兩數不重複的亂數,亂數值介於1~100之間,並印出來。 想法:相鄰兩數不重複,可以用if作判斷;作六次可以用while來控制。
public class RandomTest {

    public static void main(String[] args) {
        byte temp = 0;
        byte count = 0;
        RandomTest ob1 = new RandomTest();
        temp = ob1.getRandom();
        count++;
        System.out.println("第" + count + "次的亂數值為" + temp);

        label:
        while (count < 6) {
            byte _temp = ob1.getRandom();
            if (_temp != temp) {
                temp = _temp;
                count++;
                System.out.println("第" + count + "次的亂數值為" + temp);
                continue label; //再回去取下一個亂數值。
            } else {
                continue label; //甚麼也不做,再取一次。
            }
        }

    }

    //取1-100之間的亂數方法
    public byte getRandom() {
        return ((byte) (Math.random() * 8 + 1));
    }
}
題目要求2: 改進要求1,取六個亂數,但這六個亂數絕對不能重複。 想法:
先做一個100個空間的陣列,依序放1-100
再依序由此陣列提取亂數6次。
提取陣列後便將該欄位清空為零,
從此陣列提取數值時,為零的就不提取,以保證不會重複。
public class ArrayTest1 {

    public static void main(String[] args) {
        int[] data = new int[100]; //作一個100個空間的整數陣列
        for (int i = 0; i < data.length; i++ ) {//依序放1-100
            data[i] = i + 1;
        }
        int count = 0; //用計數器取六次
        while (count != 6) {
            //作一個0~99的亂數當成陣列索引值。
            int random = (int) ( Math.random()*100 ); 
            //取出後就把該值設為0,遇到0就不取值。
            if (data[random] != 0) {
                System.out.println(data[random]);
                data[random] = 0;
                count++;
            }
        }
    }
}