String แบบ Beginner-First: จากพื้นฐานถึงเทคนิคที่ใช้บ่อย
บทนี้รวบรวมพื้นฐาน String แบบเรียงลำดับเป็นขั้น เริ่มจากความหมาย การใช้งาน ฟังก์ชันพื้นฐาน ไปจนถึง pattern สำคัญอย่าง Hash Map, Two Pointers และ Sliding Window
1) String คืออะไร
String คือข้อมูลชนิดข้อความ เช่น ชื่อ, อีเมล, URL หรือประโยค โดยมองเป็นลำดับของตัวอักษรที่อ่านจากซ้ายไปขวา
Recap: ถ้าข้อมูลเป็นข้อความ จุดเริ่มต้นส่วนใหญ่คือ String
2) String ต่างจาก Array ยังไง
String
เป็นลำดับของ character และใน JavaScript แก้ไขตัวอักษรเดิมโดยตรงไม่ได้
Array
เก็บข้อมูลได้หลายชนิด และมีเมธอดที่ mutate โครงสร้างได้ตรง ๆ
Recap: ทั้งคู่เข้าถึงด้วย index ได้ แต่ธรรมชาติการแก้ข้อมูลไม่เหมือนกัน
3) การเก็บข้อมูลของ String
ให้คิดว่า String เป็น sequence ของตัวอักษรที่เรียงต่อกัน และระบบต้องรู้ตำแหน่งของแต่ละตัวอักษรเพื่อเข้าถึงผ่าน index
Recap: ภาพจำที่ดีคือ ข้อความเท่ากับช่องตัวอักษรที่เรียงต่อกัน
4) Character คืออะไร
Character คือหน่วยตัวอักษรเดี่ยว เช่น `a`, `Z`, `1`, หรือสัญลักษณ์ อย่าง `?` และช่องว่าง
อ่าน character เดี่ยวจาก String
Recap: String คือชุดของ character หลายตัวต่อกัน
5) การเข้าถึงตัวอักษรด้วย index
index เริ่มที่ 0 และเกินขอบเขตจะได้ undefined
Recap: อ่านตัวอักษรตามตำแหน่งเป็น O(1)
6) การวนลูป String
ใช้ for เมื่อต้องการ index และใช้ for...of เมื่อต้องการค่า
Recap: วนอ่านทั้ง String เป็น O(n)
7) การหาความยาวของ String
ใช้ property `.length`
Recap: `.length` เป็น operation ที่เร็วและใช้บ่อยมาก
8) การเปรียบเทียบ String
เปรียบเทียบแบบไม่สนตัวพิมพ์ต้อง normalize ก่อน
Recap: ก่อน compare ให้คิดเรื่อง case sensitivity ทุกครั้ง
9) การต่อ String (concatenation)
ใช้ `+` หรือ template string
Recap: การต่อข้อความใหม่สร้าง String ใหม่ ไม่ได้แก้ค่าเดิม
10) การตัด String
ตัดช่วงตัวอักษรออกมาเป็น String ใหม่
Recap: `slice` เหมาะกับงานแบ่งข้อความตามช่วง index
11) การค้นหาตัวอักษรหรือคำใน String
เมธอดพื้นฐาน: includes, indexOf
Recap: ไม่เจอค่ามักคืน `false` หรือ `-1` แล้วแต่เมธอด
12) การแทนที่ข้อความใน String
แทนที่ข้อความและได้ String ใหม่
Recap: `replace` ไม่ mutate string เดิม
13) การแปลงตัวพิมพ์เล็ก / พิมพ์ใหญ่
ใช้ normalize ก่อน compare หรือ count
Recap: normalization ช่วยลดบั๊กเวลาข้อมูลเข้ามาหลากหลายรูปแบบ
14) การลบช่องว่าง
ลบช่องว่างหัวท้าย
Recap: ก่อน validate input ควร trim เสมอ
15) การแยก String (split)
แปลงข้อความให้เป็น array ด้วยตัวคั่น
Recap: `split` เป็นสะพานสำคัญระหว่าง String และ Array
16) การรวม String (join)
รวม array ของข้อความเป็น String เดียว
Recap: เมื่อต้องประกอบข้อความยาว คิดถึง `join` ก่อน `+=` ในลูป
17) String immutable คืออะไร
การแก้ข้อความจริง ๆ คือการสร้างค่าใหม่
Recap: String เปลี่ยนไม่ได้ที่เดิม ต้องสร้าง String ใหม่เสมอ
18) String mutable vs immutable
Mutable
แก้ค่า object เดิมได้ตรง ๆ (เช่น array methods บางตัว)
Immutable
ไม่แก้ของเดิม สร้างค่าใหม่แทน (String อยู่ฝั่งนี้)
Recap: เข้าใจจุดนี้จะช่วยลดบั๊กจากการคาดหวังผิดเกี่ยวกับการแก้ค่า
19) Time Complexity พื้นฐานของการทำงานกับ String
เข้าถึงตัวอักษรด้วย index
O(1)
อ่านความยาว (length)
O(1)
วนลูปอ่านทั้งข้อความ
O(n)
เปรียบเทียบ 2 string
O(min(n, m)) ถึง O(n)
concatenation
O(n + m)
slice / substring
O(k)
split
O(n)
replace (ทั่วไป)
O(n)
Recap: งานที่ต้องอ่านหลายตัวอักษรมักโตตาม n
20) การนับความถี่ตัวอักษร
พื้นฐานสำคัญของหลายโจทย์ String
Recap: pattern นี้คือฐานของโจทย์ anagram และ counting หลายแบบ
21) การตรวจ palindrome
ใช้ two pointers เทียบหัว-ท้าย
Recap: palindrome เป็นโจทย์ฝึก two pointers ที่ดีมาก
22) การกลับ String
วิธีพื้นฐานที่อ่านง่ายและเข้าใจเร็ว
Recap: ใช้ split แล้ว reverse แล้ว join เป็น pattern พื้นฐานที่ใช้บ่อย
23) การตรวจ anagram
ใช้ Hash Map เพื่อนับความถี่อักษร
Recap: ถ้าความถี่ทุกตัวเท่ากัน จึงเป็น anagram
24) การหา substring
ตัดข้อความส่วนย่อยตามช่วง index
Recap: substring/slice ใช้บ่อยกับ parsing และ validation
25) Prefix / Suffix คืออะไร
ตรวจว่าข้อความขึ้นต้นหรือจบด้วยรูปแบบที่ต้องการ
Recap: ใช้กับงานตรวจนามสกุลไฟล์ path หรือรูปแบบ token ได้บ่อย
26) Pattern matching เบื้องต้น
ใช้ regular expression แบบง่ายเพื่อเช็กรูปแบบข้อความ
Recap: เริ่มจาก pattern ง่ายก่อน แล้วค่อยขยายความซับซ้อนทีหลัง
27) ใช้ Hash Map กับ String เบื้องต้น
Hash Map เหมาะกับงานนับจำนวน, ตรวจซ้ำ, เก็บสถานะตัวอักษรที่เจอแล้ว เพราะ lookup โดยเฉลี่ยเร็ว
Recap: เมื่อโจทย์พูดถึงความถี่หรือการเช็กว่าเคยเจอหรือยัง ให้คิดถึง Hash Map ก่อน
28) ใช้ Two Pointers กับ String
Two pointers คือการใช้ตำแหน่ง 2 ฝั่ง (ซ้าย/ขวา) เพื่อไล่เช็กเงื่อนไข โดยไม่ต้องสร้างโครงสร้างเสริมมากเกินไป
Recap: เหมาะกับ palindrome, reverse check, และโจทย์เทียบปลายทั้งสองด้าน
29) ใช้ Sliding Window กับ String
ตัวอย่างโจทย์คลาสสิก: longest substring without repeating characters
Recap: Sliding window เหมาะกับโจทย์ช่วงต่อเนื่องที่ต้อง optimize จาก O(n²) ลงมาใกล้ O(n)
30) ข้อผิดพลาดที่พบบ่อยในการใช้ String
- ลืม normalize ตัวพิมพ์เล็ก/ใหญ่ก่อนเปรียบเทียบ
- ไม่ trim ข้อมูล input ทำให้เงื่อนไขพลาด
- ใช้ `+=` ต่อ string ในลูปยาวจนช้าโดยไม่จำเป็น
- อ่าน index เกินขอบเขตโดยไม่เช็กก่อน
- ลืมว่า string immutable แล้วคาดหวังว่าแก้ตัวอักษรเดิมได้โดยตรง
Recap: ถ้าคุณ normalize ข้อมูล, ระวังขอบเขต index, และเลือกเทคนิคให้เหมาะกับโจทย์ จะลดบั๊กได้มาก