แสดงบทความที่มีป้ายกำกับ stack แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ stack แสดงบทความทั้งหมด

วันพุธที่ 27 พฤศจิกายน พ.ศ. 2556

แปลงเลขฐานแปดเป็นเลขฐานสองด้วยสแตก (Convert octal number to binary number with Stack by Java)

วิธีการในการแปลงเลขฐานนั้นมีหลากหลายวิธี วันนี้จะขอเสนอวิธีการแปลงด้วยสแตก สำหรับการสร้างแสตกสามารถเข้าไปอ่านได้ที่ สร้าง Stack ด้วยภาษา Java (Linked List Implementation) ซึ่งเป็นการสร้างสแตกโดยใช้ Linked List เก็บข้อมูล 

สำหรับวิธีการนี้จะมีขั้นตอนดังนี้

  1. รับตัวเลขฐานแปดเข้ามา
  2. อ่านเลขฐานแปดที่ละตัวจากด้านขวามือ(LSB) มองว่าเลขฐานแปดแต่ละตัวนั้นเป็นเลขฐานสิบ
  3. นำเข้าไปแปลงจากเลขฐานสิบเป็นฐานสอง
  4. เก็บค่าลงสแตกตามลำดับ
  5. กลับไปทำขั้นตอนที่ 2 จนกว่าจะแปลงเลขฐานแปดครบทุกตัว
  6. แสดงค่าทั้งหมดในสแตกก็จะได้การแปลงเลขฐานแปดเป็นเลขฐานสอง
ตัวอย่างเช่น

เลขฐานแปด คือ 416
ทำตามขั้นตอนด้านบนจะได้ว่า
  • รอบที่ 1 พิจารณา 6 สามารถแปลงเป็นเลขฐานสองได้เป็น 110 ก็จะถูกเก็บในสแตกดังนี้


  • รอบที่ 2 พิจารณา 1 สามารถแปลงเป็นเลขฐานสองได้เป็น 001 ก็จะถูกเก็บในสแตกดังนี้


  • และรอบที่ 3 พิจารณา 4 สามารถแปลงเป็นเลขฐานสองได้เป็น 100 ก็จะถูกเก็บในสแตกได้ดังนี้


  • จากนั้นทำการแสดงค่าทั้งหมดในสแตกก็จะได้ผลลัพธ์เป็น 100001110
วิธีการเขียนโค๊ดคือ
  1. ไฟล์ Node.java คือการกำหนดว่าจะให้แต่ละโหนดเก็บค่าอะไร ในที่นี้ก็จะให้เก็บค่าเป็น integer
  2. ไฟล์ Stack.java คือการสร้างเมธอดต่างๆ ที่สำคัญของการใช้สแตก
  3. ไฟล์ ConvertOctalToBinary.java คือไฟล์สำหรับทำตามกระบวนการด้านบน
ไฟล์ ConvertOctalToBinary.java มีโค๊ดดังนี้

public class ConvertOctalToBinary {
public static void main(String... args) {
Stack stack = new Stack();
String octal = "416";
for (int i = octal.length() - 1; i >= 0; i--) {
char facOctNumChar = octal.charAt(i);
String facOctNumStr = String.valueOf(facOctNumChar);
int number = Integer.parseInt(facOctNumStr);
// int number = Integer.parseInt(String.valueOf(octal.charAt(i)));

int countBit = 0;

while (number > 0) {
int bit = number % 2;
stack.push(bit);
number = number / 2;
countBit++;
}
if (countBit < 3) {
for (int j = countBit; j < 3; j++) {
stack.push(0);
}
}
}

System.out.print("Octal number is " + octal + " convert to binary number is ");

while (!stack.isEmptyStack()) {
try {
System.out.print(stack.peek());
stack.pop();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}

อธิบายโค๊ด
  • เมื่อเริ่มต้น for loop ก็จะพิจารณาตัวเลขฐานแปดที่ละตัวแล้วจับโยนเข้าไปที่ while loop เพื่อหาว่าเป็นเลขฐานสองคืออะไร
  • จากนั้นนำเลขที่ได้ใส่ในสแตกที่เตรียมไว้ จนจบ while loop
  • จากนั้นถามว่าในลูปที่ผ่านมาใส่ค่าในสแตกครบ 3 ค่าหรือยัง ทำไมต้อง 3 ค่า?
  • เพราะว่าในการเก็บค่าเลขฐานแปดให้อยู่ในรูปของเลขฐานสองนั้น ต้องใช้เลขฐานสอง 3 bit ดังนั้นจึงต้องตรวจสอบว่าครบ 3 ค่าหรือยัง นั่นก็คือครบ 3 bit หรือยังนั่นเอง หากยังไม่ครบก็จะเติม bit 0 ให้ครบ 3 bit
  • เมื่อทำไปเรื่อยๆ จนหลุดจาก for loop ก็จะสาแสดงค่าทั้งหมดที่อยู่ในสแตก ก็จะได้ผลลัพธ์ที่สวยงาม
ถามว่ายังมีวิธีอื่นอีกมั้ย ตอบได้ว่ามีครับ อีกวิธีการหนึ่งที่คล้ายๆกันคือ คล้ายกันตรงที่จะแปลงเลขฐานสิบเป็นฐานสอง แต่ไม่ได้แปลงทีละตัวอย่างที่แสดงให้ดูในตอนต้น แต่จะแปลงเลขก้อนเดียวเดียวจบได้เลขฐานแปดในรูปแบบเลขฐานสองเลย วิธีการคือ
  1. รับตัวเลขฐานแปดเข้ามา
  2. อ่านเลขฐานแปดทีละตัวจากด้านขวามือ(LSB) จากนั้นทำการแปลงเลขฐานแปดให้เป็นเลขฐานสิบโดยใช้ค่าประจำหลักของเลขฐานแปด
  3. บวกสะสมค่าที่ได้จากการแปลงเป็นเลขฐานสิบ
  4. นำเลขฐานสิบที่ได้ไปแปลงเป็นเลขฐานสองอีกครั้ง
  5. ก็จะได้ผลลัพธ์ที่ต้องการ
หมายเหตุ อาจจะได้ผลลัพธ์ไม่เหมือนวิธีด้านบนทั้งหมด เพราะอาจจะมีการแปลงบางค่าที่ได้จำนวน bit ไม่ครบ 3 bit

ตัวอย่างเช่น
เลขฐานแปด คือ 416
แปลงเป็นเลขฐานสิบโดยใช้ค่าประจำหลักจะได้เป็น
(6 * 8^0)+(1 * 8^1)+(4 * 8^2) = 6 + 8 + 256 = 270
จากนั้นแปลงเลข 270 ที่เป็นเลขฐานสิบให้เป็นเลขฐานสอง จะได้ผลลัพธ์เป็น 100001110

ผลลัพธ์ที่ได้จากทั้งสองวิธีได้เท่ากัน แล้วแต่จะเลือกวิธีการที่ชอบ

หวังว่าคงจะเป็นประโยชน์นะครับ

ดาวน์โหลดโค๊ดเต็มได้ที่นี่

วันพฤหัสบดีที่ 3 ตุลาคม พ.ศ. 2556

สร้าง Stack ด้วยภาษา Java (Stack Linked List Implementation)

สืบเนื่องจากบล็กที่แล้วเขียนถึงเรื่อง สร้าง Stack ด้วยภาษา Java (Array Implementation) สำหรับบล็อกนี้จะมาสร้าง Stack เหมือนกัน แต่ใช้ Linked List มาใช้ในการเก็บข้อมูลแทน Array จะเป็นยังไง เชิญด้านล่างเลย

อันดับแรก ต้องสร้างไฟล์ Node.java ขึ้นมาก่อน ซึ่งเขียนโค๊ดได้ดังนี้


อธิบายรูปดังนี้
  • บบรทัดที่ 2-3 คือ Attributes ของคลาสซึ่งหมายถึงว่าในโหนดใดๆจะมีข้อมูลอะไรบ้าง และที่ขาดไม่ได้คือ Node link เพราะเป็นการเชื่อมไปยังโหนดถัดไป
  • บรรทัดที่ 5-16 คือ การสร้าง Constructor Method ซึ่งมีอยู่ 3 แบบด้วยกัน ซึ่งแล้วแต่เราจะออกแบบครับ
  • บรรทัดที่ 18-32 คือ การสร้าง Getters Setters Method ให้กับ Attributes ของคลาส
อันดับต่อไป ต้องสร้างไฟล์ Stack.java ซึ่งเขียนโค๊ดได้ดังนี้


อธิบายรูปดังนี้
  • บรรทัดที่ 1 คือการสร้างโหนดเปล่าขึ้นมาเพื่อเอาไว้สำหรับชี้ที่โหนดล่าสุดที่เข้าไปในสแตก นั่นคือ top of stack
  • บรรทัดที่ 12-14 คือเมธอดสำหรับการตรวจสอบว่าสแตกว่างใช่หรือไม่ โดยตรวจสอบที่ Node stackTop ว่าว่างหรือไม่
  • บรรทัดที่ 16-18 คือเมธอดสำหรับตรวจสอบว่าสแตกเต็มหรือไม่ แต่เราสร้างสแตกด้วยลิงค์ลิสต์ดังนั้นสแตกจึงไม่มีทางเต็ม จึงคืนค่าเป็น false
  • บรรทัดที่ 20-24 คือเมธอดสำหรับการนำข้อมูลใส่ในสแตก ซึ่งมีลักษณะคล้ายกับการใช้เมธอด insertHead ของ Linked List


อธิบายรูปดังนี้
  • บรรทัดที่ 26-30 คือเมธอดสำหรับการดูค่าที่ตำแหน่ง top of stack
  • บรรทัดที่ 32-39 คือเมธอดสำหรับการนำค่าที่อยู่ตำแหน่ง top of stack ออกจากสแตก ซึ่งมีลักษณะคล้ายกับการใช้เมธอด deleteHead ของ Linked List


อธิบายรูปดังนี้
  • บรรทัดที่ 41-60 คือ main method ที่ทำการสร้างสแตกมา 2 อัน และทำการทดลองเรียกใช้เมธอดต่างไที่ได้สร้างไว้

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

สามารถดาวน์โหลดไฟล์ทั้งสองได้ที่นี่ครับ

วันพฤหัสบดีที่ 19 กันยายน พ.ศ. 2556

สร้าง Stack ด้วยภาษา Java (Stack Array Implementation)

จากบล็อกที่แล้วเขียนถึงเรื่อง Linked List สำหรับบล็อกนี้จะเขียนเกี่ยวกับโครงสร้างข้อมูลแบบง่ายอีกแบบหนึ่งที่น่าจะได้เรียนหรือเคยได้ยินมาก่อนบ้างนั่นคือ Stack

Stack ก็เป็นโครงสร้างข้อมูลอีกแบบหนึ่งที่สามารถช่วยให้สามารถจัดเก็บข้อมูลได้ และสามารถนำไปประยุกต์ใช้กับโปรแกรมอื่นๆได้ เช่น Balancing Symbols, Postfix Expression Calculator เป็นต้น

หลักการทำงานของ Stack เป็นหลักการง่ายๆคือ ข้อมูลที่เข้าหลังสุดจะถูกนำออกก่อน (Last Input First Output: LIFO)

โอเปอเรชันที่สำคัญของ Stack มีอยู่ 3 โอเปอเรเตอร์ ประกอบด้วย
  1. Push คือโอเปอเรชันที่ใช้สำหรับการเพิ่มข้อมูลไปยัง Stack
  2. Pop คือโอเปอเรชันที่ใช้สำหรับการลบข้อมูลจาก Stack
  3. Peek คือโอเปอเรชันที่ใช้สำหรับการดูข้อมูลที่ตำแหน่งบนสุดของ Stack นั่นคือดูข้อมูลล่าสุดที่เพิ่มเข้าไป
ในการสร้างสแตกสามารถสร้างได้จากอาร์เรย์ก็ได้ หรือสามารถใช้ Linked List ก็ได้ แต่สำหรับบล็อกนี้จะแสดงการสร้างสแตกโดยใช้อาร์เรย์

อันดับแรกก็สร้าง class Stack ขึ้นมาก่อน โดยมี Attribute ของคลาสดังรูป


อธิบายรูปคือ 
  • บรรทัดที่ 3 คือขนาดของสแตกโดยมีค่าเริ่มต้นอยู่ที่ 100 แต่สามารถกำหนดเองได้
  • บรรทัดที่ 4 คือตำแหน่งของข้อมูลที่เป็น top of stack
  • บรรทัดที่ 5 คืออาร์เรย์ที่ใช้เก็บข้อมูลเป็นชนิดข้อมูลใดก็ได้ เช่น int, float, long, double, char, String
ต่อไปเป็นการสร้างเมธอดที่จำเป็นต้องใช้ซึ่งประกอบด้วย

1. Stack() -> constructor method เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 7-9 เป็นการสร้าง constructor method โดยไม่มีพารามิเตอร์ และสร้างอารย์ของ Object ให้มีขนาดเท่ากับ maxStackSize
  • บรรทัดที่ 11-14 เป็นการสร้าง constructor method โดยรับพารามิเตอร์หนึ่งค่าคือ size ขนาดของสแตกที่ต้องการ แล้วสร้างอารย์ของ Object ให้มีขนาดเท่ากับ size ที่รับเข้ามา และกำหนดค่า size ให้กับ maxStackSize
2. initializeValueStack() เป็นเมธอดสำหรับกำหนดค่าเริ่มต้นให้กับอาร์เรย์ เขียนโค๊ดได้ดังนี้



อธิบายรูปคือ
  • บรรทัดที่ 17-18 เป็นการกำหนดค่า null ให้กับอาร์เรย์ทั้งหมดที่จะใช้เก็บข้อมูล
  • บรรทัดที่ 19 กำหนดให้ตำแหน่งของข้อมูล top of stack เท่ากับศูนย์
3. isEmpty() เป็นเมธอดสำหรับตรวจสอบว่าสแตกไม่มีข้อมูลใดๆ เลยใช่หรือไม่ โดยมี return type คือ boolean เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 23 คือการรีเทิร์นค่าที่ได้จากการตรวจสอบเงื่อนไข stackTop == 0 ถ้าเงื่อนไขนี้เป็นจริงจะรีเทิร์นค่า true และถ้าไม่จริงจะรีเทิร์นค่า false
4. isFull() เป็นเมธอดสำหรับตรวจสอบว่าสแตกเต็มหรือไม่  โดยมี return type คือ boolean เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 27 คือการรีเทิร์นค่าที่ได้จากการตรวจสอบเงื่อนไข stackTop == maxStackSize ถ้าเงื่อนไขนี้เป็นจริงจะรีเทิร์นค่า true และถ้าไม่จริงจะรีเทิร์นค่า false
5. push() เป็นเมธอดสำหรับการเพิ่มข้อมูลไปยังสแตก โดยมรการรับพารามเตอร์หนึ่งตัวคือ Object newItem เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 31-32 ตรวจสอบว่าสแตกเต็มหรือไม่ หากสแตกเต็มแล้วจะหยุดการทำงาน และแสดงคำว่า StackOverflow ออกทาง Console
  • บรรทัดที่ 33-34 เป็นผลมาจากการตรวจสอบเงื่อนไขด้านบน หากเงื่อนไขบนไม่เป็นจริง ก็จะกำหนดค่า newItem ลงในอาร์เรย์ตำแหน่งที่ stackTop และเพิ่มค่า stackTopไปอีกหนึ่ง เพื่อไปชี้ยังตำแหน่งถัดไปของอาร์เรย์
6. pop() เป็นเมธอดสำหรับการลบข้อมูลจากสแตก เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 44-45 ตรวจสอบว่าสแตกว่างหรือไม่ หากสแตกว่างไม่มีข้อมูลจะหยุดการทำงาน และแสดงคำว่า StackUnderflow ออกทาง Console
  • บรรทัดที่ 46-47 เป็นผลมาจากการตรวจสอบเงื่อนไขด้านบน หากเงื่อนไขบนไม่เป็นจริง ก็จะลดค่า stackTop ลงหนึ่งค่า แล้วกำหนดค่าให้ข้อมูลในอาร์เรย์ตำแหน่งที่ stackTop ชี้อยู่มีค่าเท่ากับ null
7. peek() เป็นเมธอดสำหรับการดูข้อมูลที่ตำแหน่งบนสุดของสแตก นั่นคือดูข้อมูลล่าสุดที่เพิ่มเข้าไป โดยมี return type คือ Object เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 38-39 ตรวจสอบว่าสแตกว่างหรือไม่ หากสแตกว่างไม่มีข้อมูลจะหยุดการทำงาน และแสดงคำว่า StackUnderflow ออกทาง Console
  • บรรทัดที่ 40 เป็นผลมาจากการตรวจสอบเงื่อนไขด้านบน หากเงื่อนไขบนไม่เป็นจริง ก็จะรีเทิร์นข้อมูลในอาร์เรย์ตำแหน่งที่ stackTop ชี้อยู่ แต่จากโค๊ดจะเห็นค่าต้องลบหนึ่งด้วย เพราะอินเด็กของอาร์เรย์ให้เริ่มที่ศูนย์
8. main() เป็นเมธอดสำหรับการเรียกใช้เมธอดอื่นๆ เขียนโค๊ดได้ดังนี้


อธิบายรูปคือ
  • บรรทัดที่ 50 สร้าง object s1  โดยใช้ constructor method แบบไม่มีพารามิเตอร์ จึงทำให้สแตกมีขนาดเท่ากับ 100 และสร้าง object s2 โดยใช้ constructor method แบบมีพารามิเตอร์ โดยส่งค่า 50 จึงทำให้สแตกมีขนาด 50
  • บรรทัดที่ 52-53 เรียกใช้เมธอด initializeValueStack() ทั้งสองออปเจ็ค
  • บรรทัดที่ 55-60 การเพิ่มค่าไปยังสแตก โดยพบว่าเพิ่มข้อมูลที่มีประเภทแตกต่างกันไปยังสแตกเดียวกันได้
  • บรรทัดที่ 61-68 พยายามแสดงค่าที่อยู่ที่ top of stack โดยใช้เมธอด peek() และลบข้อมูลที่อยู่ที่ตำแหน่ง top of stack โดยใช้เมธอด pop()

จากการยกตัวอย่างทั้งหมดนี้ทำให้สามรถสร้างสแตกอย่างง่ายขึ้นมมาใช้งานได้ และสามารถนำไปประยุกต์กับงานอื่นๆได้

โต๊ดสมบูรณ์สามารถดาวน์โหลดได้ที่นี่