ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 8430|ตอบกลับ: 0

[VB6/VB.NET] การตรวจสอบค่าที่ซ้ำกัน (Duplicate Value) แล้วเลือกคำตอบมาเพียงค่าเดียว

[คัดลอกลิงก์]

320

กระทู้

512

โพสต์

6583

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
6583



ข้อมูลใน Array ประกอบด้วย เช่น 1, 2, 3, 2, 3, 5, 4, 1, 5, 6, 3, 8, 5, 9
ให้ทำการตรวจสอบค่าที่ซ้ำ แล้วตัดออกให้เหลือเพียงค่าเดียว ส่วนค่าไม่ซ้ำกันเลยก็เก็บไว้
ดังนั้นตัวอย่างนี้จะได้คำตอบคือ 1, 2, 3, 5, 4, 6, 8, 9 (โดยยังไม่ต้องมีการจัดเรียงจากน้อยไปมาก หรือ มากไปน้อย)

โจทย์ข้อนี้แอดมินจะ นำเสนอวิธีการแก้ปัญหา 2 รูปแบบ โดยแบบแรกจะเป็นการใช้กระบวนการคิดแบบเป็นขั้นเป็นตอน หรือที่เราเรียกว่าอัลกอริทึ่ม (Algorithm) ซึ่งแอดมินใช้ VB6 มาเป็นตัวหลักในการแก้โจทย์นี้ เนื่องจาก VB6 ไม่ได้มี Class ไฮโซเลิศหรู แต่ก็ยังสามารถหาคำตอบออกมาได้เหมือนกัน โดยอาศัยแค่คำสั่งพื้นฐานง่ายๆทั่วไป แบบที่ 2 แอดมินจะใช้ความเก่ง หรือความเป็นสำเร็จรูปของตัวแปลภาษา ... แน่นอนว่า แบบที่ 2 จะหาคำตอบได้อย่างรวดเร็วกว่าแบบที่ 1 แต่นี่มันแค่โจทย์การบ้านส่งครู เพราะในโลกแห่งความเป็นจริง เราจะได้เจอกับเงื่อนไขที่สลับซับซ้อนมากไปกว่านี้ ต้องเจอกับ Array หลายมิติ เช่น การเช็คเวลาเข้าทำงานของพนักงาน ต้องตัดค่าที่ซ้ำออกไป แล้วเลือกค่าแรกออกมา ส่วนเวลาออก ต้องตัดค่าซ้ำออกไป แล้วเลือกเวลาสุดท้ายออกมาเพื่อเป็นคำตอบ ... การใช้ความเก่งของตัวแปลภาษา จะไม่สามารถตอบโจทย์ให้เราทั้งหมดได้เลย ...

นี่คือวิธีการคิดแบบแรก โดยการนำเอาคำตอบมาเก็บไว้ที่เดิม หรือ ตัวแปร Array เดิมของมัน นั่นแหละครับ เพื่อประหยัดพื้นที่หน่วยความจำ ... แอดมินพยายามยกตัวอย่าง และทำผังขั้นตอนออกมาให้ดูแบบง่ายๆ ทั้งนี้หากท่านต้องการทำความเข้าใจให้ได้อย่างลึกซึ้งดื่มด่ำ ต้องทำการ Debugger จากโค้ดโปรแกรมด้วยตัวเองครับผม ...

หลักการคิด ... โดยเราใช้ตัวอย่างง่ายๆ เช่น (1, 2, 3, 1, 4)

- ใช้ Nested Loop วนรอบ 2 รอบ โดยรอบนอกวนตามจำนวนค่าอินพุทที่มี นั่นคือจาก 0 - 4 (จำนวน 5 ตัว) ... รอบในวนตามการนับค่าไม่ซ้ำ ซึ่งเรายังไม่รู้ค่าที่แน่นอน แต่ใช้ตัวแปร OutLen เริ่มต้น = 0 เพื่อเริ่มต้นการนับขึ้นทีละ 1 ซึ่งตัวแปร OutLen จะมีความสำคัญอย่างมาก ...

- รอบที่ 1 ลูปนอก ให้นำค่าจากใน Array (เริ่มจาก Index = 0) ไปฝากไว้ตัวแปร CurValue ... (วงลูปใน) โดยที่รอบแรกจะต้องให้ค่านั้นมันอยู่ที่เดิม มีเทคนิคง่ายๆคือให้วงรอบ For เป็นเท็จ นั่นคือ
---- For j = 0 To (OutLen - 1) หรือ For j = 0 To -1 (เรานับขึ้นคือ Default จะเป็น Step +1) <-- เงื่อนไขเท็จ จะไม่เกิดการกระทำในลูป For

---- เพิ่มค่าให้กับ OutLen ขึ้นไป 1 ==> OutLen = 1

- รอบที่ 2 ลูปนอก ค่า i = 1, ดึงค่า 2 จาก Array ออกมา ไปเก็บไว้ที่ CurValue = 2 ... (วงลูปใน) จะทำการวนรอบ 1 รอบ เพราะ
---- For j = 0 To (OutLen - 1) หรือ For j = 0 To (1 - 1) ==> For j = 0 To (0) <-- เงื่อนไขจริง
---- If InputNumber(0) = CurValue Then หรือ If 1 = 2 Then <-- เงื่อนไขเท็จ ... จบการลูป เก็บ 2 ไว้ที่เดิม แล้วเพิ่มค่า OutLen ขึ้นไป +1 ==> OutLen = 2

- รอบที่ 3 ลูปนอก ค่า i = 2, ดึงค่า 3 จาก Array ออกมา ไปเก็บไว้ที่ CurValue = 3 ... (วงลูปใน) จะทำการวนรอบ 2 รอบ เพราะ
---- For j = 0 To (OutLen - 1) หรือ For j = 0 To (2 - 1) ==> For j = 0 To (1) <-- เงื่อนไขจริง
---- If InputNumber(0) = CurValue Then หรือ If 1 = 3 Then <-- เงื่อนไขเท็จ ... กลับไปวนลูปในอีกครั้ง ทำให้ j = 1
---- If InputNumber(1) = CurValue Then หรือ If 2 = 3 Then <-- เงื่อนไขเท็จ ... จบการลูป เก็บ 3 ไว้ที่เดิม แล้วเพิ่มค่า OutLen ขึ้นไป +1 ==> OutLen = 3

- รอบที่ 4 ลูปนอก ค่า i = 3, ดึงค่า 1 จาก Array ออกมา ไปเก็บไว้ที่ CurValue = 1 ... (วงลูปใน) จะทำการวนรอบ 3 รอบ เพราะ
---- For j = 0 To (OutLen - 1) หรือ For j = 0 To (3 - 1) ==> For j = 0 To (2) <-- เงื่อนไขจริง
---- If InputNumber(0) = CurValue Then หรือ If 1 = 1 Then <-- เงื่อนไขจริง คือมีการซ้ำ
-------- กำหนดให้ blnExist = True เพื่อไม่ให้เกิดการบวก OutLen ขึ้น 1 ตอนนี้ OutLen = 3 ตามเดิม
-------- จบการวนรอบลูปในด้วย Exit For ซึ่งภาษาอื่นไม่มีใช้ แต่เราใช้เทคนิคการบังคับให้จบลูปได้ด้วย
การให้เงื่อนไขเป็นเท็จ j = OutLen นั่นคือ 3 = 3 พอมันจะกลับขึ้นไปวนรอบทำให้ For j = 0 To (OutLen - 1) หรือ For 3 = (3 - 1) หรือ For 3 = (2) <-- เท็จ

- รอบที่ 5 ลูปนอก ค่า i = 4, ดึงค่า 4 จาก Array ออกมา ไปเก็บไว้ที่ CurValue = 4 ... (วงลูปใน) จะทำการวนรอบ 3 รอบ เพราะ OutLen = 3
---- For j = 0 To (OutLen - 1) หรือ For j = 0 To (3 - 1) ==> For j = 0 To (2) <-- เงื่อนไขจริง
---- If InputNumber(0) = CurValue Then หรือ If 1 = 4 Then <-- เงื่อนไขเท็จ ... กลับไปวนลูปในอีกครั้ง ทำให้ j = 1
---- If InputNumber(1) = CurValue Then หรือ If 2 = 4 Then <-- เงื่อนไขเท็จ ... กลับไปวนลูปในอีกครั้ง ทำให้ j = 2
---- If InputNumber(2) = CurValue Then หรือ If 3 = 4 Then <-- เงื่อนไขเท็จ ... จบการลูปจะทำการวนรอบ 3 รอบ แต่เก็บ 4 ไว้ที่ค่าอินเด็กซ์ OutLen กำหนด คือ OutLen = 3 ซึ่งเดิมช่องนี้เก็บค่า 1 ที่ซ้ำเอาไว้ ... ก่อนจบ OutLen + 1 ทำให้ได้ค่า OutLen = 4  

ดังนั้นเวลาเราเอาคำตอบออกมาจาก Array เดิม จะทำให้เหลือเพียง 4 ค่า นั่นคือ (1, 2, 3, 4) แต่อย่าลืมว่าเราเก็บค่าลง Array เริ่มต้นที่ค่าอินเด็กซ์ชี้ที่ 0 ดังนั้นเมื่อ OutLen = 4 ...  OutLen - 1 = 4 - 1 = 3 หรือให้นับจากอินเด็กซ์ 0 ถึง 3 หรือ For i = 0 To 3 ... จบ

มาดูโค้ดในส่วนของ VB6 ...
  1. ' / --------------------------------------------------------------------------------
  2. ' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
  3. ' / eMail : thongkorn@hotmail.com
  4. ' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
  5. ' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
  6. ' / Facebook: https://www.facebook.com/commonindy (Worldwide)
  7. ' / Purpose : Check for duplicate values.
  8. ' / Microsoft Visual Basic 6.0 (SP6)

  9. ' / This is open source code under @CopyLeft by Thongkorn Tubtimkrob.
  10. ' / You can modify and/or distribute without to inform the developer.
  11. ' / --------------------------------------------------------------------------------
  12. Option Explicit

  13. Sub DuplicateValueAlgorithm()
  14.         '// ชุดข้อมูลตัวเลขอินพุท
  15.         Dim InputNumber(7) As Integer
  16.         InputNumber(0) = 1
  17.         InputNumber(1) = 2
  18.         InputNumber(2) = 3
  19.         InputNumber(3) = 1
  20.         InputNumber(4) = 3
  21.         InputNumber(5) = 9
  22.         InputNumber(6) = 4
  23.         '// นับตามจำนวนคำตอบที่ได้
  24.         Dim OutLen As Integer
  25.         OutLen = 0
  26.         
  27.         Dim i As Integer
  28.         Dim j As Integer

  29.         '// ลูปตามจำนวนของอินพุท (ลบ 1 เพราะเราเริ่มนับจาก 0)
  30.         For i = 0 To UBound(InputNumber) - 1
  31.             '// หากมีค่าซ้ำกันให้เปลี่ยนเป็น True
  32.             Dim blnExist As Boolean
  33.             blnExist = False
  34.             '// นำค่าตัวเลขอินพุทแต่ละตัวเข้ามา ฝากไว้ในตัวแปร
  35.             Dim CurValue As Integer
  36.             CurValue = InputNumber(i)

  37.             '// ลูปตามจำนวน InputNumber (ลบ 1 เพราะเราเริ่มนับจาก 0)
  38.             '/ รอบแรกจะข้ามไป เพราะว่า j = 0 และ OutLen = 0 คือการเอาค่าแรกของมันมาเปรียบเทียบกันมันก็ต้องซ้ำอยู่แล้ว
  39.             For j = 0 To OutLen - 1
  40.                 '// เปรียบเทียบว่ามีค่าตรงกับค่าเดิมหรือไม่
  41.                 If InputNumber(j) = CurValue Then
  42.                     '// พบการซ้ำ ก็ต้องออกจากลูป
  43.                     blnExist = True
  44.                     '// ออกจากลูปเมื่อกำหนดให้ j = OutLen (เทคนิคของการบังคับออกจากลูป For โดยไม่ใช้ Exit For)
  45.                     j = OutLen '// หรือใช้ Exit For
  46.                     'Exit For
  47.                 End If
  48.             Next

  49.             '// หากไม่พบการซ้ำกัน ให้ใส่ค่าที่ตรวจสอบกลับเข้าไปใน Array ของตัวแปรเดิม (แต่ตำแหน่ง OutLen จะอยู่คนละที่กันแล้ว)
  50.             If Not blnExist Then
  51.                 '// เพิ่มตัวเลขที่พบกลับลงไปใน InputNumber
  52.                 InputNumber(OutLen) = CurValue
  53.                 '// เลื่อนตำแหน่งขึ้นไปอีก 1
  54.                 OutLen = OutLen + 1
  55.             End If
  56.         Next

  57.         '// แสดงผล
  58.         Dim s As String
  59.         s = ""
  60.         For i = 0 To OutLen - 1
  61.             s = s & InputNumber(i) & vbCrLf
  62.         Next
  63.         MsgBox (s)
  64.     End Sub

  65. Private Sub Form_Load()
  66.     Call DuplicateValueAlgorithm
  67.     End
  68. End Sub
คัดลอกไปที่คลิปบอร์ด

มาดูโค้ดของ VB .NET (2010) ...
  1. ' / --------------------------------------------------------------------------------
  2. ' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
  3. ' / eMail : thongkorn@hotmail.com
  4. ' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
  5. ' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
  6. ' / Facebook: https://www.facebook.com/commonindy (Worldwide)
  7. ' / Purpose : Check for duplicate values with two methods.
  8. ' / Microsoft Visual Basic .NET (2010) SP1

  9. ' / This is open source code under @CopyLeft by Thongkorn Tubtimkrob.
  10. ' / You can modify and/or distribute without to inform the developer.
  11. ' / --------------------------------------------------------------------------------

  12. Public Class Form1

  13.     Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  14.         Call DuplicateValueAlgorithm()
  15.         Call DuplicateValueLanguage()
  16.         End
  17.     End Sub

  18.     ' / --------------------------------------------------------------------------------
  19.     ' / การใช้ทักษะพื้นฐานทางด้านโปรแกรมมิ่ง และกระบวนการคิด (Algorithm)
  20.     ' / โดยเราจะเอาคำตอบกลับมาเก็บไว้ที่อินพุทแบบ Array ตามเดิม
  21.     Sub DuplicateValueAlgorithm()
  22.         '// ชุดข้อมูลตัวเลขอินพุท (เวลาทดสอบจริงไม่ต้องยาวก็ได้ เช่น {1, 2, 3, 1, 4})
  23.         'Dim InputNumber() As Integer = {1, 2, 3, 1, 4}
  24.         Dim InputNumber() As Integer = {1, 2, 3, 2, 3, 5, 4, 1, 5, 6, 3, 8, 5, 9}
  25.         '// นับตามจำนวนคำตอบที่ได้
  26.         Dim OutLen As Integer = 0

  27.         '// ลูปตามจำนวนของอินพุท (ลบ 1 เพราะเราเริ่มนับจาก 0)
  28.         For i As Integer = 0 To InputNumber.Length - 1
  29.             '// หากมีค่าซ้ำกันให้เปลี่ยนเป็น True
  30.             Dim blnExist As Boolean = False
  31.             '// นำค่าตัวเลขอินพุทแต่ละตัวเข้ามา ฝากไว้ในตัวแปร
  32.             Dim CurValue As Integer = InputNumber(i)

  33.             '// ลูปตามจำนวน InputNumber (ลบ 1 เพราะเราเริ่มนับจาก 0)
  34.             '/ รอบแรกจะข้ามไป เพราะว่า j = 0 และ OutLen = 0 คือการเอาค่าแรกของมันมาเปรียบเทียบกันมันก็ต้องซ้ำอยู่แล้ว
  35.             For j As Integer = 0 To OutLen - 1
  36.                 '// เปรียบเทียบว่ามีค่าตรงกับค่าเดิมหรือไม่
  37.                 If InputNumber(j) = CurValue Then
  38.                     '// พบการซ้ำ ก็ต้องออกจากลูป
  39.                     blnExist = True
  40.                     '// ออกจากลูปเมื่อกำหนดให้ j = OutLen (เทคนิคของการบังคับออกจากลูป For โดยไม่ใช้ Exit For)
  41.                     j = OutLen '// หรือใช้ Exit For
  42.                 End If
  43.             Next

  44.             '// หากไม่พบการซ้ำกัน ให้ใส่ค่าที่ตรวจสอบกลับเข้าไปใน Array ของตัวแปรเดิม (แต่ตำแหน่ง OutLen จะอยู่คนละที่กันแล้ว)
  45.             If Not blnExist Then
  46.                 '// เพิ่มตัวเลขที่พบกลับลงไปใน InputNumber
  47.                 InputNumber(OutLen) = CurValue
  48.                 '// เลื่อนตำแหน่งขึ้นไปอีก 1
  49.                 OutLen += 1
  50.             End If
  51.         Next

  52.         '// แสดงผล
  53.         Dim s As String = String.Empty
  54.         For i As Integer = 0 To OutLen - 1
  55.             s = s & InputNumber(i) & vbCrLf
  56.         Next
  57.         MsgBox(s)
  58.     End Sub

  59.     ' / --------------------------------------------------------------------------------
  60.     ' / การใช้ความเก่งของตัวแปลภาษา
  61.     Sub DuplicateValueLanguage()
  62.         '// สร้าง List และข้อมูลตัวอย่าง
  63.         Dim InList As New List(Of Integer)(New Integer() {1, 2, 3, 2, 3, 5, 4, 1, 5, 6, 3, 8, 5, 9})
  64.         '// กรองข้อมูลที่ซ้ำ (Distinct) แล้วเอามันกลับไปเก็บไว้ใน List
  65.         Dim OutList As List(Of Integer) = InList.Distinct().ToList
  66.         '// แสดงผล
  67.         Dim s As String = String.Empty
  68.         For Each CurValue As Integer In OutList
  69.             s = s & CurValue & vbCrLf
  70.         Next
  71.         MsgBox(s)
  72.     End Sub
  73. End Class
คัดลอกไปที่คลิปบอร์ด

Conclusion: หลายคนอาจจะมองว่าโค้ดสั้นๆมันมี Performance ที่สูงกว่า ลดบั๊กหรือความผิดพลาดลงไปได้เยอะ แต่เชื่อแอดมินเถอะครับ กับงานจริงๆเราไม่ได้หาคำตอบง่ายๆแบบนี้ออกมา เพราะมันจะมีเงื่อนไข ตรรกะ จุกจิกอีกเยอะแยะมากมาย สำหรับคนที่พึ่งเริ่มฝึกเขียนโปรแกรม ก็จงพยายามคิดก่อนที่จะเขียนโปรแกรม ดังวิธีการคิดในแบบแรก เราไม่จำเป็นต้องเปิดหนังสือ และไม่ต้องไปค้นหาในเน็ต แต่ใช้กระบวนการคิดแบบเป็นขั้นเป็นตอน และที่สำคัญคือ วิธีการคิดแบบนี้ไม่ขึ้นกับภาษาใดๆ ... สวัสดี

ดาวน์โหลดโค้ดต้นฉบับ VB6 และ VB .NET (2010) ได้ที่นี่ ...

ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2024-11-27 23:39 , Processed in 0.163883 second(s), 4 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้