Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python: หาตัวอักษรซ้ำในสตริง (Find Duplicate Characters)

โจทย์: หาตัวอักษรที่ปรากฏซ้ำ (Duplicate Characters) ในสตริง เช่น "tutorialspoint" -> t, o, i (ตัวอักษรที่มี Count > 1)

วิธีที่ 1: ใช้ count() Method (เข้าใจง่าย)

def find_duplicates_count(s):
    duplicates = []
    for char in s:
        if s.count(char) > 1 and char not in duplicates:
            duplicates.append(char)
    return duplicates

print(find_duplicates_count("tutorialspoint"))  # ['t', 'o', 'i']

Time Complexity: O(n²) - ใช้ count() ใน Loop

วิธีที่ 2: ใช้ Dictionary/Hash Map (Efficient - O(n))

def find_duplicates_dict(s):
    char_count = {}
    for char in s:
        char_count[char] = char_count.get(char, 0) + 1
    
    return [char for char, count in char_count.items() if count > 1]

print(find_duplicates_dict("tutorialspoint"))  # ['t', 'o', 'i']

วิธีที่ 3: ใช้ collections.Counter (Pythonic)

from collections import Counter

def find_duplicates_counter(s):
    counts = Counter(s)
    return [char for char, count in counts.items() if count > 1]

print(find_duplicates_counter("tutorialspoint"))  # ['t', 'o', 'i']

วิธีที่ 4: ใช้ Set (Memory Efficient)

def find_duplicates_set(s):
    seen = set()
    duplicates = set()
    for char in s:
        if char in seen:
            duplicates.add(char)
        else:
            seen.add(char)
    return list(duplicates)

print(find_duplicates_set("tutorialspoint"))  # ['t', 'o', 'i'] (ลำดับอาจแตกต่าง)

วิธีที่ 5: หา Duplicates พร้อม Count

from collections import Counter

def find_duplicates_with_count(s):
    counts = Counter(s)
    return {char: count for char, count in counts.items() if count > 1}

result = find_duplicates_with_count("tutorialspoint")
print(result)  # {'t': 2, 'o': 2, 'i': 2}

# เรียงตาม Count มากไปน้อย
sorted_duplicates = sorted(result.items(), key=lambda x: x[1], reverse=True)
print(sorted_duplicates)  # [('t', 2), ('o', 2), ('i', 2)]

ตัวอย่างเพิ่มเติม

test_strings = [
    "tutorialspoint",
    "hello world",
    "abcdefg",
    "aabbccddeeff",
    "🎉🎉🎈🎈🎁",  # Unicode/Emoji
    ""
]

for s in test_strings:
    dupes = find_duplicates_counter(s)
    print(f"'{s}' -> Duplicates: {dupes}")

ผลลัพธ์

'tutorialspoint' -> Duplicates: ['t', 'o', 'i']
'hello world' -> Duplicates: ['l', 'o', ' ']
'abcdefg' -> Duplicates: []
'aabbccddeeff' -> Duplicates: ['a', 'b', 'c', 'd', 'e', 'f']
'🎉🎉🎈🎈🎁' -> Duplicates: ['🎉', '🎈']
'' -> Duplicates: []

Performance Comparison

import timeit
import random
import string

# สร้างสตริงทดสอบ 10,000 ตัวอักษร
test_str = ''.join(random.choices(string.ascii_letters + string.digits, k=10000))

methods = {
    "count()": "find_duplicates_count(test_str)",
    "dict.get": "find_duplicates_dict(test_str)",
    "Counter": "find_duplicates_counter(test_str)",
    "set": "find_duplicates_set(test_str)",
}

for name, code in methods.items():
    time = timeit.timeit(code, globals=globals(), number=100)
    print(f"{name:12}: {time:.4f}s")

ผลลัพธ์ประมาณ

count()      : 12.4500s  (ช้ามาก O(n²))
dict.get     : 0.0120s
Counter      : 0.0085s  (เร็วที่สุด)
set          : 0.0100s

สรุป

  • Counter: เร็วที่สุด โค้ดสั้นที่สุด แนะนำสำหรับ Production
  • Dictionary/Set: เร็ว ใช้ Memory น้อย เข้าใจ Logic ได้
  • count(): เข้าใจง่ายแต่ช้า (O(n²)) ใช้ได้เฉพาะ String สั้น
  • ทั้งหมดรองรับ Unicode/Emoji ได้ปกติ