ภาพรวม
บทความนี้สาธิตวิธีหา Index ของตัวอักษรแรกที่ปรากฏซ้ำในสตริง โดยใช้ Map เพื่อติดตามตำแหน่งแรกที่เจอแต่ละตัวอักษร
ตัวอย่าง
const str = 'Hello world, how are you';
// H e l l o ...
// Index 2: 'l' เป็นตัวแรกที่ซ้ำ (เจอที่ index 2 และ 3)
การนำไปใช้
const firstRepeating = (str) => {
const map = new Map();
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (map.has(char)) {
return map.get(char); // คืนค่า Index แรกที่เจอ
}
map.set(char, i);
}
return -1; // ไม่มีตัวซ้ำ
};
console.log(firstRepeating('Hello world, how are you')); // 2
ผลลัพธ์
2
วิธีการอื่นๆ
1. ใช้ Object แทน Map (รองรับ IE)
const firstRepeatingObj = (str) => {
const seen = {};
for (let i = 0; i < str.length; i++) {
if (seen[str[i]] !== undefined) return seen[str[i]];
seen[str[i]] = i;
}
return -1;
};
2. ใช้ Array.indexOf (Simple แต่ O(n²))
const firstRepeatingSimple = (str) => {
for (let i = 0; i < str.length; i++) {
if (str.indexOf(str[i], i + 1) !== -1) return i;
}
return -1;
};
3. หาตัวอักษรที่ซ้ำ "ตัวแรกที่เจอซ้ำ" (First Duplicate Character)
// คืนค่าตัวอักษร ไม่ใช่ Index
const firstDuplicateChar = (str) => {
const seen = new Set();
for (const char of str) {
if (seen.has(char)) return char;
seen.add(char);
}
return null;
};
กรณีพิเศษ
- Case Sensitivity: 'A' != 'a' (ใช้ toLowerCase() ถ้าต้องการ Case-insensitive)
- Whitespace: นับ Space เป็นตัวอักษรหรือไม่
- Unicode: ใช้ [...str] แทน str[i] สำหรับ Surrogate Pairs
เวอร์ชัน Unicode-Safe
const firstRepeatingUnicode = (str, caseInsensitive = false) => {
const map = new Map();
const chars = [...str]; // รองรับ Emoji, Thai, etc.
for (let i = 0; i < chars.length; i++) {
const char = caseInsensitive ? chars[i].toLowerCase() : chars[i];
if (map.has(char)) return map.get(char);
map.set(char, i);
}
return -1;
};
การประยุกต์ใช้
- String Compression (Run-Length Encoding)
- Duplicate Detection ใน Form Input
- Cryptanalysis: Frequency Analysis
- Text Editor: Highlight Repeated Characters