You are on page 1of 20

nd

2 EDITION – BUG FIXED

เอกสารชุดนี้มอี ะไรบ้าง
• สรุปเนื้อหาหลังมิดเทอม ในเรื่องของ Methods / Arrays
• ทบทวนพื้นฐานการเขียนภาษาจาว่าเบื้องต้น
• แบบฝึกหัดในแต่ละหัวข้อ และแนวโจทย์ข้อสอบ พร้อมวิเคราะห์และเฉลย
• เทคนิค, ข้อควรระวัง, ข้อควรสังเกต แทรกไว้ระหว่างการอธิบาย

คําแนะนํา
• เนื้อหาได้พยายามสรุปให้กระชับและนําไปทําโจทย์ได้ทันที จึงขอแนะนําให้ทําความเข้าใจมาก่อนบ้าง
• เอกสารชุดนี้ ไม่ครอบคลุม เนื้อหาทางด้านทฤษฎี แต่ เน้น ในด้านการทําโจทย์สําหรับปลายภาค
• เนื้อหาได้พยายามเรียบเรียงสําหรับอ่านเรียงลําดับ (เพราะบางอย่างจะไม่อธิบายซ้ําตอนหลังแล้ว)
• เอกสารชุดนี้แบ่งกันเขียนหลายคน อาจมีความไม่ต่อเนื่องหรือสํานวนไม่เหมือนกัน ก็อย่างง (เวรกํา)

โชคเอครับ *
COMPLETED BY INTANIA’91
ZA-NUKER (F) // LUPIN (F) // NORTHERN (F) // MOOZZ (C)
JANUARY 23, 2008

いるか
Quick guide to A+JAVA (PART I) 2

>> Methods

สมมติเราจะเขียนส่วนของโปรแกรม การกินอาหารในแต่ละวัน ของคนๆ หนึ่งอย่างคร่าวๆ ด้านล่างนี้เป็นสอง


ตัวอย่างของโปรแกรมให้ลองเปรียบเทียบกันดู (ระหว่างฝั่งซ้ายและฝั่งขวา)
(หมายเหตุ: ตัวอย่างด้านล่างนี้ไม่ใช่โปรแกรมจริงๆ อย่าพยายามเอาไปพิมพ์ลง JLab นะ จะหาว่าไม่เตือน)

// โปรแกรมการกินอาหาร เวอร์ชัน 1 // โปรแกรมการกินอาหาร เวอร์ชัน 2

public static void main (String[] args) { public static void main (String[] args) {
if ( เวลา == ตอนเช้า ) { if (เวลา == ตอนเช้า )
หยิบช้อน ; กินอาหาร (โจ๊กหมู) ;
while ( โจ๊กหมูยังไม่หมด ) { } else if ( เวลา == ตอนเที่ยง ) {
ตักโจ๊กหมูเข้าปาก ; กินอาหาร (ส้มตําปลาร้า) ;
โจ๊กหมูลดลง ; } else if ( เวลา == ตอนเย็น ) {
} กินอาหาร (ผัดไทยกุ้งสด) ;
เก็บจาน ; }
} else if ( เวลา == ตอนเที่ยง ) { }

หยิบช้อน ; public static void กินอาหาร ( อาหาร ) {

while ( ส้มตําปลาร้ายังไม่หมด ) { หยิบช้อน ;


ตักส้มตําปลาร้าเข้าปาก ; while ( อาหารยังไม่หมด ) {

ส้มตําปลาร้าลดลง ; ตักอาหารเข้าปาก ;
} อาหารลดลง ;
เก็บจาน ; }
} else if ( เวลา == ตอนเย็น ) { เก็บจาน ;

หยิบช้อน ; }

while ( ผัดไทยกุ้งสดยังไม่หมด ) {
ตักผัดไทยกุ้งสดเข้าปาก ;
ผัดไทยกุ้งสดลดลง ;
}
เก็บจาน ;
}
}

ไม่แน่ใจเหมือนกันว่าพออ่านจบแล้วจะเข้าใจอะไรมากขึ้นหรือว่ากลายเป็นงงกว่าเดิมกันแน่ - -“ ที่
อยากให้สังเกตจากตัวอย่างสองโปรแกรมด้านบนก็คือทั้งสองโปรแกรมนั้นได้ ผลลัพธ์การทํางานเหมือนกันทุก
ประการ คือสุดท้ายแล้วเราจะได้ว่า ตอนเช้ากินโจ๊กหมู ตอนเที่ยงกินส้มตําปลาร้า และตอนเย็นกินผัดไทยกุ้ง
สด แต่ว่าโปรแกรมด้านขวาจะอ่านเข้าใจและดูเป็นระเบียบมากกว่าด้านซ้าย

ลองคิดดูว่า ถ้าวันๆ หนึ่งเราต้องกินอาหารซัก 20 มื้อ โปรแกรมด้านซ้ายและขวาจะเปลี่ยนไป


อย่างไร และนอกจากนั้น ถ้าเกิดเราเปลี่ยนวิธีการกินอาหาร จาก “ตักเข้าปาก” เป็น “ดูด” แทนล่ะ
Quick guide to A+JAVA (PART I) 3

ส่วนที่เราเรียกว่า Method จากโปรแกรมด้านบนก็คือ “กินอาหาร” นั่นเอง สังเกตว่าในวันๆ หนึ่งเรา


กินอาหารมากกว่า 1 ครั้ง และแต่ละครั้งเราไม่จําเป็นต้องกินเหมือนกัน หากเขียนโปรแกรมแบบด้านซ้ายนั้น
เราสั่งอย่างละเอียดมากว่าจะทําอะไร แต่ว่าคนอ่านจะไม่เข้าใจว่าเรากําลัง “กินอาหาร” อยู่ ในขณะที่
โปรแกรมด้านขวา เขียนสั้นกว่า เขียนง่ายกว่า และอ่านได้เข้าใจในทันทีว่าเรากําลังสั่งให้ “กินอาหาร”
ซึ่งอาหารที่เปลี่ยนแปลงไปในแต่ละมื้อนั้น ไม่ใช่อุปสรรคของการเขียน Method กินอาหาร นี้เลย
แม้แต่น้อย เพราะเราสามารถกําหนดได้ว่าจะให้อาหารในแต่ละมื้อเป็นอะไร โดยโยนค่าเข้าไปในวงเล็บนั้นๆ

กลัวว่ายิ่งอ่านแบบนี้ต่อไปจะยิ่งงง ลองมาดูตัวอย่าง Method ที่เราใช้กันจริงในจาว่าดีกว่า


เราเคยใช้ Method ในภาษาจาว่ามาจํานวนหลาย Method แล้ว โดยที่อาจจะรู้ตัว
หรือไม่รู้ตัว เช่น ลองมาดูคําสั่งต่อไปนี้กัน ว่าเราเคยคุ้นเคยกับมันมาก่อนที่ไหนหรือเปล่า

String a = JLabIO.readString(“ ใส่ข้อความ = “); System.out.println(“สวัสดี, โลก”);


double b = Math.pow(8, 3); System.out.print(“บ๊ายบาย, โลก”);
double c = Math.sqrt(172);
int d = a.length();

คําสั่งที่ขีดเส้นใต้ทั้งหมดด้านบนนั่นคือ Method ทั้งนั้น คิดว่าทุกคนต้องเคยเจออย่างน้อยครึ่งหนึ่งแน่นอน ซึ่ง


จากด้านบนนี้ ที่อยากให้สังเกตก็คือความแตกต่างระหว่าง Method ทางด้านซ้ายกับทางด้านขวา
Method ทางด้านซ้ายนั้น เมื่อเราเรียกมัน มันจะให้ค่าอะไรซักอย่างกลับคืนมาด้วย เช่น เมื่อเราเรียก
Math.pow(8, 3) เราจะได้ค่าของ 83 = 512 กลับมา แล้วเราก็เก็บไว้ในตัวแปร (หรือจะเอาไปทําอย่างอื่นก็
ได้) ในขณะที่ Method ฝั่งขวานั้น เมื่อเราเรียก System.out.println(“สวัสดี, โลก”) ปุ๊ป หน้าจอจะแสดง
ข้อความว่า สวัสดี, โลก ออกมาเท่านั้น แต่ว่าไม่มีค่าอะไรที่คืนกลับมาเลย นั่นคือ เราไม่สามารถเรียกคําสั่ง
ดังต่อไปนี้ได้
incompatible types, found : void,
String x = System.out.println(“ สวัสดี, โลก”); required: java.lang.String, column:34

ระวังความแตกตางระหวางขอความที่แสดงออกมาบนหนาจอ กับ คาที่คืนกลับ ดีๆ นะ (คอยๆ คิด)

Method ด้านบนนั้น เราสามารถเรียกใช้ได้เลยโดยจําแค่ว่าภายในวงเล็บต้องใส่ค่าอะไรให้มันบ้าง


เพราะว่า Method เหล่านั้นถูกเขียนขึ้นมารองรับเอาไว้อยู่แล้ว แต่ในกรณีที่เราอยากจะเน้นกว่าก็คือ Method
ที่เราเขียนขึ้นมาเพื่อใช้งานเอง อย่างเช่น Method หาระยะทางระหว่างจุดสองจุด เป็นต้น
public static double distance ( double x1, double y1, double x2, double y2 ) {
double d = Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
return d; // บรรทัดนี้หมายความว่าให้ ส่งค่าที่อยู่ในตัวแปร d คืนกลับไป
}

ด้านบนนี้เป็นการ “สร้าง” Method ใหม่เพื่อใช้งาน มีชื่อว่า distance โดยเมื่อเวลาเรียกใช้งาน ให้ใส่ค่าใน


วงเล็บเป็นค่าของ x1, y1, x2, y2 ตามลําดับ หลังจากนั้น เมื่อคํานวณเสร็จเรียบร้อยแล้ว Method นี้จะคืนค่า
ระยะทางที่ได้จากสูตรออกไป เป็นค่าข้อมูลชนิด double ซึ่งเราสามารถนําไปใช้งานได้ทันที เช่น

System.out.println(“ ระยะทางระหว่างจุด (2, 5) กับ (1.2, 8.6) คือ “ + distance(2, 5, 1.2, 8.6));
Quick guide to A+JAVA (PART I) 4

ข้อที่ควรทราบ
• Method สามารถคืนค่าได้ 3 รูปแบบใหญ่ๆ ได้แก่
o ข้อมูลพื้นฐาน เช่น int, char, double, boolean, long, …
o ข้อมูลประเภทคลาส (Class) เช่น String, … (กล่าวถึงเรื่องคลาสอีกทีในบทถัดๆ ไป)
o ไม่คืนค่าอะไรเลย ให้ใช้คําว่า void
• การตั้งชื่อ Method มีกฎเหมือนการตั้งชื่อตัวแปร แต่นิยมใช้คํากริยา เช่น isOdd(), isNegative()
• Method นั้นสามารถรับค่าเข้ามา (เราเรียกว่า Parameter) ทางวงเล็บ หรือไม่รับเลยก็ได้ (ว่างไว้)
• โดยปกติ ตัวแปรที่ประกาศใน Method ใดๆ จะสามารถเรียกใช้งานได้แค่ใน Method นั้นเท่านั้น
• คืนค่าด้วยคําสั่ง return ตามด้วยค่าที่ต้องการจะคืนกลับไป Method นั้นจะจบการทํางานทันที
• ส่วน Method ที่เป็น void ไม่ต้องใช้คําสั่ง return ก็ได้ หรือถ้าจะใช้ ให้ใช้ return; (ตามด้วย ; เลย)

มาจับผิดโปรแกรมกัน
import jlab.JLabIO;

public class NumberChecker {


public static void main (String[] args) {
double n1 = largestNumber(12.1, 16.2, 7);
int n2 = absoluteNumber(-23);
if ( isNegative(16) ) {
System.out.println(“16 is a negative number”);
}
} แก้เป็น largestNumber (double a, double b, double c) {
public static double largestNumber (int a, int b, int c) {
double max = a;
if (b > max) max = b;
if (c > max) max = c;
return max;
ไม่สามารถใช้ตัวแปร n2 ที่ประกาศใน Method อื่นได้
}
แก้เป็น if (a < 0) a = -a;

public static int absoluteNumber (int a) {


if (n2 < 0) a = -n2;
return a;
} Method นี้ถูกเรียกใช้ในคําสั่ง
แสดงว่า if
public static int isNegative (double a) { ต้องการ public static boolean ต่างหาก
if (a < 0) return true;
}
}
แล้วในกรณีที่ a ไม่น้อยกว่า 0 ล่ะจะทํายังไง
ต้อง return false ออกไปด้วยสิ
Quick guide to A+JAVA (PART I) 5

แบบฝึกหัด
ให้เขียนโปรแกรมเพื่อรับค่าด้านของสามเหลี่ยมทั้งสามด้านมาทั้งหมด 20 ชุด แล้วตรวจสอบว่าสามเหลี่ยม
นั้นเป็นสามเหลี่ยมมุมฉากหรือไม่ หากว่าเป็น ให้บอกด้วยว่าด้านตรงข้ามมุมฉากมีความยาวเท่าใด

ตัวอย่าง

ใส่ด้านที่ 1 ของสามเหลี่ยมรูปที่ 1 = 3
ใส่ด้านที่ 2 ของสามเหลี่ยมรูปที่ 1 = 4
ใส่ด้านที่ 3 ของสามเหลี่ยมรูปที่ 1 = 5
เป็นสามเหลี่ยมมุมฉาก ด้านตรงข้ามมุมฉากยาว 5

(หน้าต่อไปเป็นวิเคราะห์โจทย์และเฉลย … ดังนั้นหากต้องการจะคิดเองก่อน อย่าเผลอเหลือบตาไปมองนะ)


(ส่วนข้างล่างนี่ กระดาษทดจ้า~)
Quick guide to A+JAVA (PART I) 6

แนวคิด
• ก่อนอื่นเลย เราต้องรับค่าทั้งหมด 20 ชุด แสดงว่าเราต้องเขียน loop ด้วย for หรือ while (อันใดก็
ได้ แล้วแต่ถนัด) อย่างแน่นอน (หรือว่าจะ copy โค้ดเอาเอง 20 ครั้งก็ได้นะ)
• ในแต่ละรอบของ loop เราต้องทําอะไรบ้าง?
o แสดงข้อความว่าเรากําลังรับด้านที่ 1, 2, 3 ของสามเหลี่ยม และรับค่าเก็บในตัวแปร
o ด้านของสามเหลี่ยมสามารถเป็นทศนิยมได้นะ ดังนั้นควรใช้ double จะปลอดภัยกว่า
o ตรวจสอบว่าสามเหลี่ยมนั้นเป็นสามเหลี่ยมมุมฉากหรือไม่ (เอ๊ะ ตรงนี้น่าจะใช้ Method นะ)
o ถ้าใช่ ก็หาต่อว่าด้านตรงข้ามมุมฉากยาวเท่าไหร่ (ด้านยาวที่สุดนั่นเอง – Method อีกแน่ๆ)
o แสดงผลลัพธ์ออกมา
จะได้โปรแกรมมีหน้าตาประมาณนี้ (โปรแกรมด้านล่างนี่ยังไม่ถูกต้อง 100% นะ ลองหาจุดผิดดูด้วย)
import jlab.JLabIO;

public class Triangle {


public static void main (String[] args) {
for (int i = 1; i <= 20; i++) {
double n1 = JLabIO.readDouble(“ด้านที่ 1 ของสามเหลี่ยมรูปที่ “ + i + “ = “);
double n2 = JLabIO.readDouble(“ด้านที่ 2 ของสามเหลีย่ มรูปที่ “ + i + “ = “);
double n3 = JLabIO.readDouble(“ด้านที่ 3 ของสามเหลีย ่ มรูปที่ “ + i + “ = “);
if ( isRightTriangle(n1, n2, n3) ) {
double hyp = findHypotenuse(n1, n2, n3);
System.out.println(“ เป็นสามเหลี่ยมมุมฉาก ด้านตรงข้ามยาว “ + hyp);
} else {
System.out.println(“ มันไม่ใช่อ่ะ.. มันไม่ใช่สามเหลี่ยมมุมฉากแน่ๆ”);
}
}
}
public static boolean isRightTriangle (double a, double b, double c) {
if ( a * a + b * b == c * c ) return true;
ตรงนี้สามารถยุบรวมสามบรรทัดเป็นบรรทัด
if ( a * a + c * c == b * b ) return true;
if ( b * b + c * c == a * a ) return true;
เดียวได้ โดยใช้เครื่องหมาย || (or)
return false;
}
public static double findHypotenuse (double a, double b, double c) {
double max = a;
if ( b > max ) max = b;
if ( c > max ) max = c;
return max;
}
}

ขอควรระวัง! ใน Method ชื่อ isRightTriangle จริงๆ แลวไมควรเปรียบเทียบขอมูล x− y


ทศนิยมดวยการจับมา == กัน เพราะบางครั้งมันอาจจะตางกันเล็กนอย ≤ 10−14
max( x , y )
(คอมพิวเตอรเก็บคาที่ตรงเปะใหเราไมได) ควรใชวิธีการเปรียบเทียบดานขวานี้แทน
Quick guide to A+JAVA (PART I) 7

แก้ไขเรื่องวิธีการตรวจสอบความเท่ากันของจํานวนจริง (ที่มีทศนิยม)
เราจะแก้ Method isRightTriangle จากโปรแกรมหน้าที่แล้ว โดยไม่ให้เปรียบเทียบ x == y ในกรณีที่ x
และ y เป็นข้อมูลชนิด double (หรือ float) ด้วยกันทั้งคู่ แต่ให้ใช้การเปรียบเทียบโดยดูอัตราส่วนเอา ว่า
ผลต่างของค่าข้อมูล x กับ y หารด้วยค่าที่มากกว่าระหว่าง |x| กับ |y| นั้นมีค่าน้อยกว่า 10-14 หรือไม่ ถ้าใช่
แสดงว่าข้อมูล x กับ y นั้นแตกต่างกันน้อยมาก จนถือได้ว่าเป็นค่าที่เท่ากัน
อ่านถึง ณ ตรงนี้ ให้เราแทนค่า x และ y ในสูตรหน้าที่แล้วด้วยค่าที่เราต้องการ (จากโปรแกรม
หน้าที่แล้ว) เราจะสามารถเขียน Method isRightTriangle ใหม่ได้เป็นดังนี้
public static boolean isRightTriangle (double a, double b, double c) {
if(Math.abs(a * a + b * b – c * c) / Math.max(Math.abs(a * a + b * b), Math.abs(c * c)) < 1E-14)
return true;
if(Math.abs(a * a + c * c – b * b) / Math.max(Math.abs(a * a + c * c), Math.abs(b * b)) < 1E-14)
return true;
if(Math.abs(b * b + c * c – a * a) / Math.max(Math.abs(b * b + c * c), Math.abs(a * a)) < 1E-14)
return true;
return false;
}

ซึ่งดูแล้วมันช่างวุ่นวายเหลือเกิน … แต่จากการสังเกตเราจะพบว่าโค้ด if ทั้งสามบรรทัดนั้น มีความคล้ายกัน


มาก ต่างกันแค่ค่าของข้อมูลที่นํามาเปรียบเทียบเท่านั้น จึงเหมาะสําหรับเราที่จะเขียน Method ใหม่ขึ้นมา
รองรับ ตั้งชื่อว่า equals โดย Method นี้จะทําหน้าที่เปรียบเทียบจํานวนจริงสองจํานวนว่าใกล้เคียงจนถือว่า
เท่ากันหรือไม่ ถ้าใช่ให้คืนค่า true แต่ถ้าเท็จให้คือค่า false ออกไป … เราจะแก้เพิ่มเติมได้เป็นดังนี้
public static boolean isRightTriangle (double a, double b, double c) {
if ( equals(a * a + b * b, c * c) ) return true;
if ( equals(a * a + c * c, b * b) ) return true;
if ( equals(b * b + c * c, a * a) ) return true;
return false;
}
public static boolean equals (double x, double y) {
if ( Math.abs(x – y) / Math.max( Math.abs(x), Math.abs(y) ) < 1E-14 )
return true;
return false;
}

สิ่งที่ควรสังเกต
• Methodย่อยๆ สามารถเรียกไปยัง Method อื่นๆ ได้อีก
• สังเกตว่าทั้งสอง Method นั้น ตรงส่วน return false ทําไมถึงไม่ต้องมี else ก็เพราะว่า
หากว่าในกรณีที่ if ใดก็ตามก่อนหน้าคําสั่ง return false เป็นจริง Method จะ return
true และจบการทํางานทันที เพราะฉะนั้นการที่มันลงมาทํางานถึงบรรทัด return false ได้ แสดงว่า
ไม่มีเงื่อนไขใดๆ ก่อนหน้ามันเป็นจริงเลย

เรื่องที่ต้องอ่านเอง Method Overloading หน้า 33-34 ชีทจุฬาฯ เป็นทฤษฎีมากกว่าทําโจทย์


Quick guide to A+JAVA (PART I) 8

>> Arrays

อาร์เรย์ คือ แถวของข้อมูลประเภทเดียวกัน เพื่อความสะดวกในการประกาศตัวแปร หรือใช้งานในบางกรณี

ตัวอย่าง ให้รับข้อมูลเป็นจํานวนเต็ม 10 ข้อมูล แล้วแสดงผลข้อมูลทั้ง 10 จํานวนออกมา โดยแสดงสลับ


ลําดับจากตอนแรก กล่าวคือข้อมูลตัวที่ 10 จะแสดงเป็นตัวแรก … ข้อมูลตัวที่ 1 จะแสดงเป็นตัวสุดท้าย

> จํานวนที่ 1=1 // ส่วนของโปรแกรม


> จํานวนที่ 2=8 public static void main (String[] args) {
> จํานวนที่ 3=2 int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;

> จํานวนที่ 4=7


x0 = JLabIO.readInt(“จํานวนที่ 1 = “);
x1 = JLabIO.readInt(“จํานวนที่ 2 = “);
> จํานวนที่ 5=6
x2 = JLabIO.readInt(“จํานวนที่ 3 = “);
> จํานวนที่ 6=9
… ไปจนถึง x9
> จํานวนที่ 7 = 12
> จํานวนที่ 8=4
System.out.println(“ ผลลัพธ์:”);
> จํานวนที่ 9=3
System.out.println( x9 );
> จํานวนที่ 10 = 7
System.out.println( x8 );
> ผลลัพธ์: System.out.println( x7 );
>7 … ไปจนถึง x0
>3 }
>4
> 12
>9
>6
>7
>2
>8
>1

โปรแกรมนี้โจทย์กําหนดมาว่าให้รับแค่ 10 จํานวน ก็ยังพอจะ copy ไหวอยู่ แต่ถ้าเกิดเปลี่ยนโจทย์ใหม่เป็นให้


รับจํานวนเต็มทั้งหมด 100 จํานวนขึ้นมา ดูท่าว่าพระเอกของบทนี้ (อาร์เรย์) จะได้ออกโรงก็คราวนี้แหละ

public static void main (String[] args) {


int[] x = new int[100]; // วิธีการประกาศตัวแปรอาร์เรย์เพื่อเก็บข้อมูลชนิด int 100 ตัว
for (int i = 0; i < 100; i++)
x[i] = JLabIO.readInt(“ จํานวนที่ “ + (i + 1) + “ = “);
System.out.println(“ ผลลัพธ์: ”);
for (int i = 99; i >= 0; i--)
System.out.println( x[i] );
}
Quick guide to A+JAVA (PART I) 9

จากตัวอย่างโปรแกรมและข้อมูลที่ป้อนให้โปรแกรมที่ผ่านมา เราจะเห็นได้ว่าเราสามารถเข้าถึงข้อมูล
ได้ต่อเนื่องกัน เราจึงสร้างมโนภาพให้กับอาร์เรย์นี้ว่าเป็น “แถวของข้อมูล” ดังภาพ

1 8 2 7 6 9 12 4 3 7
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]

นอกเหนือจากการประกาศตัวแปรอาร์เรย์ด้วยวิธีข้างต้นแล้ว ในกรณีที่เรามีค่าเริ่มต้นให้กับอาร์เรย์ เรา


สามารถประกาศอาร์เรย์ได้อีกแบบ ดังนี้

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

ซึ่งจะถือว่าเป็นการประกาศอาร์เรย์ที่ชื่อ x เป็นชนิด int มีขนาด 10 ตัว พร้อมค่าเริ่มต้นในทันที แต่หากว่า


เราไม่ประกาศแบบนี้ ก็สามารถประกาศด้วยวิธีเดิมได้ แต่จะยุ่งยากกว่า ดูตัวอย่าง
int[] x = new int[10];
x[0] = 1;
x[1] = 8;
x[2] = 2;
x[3] = 7;
x[4] = 6;
x[5] = 9;
x[6] = 12;
x[7] = 4;
x[8] = 3;
x[9] = 7;

ข้อที่ควรทราบ
• การประกาศอาร์เรย์นั้น เป็นการประกาศตัวแปรชนิดหนึ่ง แต่ประกาศเพียงครั้งเดียว ได้มาหลายตัว
• การอ้างถึงข้อมูลแต่ละตัวในอาร์เรย์ จะอ้างโดยใช้วงเล็บก้ามปูหลังชื่อตัวแปร เช่น x[2]
• ข้อมูลในอาร์เรย์จะเริ่มต้นที่ x[0] เป็นข้อมูลตัวแรก ไม่ใช่ x[1] (ระวังให้ดี)
• หากประกาศ int[] x = new int[5] ตัวที่สามารถใช้ได้ทั้งหมดคือ x[0] x[1] x[2] x[3] และ x[4]
• ตัวเลขในวงเล็บก้ามปูนั้น ต้องเป็นจํานวนเต็มที่ไม่เป็นลบ เราเรียกว่า index ของอาร์เรย์

เรื่องของอาร์เรย์นั้นมีรายละเอียดอยู่ไม่มากนัก แต่โดยส่วนใหญ่แล้วโจทย์เกือบทุกข้อมักจําเป็นต้อง
นําอาร์เรย์มาใช้ให้เกิดประโยชน์อยู่เสมอ เพราะฉะนั้นมันเป็นเรื่องพื้นฐานเรื่องหนึ่งที่ควรจะทําให้ได้ และ
เข้าใจ ดังนั้นหลังจากนี้ จะขอยกตัวอย่างโจทย์เพิ่มเติมซักเล็กน้อย ขอให้ลองพยายามลองคิด ลองเขียนดูเอง
ก่อน ไม่เช่นนั้นแล้วจะไม่เกิดประโยชน์อันใดเลย (นะ)

แบบฝึกหัด
จํานวนลําดับที่ n ในอนุกรมฟิโบนักชี (Fibonacci) เกิดจากการนําจํานวน 2 ลําดับก่อนหน้ามาบวกกัน ดังนี้
A = {0,1,1, 2, 3,5,8,13,...} จงเขียนโปรแกรมเพื่อหาว่าจํานวนในลําดับที่ 30 ( a30 ) ของอนุกรมฟิโบนักชีนี้ มี
ค่าเท่ากับเท่าใด (กําหนดให้ลําดับแรกถือเป็นลําดับที่ 0 และ a0 = 0, a1 = 1 )
Quick guide to A+JAVA (PART I) 10

แนวคิด
• ประกาศอาร์เรย์ a[] มาเก็บอนุกรมฟิโบนักชีนี้ โดยให้ชนิดเป็น int ได้ (เป็นจํานวนเต็มเสมอ) – กี่ตัว?
• ระวังตรงนี้ดีๆ ว่าเราต้องการ a[30] แสดงว่าเราต้องประกาศไว้ 31 ตัว ไม่ใช่ 30 ตัว!!
• กําหนดให้ a[0] = 0 และ a[1] = 1;
• ทําการวน loop เริ่มตั้งแต่ n = 2 ไปจนถึง 30 เพื่อหาค่า a[n]
import jlab.JLabIO;

public class Fibonacci {


public static void main (String[] args) {
int[] a = new int[31]; // 31 ตัวนะจ๊ะ คือ 0 ถึง 30
a[0] = 0;
a[1] = 1;
for (int n = 2; n <= 30; n++)
a[n] = a[n-1] + a[n-2];
System.out.println(“ จํานวนลําดับที่ 30 ของอนุกรมฟิโบฯ = “ + a[30]);
}
}

* ลองคิดดู: จริงๆ แล้วโจทย์ข้อนี้ เราสามารถเขียนโดยไม่ใช้อาร์เรย์ก็ได้ โดยใช้ตัวแปรทั้งหมดไม่เกิน 5 ตัว


สิง่ ที่ควรสั
ควรสังเกต
ควร
ลองแกโปรแกรมขางตน จากเดิมหา a30 เปลี่ยนเปนหา a50 แทน แลวรันใน JLab ดูวาผลลัพธที่ไดมัน
ประหลาดไปจากที่ควรจะเปนอยางไร … เพราะอะไรถึงเปนเชนนั้น

แบบฝึกหัด
ปัจจุบันนครรัฐยางใหญ่ไฮโซ ได้รับเหรียญรางวัลจากการแข่งขันโอลิมปิกในระดับโลกมาอย่างมากมาย การ
ประเมินผลในแต่ละปีนั้น จะให้รวมจํานวนเหรียญที่คิดน้ําหนักแล้ว ทอง : เงิน : ทองแดง = 4 : 2 : 1 นั่น
หมายความได้ 1 เหรียญทอง ดูจะดีกว่าได้ 3 เหรียญทองแดง แต่การประเมินผลนั้น การดูเป็นปีๆ ย่อมจะ
ได้ผลที่ไม่ชัดเจนเท่าไรนัก จึงจะต้องดูผลรวมต่อเนื่อง 3 ปีแทน
จงเขียนโปรแกรมเพื่อรับข้อมูลเหรียญทอง เหรียญเงิน และเหรียญทองแดงที่นครรัฐยางใหญ่ไฮโซ
ได้รับในช่วง 10 ปีที่ผ่านมา แล้วหาว่า ช่วง 3 ปีใด ที่ผลงานของนครรัฐยางใหญ่ไฮโซ ดีที่สุด

ตัวอย่าง คําถามชวนคิด
• เราจะให้อาร์เรย์มาเก็บอะไรดี จน.เหรียญ
> จํานวนเหรียญทองปีที่ 1 = 0 หรือผลรวม
> จํานวนเหรียญเงินปีที่ 1 = 1 • การหาผลรวม 3 ปีนั้น จะหาอย่างไรดี
> จํานวนเหรียญทองแดงปีที่ 1 = 3 • ไม่ยากใช่มั้ย !?
… จนครบ 10 ปี • อย่าเพิ่งเปิดหน้าถัดไป หากยังไม่ได้คิด

> ช่วงปีที่ผลงานดีที่สุดคือช่วงปีที่ 2 ถึง 4


Quick guide to A+JAVA (PART I) 11

แนวคิด
ถ้าไม่รู้ว่าจะเริ่มคิดยังไงในหัวเลยดี ให้ลองสมมติข้อมูลชุดหนึ่งขึ้นมาตามเงื่อนไขของโจทย์ดูละกัน
ทอง 0 3 2 1 0 4 0 0 0 3
เงิน 0 0 2 0 1 0 2 3 2 1
ทองแดง 0 1 0 3 0 0 2 1 0 0
ปีที่ 1 ปีที่ 2 ปีที่ 3 ปีที่ 4 ปีที่ 5 ปีที่ 6 ปีที่ 7 ปีที่ 8 ปีที่ 9 ปีที่ 10

คราวนี้ก็มาคิดกันต่อว่าโปรแกรมเราจะแบ่งออกเป็นสองส่วน เพื่อให้ง่ายขึ้น ก็คือ


• ส่วนแรก เราต้องหาว่าในแต่ละปีได้ผลรวมเท่าไหร่ (โดยคิดแบบถ่วงน้ําหนัก 4 : 2 : 1 ด้วย)
• ส่วนหลัง หาผลรวมของทุกๆ 3 ปี (และหาด้วยเลยว่าช่วงไหนที่ผลรวมมากที่สุด)

พอคิดอย่างนี้แล้วน่าจะทําให้ง่ายขึ้นนะ (รึเปล่า?) สังเกตว่าในส่วนหลังนั้น เราต้องใช้ผลรวมที่คิดของแต่ละปี


มาใช้ ซึ่งเป็นผลที่ได้จากการคํานวณในส่วนแรก แสดงว่าต้องมีการใช้ตัวแปรมาเก็บค่าไว้แหละน่า

คิดส่วนแรก
ตัวแปรที่เราจะสร้างขึ้น ก็คือตัวแปรชนิดอาร์เรย์ สําหรับเก็บผลรวมมูลค่าเหรียญในแต่ละปี ที่ได้จากการ
คํานวณสูตร (4 * เหรียญทอง) + (2 * เหรียญเงิน) + เหรียญทองแดง
ทอง 0 3 2 1 0 4 0 0 0 3
เงิน 0 0 2 0 1 0 2 3 2 1
ทองแดง 0 1 0 3 0 0 2 1 0 0
ผลรวม 0 13 12 7 2 16 6 7 4 14
ปีที่ 1 ปีที่ 2 ปีที่ 3 ปีที่ 4 ปีที่ 5 ปีที่ 6 ปีที่ 7 ปีที่ 8 ปีที่ 9 ปีที่ 10

ที่เราจําเป็นต้องใช้ก็มีเพียงข้อมูลในแถวผลรวม แถวนี้แถวเดียวเท่านั้น เพื่อมาคิดต่อในส่วนหลัง

คิดส่วนหลัง
นําแถวผลรวมมาบวกกันทีละ 3 ปี (ที่ต่อเนื่อง) โดยเริ่มจากปีที่ 1-3 ก่อน ดูว่าได้ผลรวมทั้ง 3 ปีเป็นเท่าไหร่
เก็บเอาไว้เป็นค่ามากสุดในขณะนี้ หลังจากนั้นก็ทําปีที่ 2-4 ดูว่าผลรวม 3 ปีนี้มากกว่าเดิมมั้ย ถ้ามากกว่าก็ให้
ถือว่าค่ามากสุดในขณะนี้เป็นช่วงปีที่ 2-4 วน loop ทําไปเรื่อยๆ จนถึงปีที่ 8-10 ซึ่งถือว่าเป็นช่วงปีสุดท้ายใน
การคํานวณ ลองไล่โปรแกรมดูจะได้ผลตามด้านล่างนี้ (ตัวหนาคือข้อมูล 3 ตัวที่กําลังพิจารณาอยู่)

ข้อมูล ผลรวม ค่ามากสุด ช่วงปีดีสุด


0 13 12 7 2 16 6 7 4 14 25 25 1-3
0 13 12 7 2 16 6 7 4 14 32 32 2-4
0 13 12 7 2 16 6 7 4 14 21 32 2-4
0 13 12 7 2 16 6 7 4 14 25 32 2-4
0 13 12 7 2 16 6 7 4 14 24 32 2-4
0 13 12 7 2 16 6 7 4 14 29 32 2-4
0 13 12 7 2 16 6 7 4 14 17 32 2-4
0 13 12 7 2 16 6 7 4 14 25 32 2-4
Quick guide to A+JAVA (PART I) 12

ลองเขียน loop ดังกล่าวคร่าวๆ เป็นภาษาที่เราเข้าใจ ก็น่าจะประมาณนี้แหละมั้ง

for ( เลือกปีแรกของช่วงออกมา ) {
หาผลรวมในช่วง 3 ปี เริ่มนับจากปีแรกที่เลือก ;
if ( ผลรวมตะกี้ > max ) {
max = ผลรวมตะกี้ ;
maxYear = ปีแรกของช่วง ;
}
}

จริงๆ แล้วในบรรทัดที่ให้ maxYear = ปีแรกของช่วง นั้นแทบไม่มีผลต่อการ loop ของโปรแกรมเลย แต่ว่า


จําเป็นต้องมี เพราะว่าคําตอบที่ต้องการนั้น ไม่ใช่มูลค่าผลรวมที่มากที่สุด แต่เป็นช่วงปีที่มากที่สุดต่างหาก
คราวนี้ก็ถึงเวลามาดูโค้ดโปรแกรมเต็มๆ กันซักที
import jlab.JLabIO;
public class Olympiad {
public static void main (String[] args) {
int gold, silver, bronze, max=0, maxYear;
int[] sum = new int[10];
// โปรแกรมส่วนแรก
for (int i = 0; i < 10; i++) {
gold = JLabIO.readInt(“ จํานวนเหรียญทองปีที่ “ + (i + 1) + “ = “);
silver = JLabIO.readInt(“จํานวนเหรียญเงินปีที่ “ + (i + 1) + “ = “);
bronze = JLabIO.readInt(“จํานวนเหรียญทองแดงปีที่ “ + (i + 1) + “ = “);
sum[i] = (4 * gold) + (2 * silver) + bronze;
}
// โปรแกรมส่วนหลัง
for (int i = 0; i < 8; i++) {
int sumRange = sum[i] + sum[i+1] + sum[i+2];
if (sumRange > max) {
max = sumRange;
maxYear = i + 1;
}
}
System.out.println(“ ช่วงปีที่ดีที่สุด คือช่วงปี “ + maxYear + “ ถึง “ + (maxYear + 2));
}
}

ฝากให้คิด
• ใน loop ของโปรแกรมส่วนหลัง ทําไมใน for ถึงใช้แค่ i < 8 ไม่ใช่ i < 10 ล่ะ?
• บรรทัดที่กําหนดให้ maxYear = i + 1 นั้น ทําไมต้อง บวกหนึ่ง ไปด้านหลังด้วย
• มันคือข้อสอบรอบคัดเลือก สสวท. คอมฯ ปี 50 ไม่ยากเกินไปใช่มั้ย
Quick guide to A+JAVA (PART I) 13

เทคนิคการใช้อาร์เรย์นั้น มีอีกเยอะมากๆ เนื่องจากมันอาจจะไม่ได้ใช้เป็นตัวเก็บข้อมูลดิบแต่เพียง


อย่างเดียว แต่สามารถประยุกต์ใช้ได้อีกหลายกรณี
ยกตัวอย่างเลยละกัน

แบบฝึกหัด
จงเขียนโปรแกรม รับ String เข้ามา แล้วนับว่ามีตัวอักษร A-Z อย่างละกี่ตัวโดยไม่สนใจว่าเป็นตัวเล็กตัว
ใหญ่ (ให้ถือว่าเป็นตัวอักษรตัวเดียวกัน) หากไม่มีตัวนั้นๆ ก็ไม่ต้องแสดงผลออกมา (ไม่สนจํานวนช่องว่าง)

ตัวอย่าง
> ระบุข้อความที่จะนับตัวอักษร = APLUSJAVA PROJECT
> ความถี่ตัวอักษรทั้งหมดมีดังต่อไปนี้
>A=3
>C=1
>E=1
>J=2
>L=1
>O=1
>P=2
>R=1
>S=1
>T=1
>U=1
>V=1

ด้านล่างนี้เป็นกระดาษลองทด (นะเออ)
Quick guide to A+JAVA (PART I) 14

แนวคิด
• ใส่ String คําหนึ่งลงไป
• วิ่งหาตัว A ใน String นั้น เจอกี่ตัวก็พิมพ์ออกมา
• วิ่งหาตัว B ใน String นั้น เจอกี่ตัวก็พิมพ์ออกมา
• …
• วิ่งหาตัว Z ใน String นั้น เจอกี่ตัวก็พิมพ์ออกมา

สําหรับโค้ดโปรแกรมของวิธีคิดแบบนี้ ให้ลองไปเขียนดูเองนะ จะไม่ขอเฉลย


สมมติให้ 1 วินาที คอมพิวเตอร์คิดได้ 1,000,000 คําสั่ง ถ้า String ของเรายาวซัก 1,000,000 ตัว
เราก็ต้องทําทั้งหมด A-Z = 26 รอบ x 1,000,000 ตัว = 26 วินาทีเลยทีเดียว
แต่มันมีเทคนิควิธีการคิดที่ดีกว่านี้ ซึ่งเราจะวิ่งเพียงแค่รอบเดียว หมายความว่า loop เข้าไปใน
String ยาว 1,000,000 ตัวอักษรทีเดียวแล้วก็ให้คําตอบได้เลยว่ามีตัวอักษรอะไรบ้าง อย่างละกี่ตัว ซึ่ง
หมายความว่าเราสามารถแก้ปัญหาเดียวกันได้ใน 1 วินาทีเท่านั้น น่าจะดีกว่า

แนวคิด (ของจริง)
• โจทย์ข้อนี้อยู่ในแบบฝึกหัดอาร์เรย์ แสดงว่าต้องมีอาร์เรย์มาใช้แน่ๆ แต่จะใช้ยังไงดีล่ะ
• มองภาพแบบนี้ดีมั้ย สมมติเรามีถัง 26 ใบ แต่ละใบมีป้ายตัวอักษร A-Z ตัวใดตัวหนึ่งแปะอยู่ (ไม่ซ้ํา)
• รับ String ยาวๆ นั้นเข้ามา
• ดูว่าตัวที่ 1 เป็นตัวอักษรอะไร แล้วก็โยนลงไปในถังที่แปะตัวอักษรตัวนั้นไว้
• ดูว่าตัวที่ 2 เป็นตัวอักษรอะไร แล้วก็โยนลงไปในถังที่แปะตัวอักษรตัวนั้นไว้
• …
• ทําจนครบความยาวของ String แบบนี้น่าจะเวิร์กนะ
• ว่าแต่ว่า เราจะมอง “ถัง” ในจินตนาการเมื่อกี้ ให้กลายเป็นอาร์เรย์ได้ยังไงล่ะ
• ให้โอกาสคิดอีกรอบหนึ่ง แล้วค่อยมาดูแนวคิดต่อไปละกัน

แนวคิด (รอบสุดท้าย)
• เราจะประกาศอาร์เรย์ count[] จํานวน 26 ช่อง (แทนถัง 26 ใบดังที่ว่ามา)
• ให้ถังของ A เป็นถังหมายเลข 0, ถัง B เป็นถังหมายเลข 1 … ถัง Z เป็นถังหมายเลข 25 (ไม่ใช่ 26)
• ใช้ความรู้เดิม (ก่อนมิดเทอม) ว่า ‘A’ – ‘A’ = 0 และ ‘B’ – ‘A’ = 1
• เราจึงสามารถอ้างถึงอาร์เรย์ได้ด้วยวิธีการ count[ ‘ตัวอักษรนั้น’ – ‘A’ ] จริงมั้ย?

เพิ่มเติม คอมพิวเตอร์เก็บอักขระ ‘A’ ด้วยตัวเลข 65 ดังนั้นสมมติว่าเราเอาอักขระ ‘D’ มาลบออกด้วย ‘A’ จะ


มีค่าเทียบเท่ากับการเอา 68 – 65 = 3 นั่นเอง การเรียก count[ ‘D’ – ‘A’ ] จึงเท่ากับการเรียก count[3]

สงสัยมั้ยว่า แล้วตอนแสดงผล เราจะทําการแสดงผลออกมาอย่างไรล่ะ ถ้าทําวิธีนี้


• เริ่มจากถังหมายเลข 0 (ถัง A) ก่อน ดูว่ามีทั้งหมดกี่ตัว
• ทําต่อไปยังถังหมายเลข 1 (ถัง B) ดูว่ามีทั้งหมดกี่ตัว
• … ทําไปเรื่อยๆ จนถึงถังหมายเลข 25 (ถัง Z) นั่นเอง

ข้อนี้อาจจะอธิบายยากหน่อย แต่อยากให้ลองอ่านโค้ดโปรแกรมเฉลยดู แล้วค่อยๆ ทําความเข้าใจจากโค้ด


โปรแกรมที่เฉลยละกันนะ
Quick guide to A+JAVA (PART I) 15

import jlab.JLabIO;

public class AlphabetFreq {


public static void main (String[] args) {
int[] count = new int[26];
// รับ String มาแล้วทําให้เป็นตัวใหญ่เอาไว้เลย
เพื่อให้ไม่มีปัญหาว่าตัวเล็กหรือตัวใหญ่
String name = JLabIO.readString(“ระบุข้อความที่จะนับตัวอักษร = “).toUpperCase();

// เริ่มทําทีละตัวอักษร จากตัวแรกจนถึงตัวสุดท้ายของ String


for (int i = 0; i < name.length(); i++) {
char tmp = name.charAt( i );
count[ tmp – ‘A’ ]++; // เพิ่มค่าในถังของตัวอักษรนั้นๆ (อธิบายไปแล้ว)
}

// เริ่มการแสดงผล โดยไล่จากถัง A, B, …, Z ถ้าถังไหนไม่มีเลยก็ไม่ต้องแสดงอะไร


for (int i = 0; i < 26; i++) {
if ( count[i] != 0 ) {
System.out.println( (char)(‘A’ + i) + “ = “ + count[i] );
}
}
}
}

สิง่ ที่ควรสังเกต
ลองแกไขบรรทัดแสดงผล System.out.println( (char)(‘A’ + i) + “ = “ + count[i] ) ใหเหลือแค
System.out.println( (‘A’ + i) + “ = “ + count[i] ) ดูวาผลลัพธที่ไดจะเปนอะไร เพราะเหตุใด?
Quick guide to A+JAVA (PART I) 16

แบบฝึกหัด
จงเขียนโปรแกรมเพื่อรับค่าจํานวนเต็มทั้งหมด 10 จํานวนเข้ามา หลังจากนั้นให้รับจํานวนเต็มอีกหนึ่งจํานวน
และตรวจสอบว่าจํานวนนี้มีอยู่ใน 10 จํานวนแรกหรือไม่ แสดงผลลัพธ์การค้นหาออกทางหน้าจอให้ผู้ใช้ทราบ

แนวคิด
• ประกาศอาร์เรย์ชนิด int ขนาด 10 ตัวไว้ก่อน
• วน loop ทั้งหมด 10 ครั้ง (จาก 0 ถึง 9) เพื่อรับจํานวนเต็มแต่ละจํานวนเข้ามา
• รับจํานวนเต็มอีกจํานวนหนึ่ง แล้วนําไปค้นในอาร์เรย์ที่ได้เก็บค่า 10 จํานวนเอาไว้แล้ว
• การเปรียบเทียบนั่นก็คือ ทําการ loop ในอาร์เรย์และตรวจสอบว่าค่า x[i] เท่ากับจํานวนนั้นหรือไม่

เฉลย
import jlab.JLabIO;
public class LinearSearch {
public static void main (String[] args) { x.length มีค่าเท่ากับ 10 ซึง่ คือขนาดของ
int[] x = new int[10]; อาร์เรย์ x นั่นเอง ระวัง อย่าสับสนกับ
int number; String ซึ่งใช้ length() มีวงเล็บด้วย
for (int i = 0; i < x.length; i++)
ใส่จํานวนเต็ม #” + (i + 1) + “ = “);
x[i] = JLabIO.readInt(“
number = JLabIO.readInt(“ใส่จํานวนที่ต้องการค้นหา = “);
if ( exists( x, number ) ) {
System.out.println(“ พบจํานวน “ + number + “ ในอาร์เรย์”);
} else {
System.out.println(“ ไม่พบจํานวน “ + number + “ ในอาร์เรย์”);
}
}
public static boolean exists (int[] x, int number) {
for (int i = 0; i < x.length; i++)
if ( x[i] == number) return true;
return false;
}
}

คําอธิบายโปรแกรม
• โปรแกรมนี้ต้องการจะสื่อว่า สามารถโยนค่าอาร์เรย์ทั้งแถวไปยัง Method อื่นได้เช่นเดียวกับข้อมูล
ชนิดอื่นๆ ซึ่งใน Method exists ที่เขียนขึ้นมาเพื่อรับค่าอาร์เรย์นั้น ก็ให้ใส่ int[] x เช่นเดียวกับการ
ประกาศตัวแปรชนิดอาร์เรย์ขึ้นมานั่นเอง
• ใน Method exists นั้น จะ loop เช็คว่า x[i] เท่ากับ number หรือไม่ ถ้าเท่ากันจะคืนค่า true และ
จบการทํางานของ Method ทันที (อาจจะไม่จําเป็นต้องตรวจสอบจนครบทั้ง 10 จํานวนก็ได้) แต่
หากว่าไม่มีจํานวนใดเท่ากับ number เลย ก็จะลงมาจนถึงคําสั่งคืนค่า false
• หากว่าโจทย์ข้อนี้แก้ไขจาก จํานวนเต็ม เป็น จํานวนจริง จะต้องแก้ส่วนใดของโปรแกรมบ้าง? (ระวัง)
• การใช้ x.length นั้นจะให้ค่า ขนาดของอาร์เรย์ x ซึ่งมีค่าเท่ากับ 10 (เราสามารถเขียน 10 ไปตรงๆ
ก็ได้แต่ว่าทําไมเราถึงไม่ควรทํา?)
Quick guide to A+JAVA (PART I) 17

แบบฝึกหัด
จงเขียนโปรแกรมรับค่าจํานวนแถวและจํานวนหลักของ Matrix หนึ่ง และรับค่า aij ซึ่งเป็นจํานวนเต็ม จน
ครบทุกตัวใน Matrix นั้น แล้วให้แสดงผล Matrix นั้นให้อยู่ในรูป Matrix n แถว m หลัก ตามที่ต้องการ

ตัวอย่าง
> จํานวนแถวที่ต้องการ = 2
> จํานวนหลักที่ต้องการ = 3
> a[0][0] = 1
> a[0][1] = 2
> a[0][2] = 3
> a[1][0] = 4
> a[1][1] = 5
> a[1][2] = 6
>
> เมตริกซ์ดังกล่าวคือ
>012
>345

ข้อที่ควรทราบ
ที่ผ่านมาเราเคยเขียนแต่โปรแกรมที่ใช้อาร์เรย์มิติเดียว (คือแถวเส้นตรงเดียว) แต่ในข้อนี้จําเป็นต้องใช้
อาร์เรย์ 2 มิติ (คือในรูปของเมตริกซ์นั่นเอง) โดยมีวิธีการประกาศดังนี้
int[][] x = new int [5][5]; ตามทันมั้ย
หมายถึงประกาศตัวแปร x เป็นอาร์เรย์ 2 มิติที่มีขนาด 5*5

ส่วนของโปรแกรมเฉลย

public static void main (String [] args) {


int n = JLabIO.readInt("จํานวนแถวที่ต้องการ = ");
int m = JLabIO.readInt("จํานวนหลักที่ต้องการ = ");
int[][] a = new int[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
a[i][j] = JLabIO.readInt("a[" + i + "][" + j + "] = ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
System.out.print(a[i][j] + " ");
System.out.println();
}
}
Quick guide to A+JAVA (PART I) 18

รูปแบบนี้ เป็นรูปแบบที่ง่ายที่สุดของการมองภาพอาร์เรย์ 2 มิติ ต่อไปนี้ให้มองอาร์เรย์ 2 มิติ เป็นรูปนี้แหละ


จะสามารถทําความเข้าใจได้ง่ายที่สุด ข้อต่อไปเลยนะ

แบบฝึกหัด
จงเขียนโปรแกรมรับค่าจํานวนแถวและจํานวนหลักของ Matrix A และรับค่า aij ซึ่งเป็นจํานวนเต็มจนครบ
และรับค่าจํานวนแถวและจํานวนหลักของ Matrix B และรับค่า bij ซึ่งเป็นจํานวนเต็มจนครบ จากนั้นให้
แสดงผล Matrix ผลลัพธ์ที่ได้จาก A+B แต่ถ้าบวกกันไม่ได้ ให้แสดงคําว่า “ไม่สามารถบวกกันได้”

ส่วนของโปรแกรมเฉลย

public static void main (String [] args) {


int n = JLabIO.readInt("จํานวนแถวที่ต้องการ = ");
int m = JLabIO.readInt("จํานวนหลักที่ต้องการ = ");
int[][] a = new int [n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
a[i][j] = JLabIO.readInt("a[" + i + "][" + j + "] = ");

int p = JLabIO.readInt( "จํานวนแถวที่ต้องการ = ");


int q = JLabIO.readInt("จํานวนหลักที่ต้องการ = ");
int[][] b = new int [p][q];
for (int i = 0; i < p; i++)
for (int j = 0; j < q; j++)
b[i][j] = JLabIO.readInt("b["+i+"]["+j+"] = ");

(
if n == p && m == q) {
( 0
for int i = ; i < n; i++) {
for (int j = 0; j < m; j++)
.
System out.print( (a[i][j] + b[i][j]) + " ");
.
System out.println();
}
} else {
.
System out.print( "ไม่สามารถบวกกันได้");
}
}
Quick guide to A+JAVA (PART I) 19

แบบฝึกหัด
จงเขียนโปรแกรมรับค่าจํานวนแถวและจํานวนหลักของ Matrix A และรับค่า aij ซึ่งเป็นจํานวนเต็มจนครบ
แล้วรับค่าจํานวนแถวและจํานวนหลักของ Matrix B และรับค่า bij ซึ่งเป็นจํานวนเต็มจนครบ จากนั้นให้หา
AxB ไม่ใช่ BxA นะ แต่หากคูณกันไม่ได้ ให้แสดงคําว่า “ไม่สามารถคูณกันได้”

ส่วนของโปรแกรมเฉลย

public static void main (String [] args) {


int n = JLabIO.readInt("จํานวนแถวที่ต้องการ = ");
int m = JLabIO.readInt("จํานวนหลักที่ต้องการ = ");
int[][] a = new int [n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
a[i][j] = JLabIO.readInt("a[" + i + "][" + j + "] = ");

int p = JLabIO.readInt( "จํานวนแถวที่ต้องการ = ");


int q = JLabIO.readInt("จํานวนหลักที่ต้องการ = ");
int[][] b = new int [p][q];
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++)
b[i][j] = JLabIO.readInt("b[" + I + "][" + j + "] = ");
}

int sum = ; 0
(
if m == p) {
( 0
for int i = ; i < n; i++) {
for (int j = 0; j < q; j++) {
sum = ; 0
( 0
for int k = ; k < m; k++)
sum += a[i][k] * b[k][j];
.
System out.print(sum + " ");
}
.
System out.println();
}
} else {
.
System out.print( "ไม่สามารถคูณกันได้");
}
}
Quick guide to A+JAVA (PART I) 20

Arrays Class
นอกจากนี้ ยังมีบาง Method ที่ภาษาจาว่าได้เขียนขึ้นมาเพื่ออํานวยความสะดวกในการใช้งานอาร์เรย์ ซึ่ง
เพื่อนๆ อาจจะได้ใช้ในการเขียนโปรแกรม (หากเค้าอนุญาตให้ใช้ได้) โดยการเรียกใช้ Method เหล่านี้นั้น
ต้องทําการ import เพิ่มเติม (ที่ส่วนหัวของโปรแกรม) นอกเหนือจากเดิมที่ import เพียง jlab.JLabIO
import jlab.JLabIO;
import java.util.Arrays;

Arrays.sort
Arrays.sort ( ตัวแปรอาร์เรย์, ตําแหน่งแรกที่จะเรียง, ตําแหน่งหลังจากตําแหน่งสุดท้ายที่เรียง )
ทําการเรียงลําดับข้อมูลในอาร์เรย์เสียใหม่ โดยเรียงลําดับจากน้อยไปมาก
int[] x = { 6, 3, 1, 7, 4, 9, 3 };
Arrays.sort( x , 1 , 4 );
for (int i = 0; i < x.length; i++)
System.out.print( x[i] + “ “ );

ผลลัพธ์
>6137493

Arrays.binarySearch ( ตัวแปรอาร์เรย์, ค่าที่ต้องการค้น )


ทําการค้นหาว่ามีค่าที่ต้องการค้นอยู่ในอาร์เรย์หรือไม่ และอยู่ตําแหน่ง (index) ที่เท่าใด โดยอาร์เรย์ที่จะทํา
การค้นนั้น ต้องเรียงลําดับมาก่อน (จากน้อยไปมาก) แต่หากว่าไม่พบจะคืนค่าออกมาเป็นค่าลบ
int[] x = { 2, 3, 5, 9, 14, 23, 99 };
System.out.println( Arrays.binarySearch(x, 5) );
System.out.println( Arrays.binarySearch(x, 8) );

ผลลัพธ์
>2
> -4

Arrays.equals ( ตัวแปรอาร์เรย์ที่หนึ่ง, ตัวแปรอาร์เรย์ที่สอง )


ทําการเปรียบเทียบว่าอาร์เรย์ทั้งสองแถวนั้นมีลักษณะเหมือนกันหรือไม่ (หมายความว่ามีขนาดเท่ากัน,
จํานวนข้อมูลชุดเดียวกัน, ลําดับเหมือนกัน)

int[] x = { 1, 3, 5, 7, 9, 12 };
int[] y = { 1, 3, 5, 7, 9, 12 };
int[] z = { 1, 3, 5, 7, 12, 9 };
System.out.println( Arrays.equals(x, y) );
System.out.println( Arrays.equals(x, z) );

ผลลัพธ์
> true
> false เรื่องที่ต้องอ่านเอง:
อาร์เรย์ของอาร์เรย์ (หน้า 44 ชีทจุฬา)

You might also like