Anagram (อะนาก램) คือคำหรือวลีที่ประกอบด้วยตัวอักษรชุดเดียวกัน แต่เรียงลำดับต่างกัน เช่น "silent" และ "listen"
อัลกอริทึม: เรียงตัวอักษรแล้วเปรียบเทียบ
using System;
public class Demo
{
public static void Main()
{
string str1 = "silent";
string str2 = "listen";
bool isAnagram = AreAnagrams(str1, str2);
Console.WriteLine(isAnagram
? "Both strings are Anagrams"
: "Both strings are not Anagrams");
}
public static bool AreAnagrams(string s1, string s2)
{
if (s1.Length != s2.Length) return false;
// แปลงเป็นพิมพ์เล็ก ทั้งคู่ แล้วเรียงตัวอักษร
var chars1 = s1.ToLower().ToCharArray();
var chars2 = s2.ToLower().ToCharArray();
Array.Sort(chars1);
Array.Sort(chars2);
// เปรียบเทียบอาร์เรย์
return chars1.SequenceEqual(chars2);
}
}
ผลลัพธ์
Both strings are Anagrams
วิธี Alternative: ใช้ Character Counting (O(n) เร็วกว่า)
public static bool AreAnagramsFast(string s1, string s2)
{
if (s1.Length != s2.Length) return false;
var count = new int[26]; // สำหรับ a-z
foreach (char c in s1.ToLower())
if (c >= 'a' && c <= 'z') count[c - 'a']++;
foreach (char c in s2.ToLower())
if (c >= 'a' && c <= 'z') count[c - 'a']--;
return count.All(c => c == 0);
}
วิธี LINQ (สั้นกระชับ)
public static bool AreAnagramsLinq(string s1, string s2)
{
return s1.ToLower().OrderBy(c => c).SequenceEqual(
s2.ToLower().OrderBy(c => c));
}
เปรียบเทียบประสิทธิภาพ
| วิธี | Time Complexity | Space | หมายเหตุ |
|---|---|---|---|
| Sort + Compare | O(n log n) | O(n) | ง่าย อ่านง่าย |
| Char Counting | O(n) | O(1) | เร็วที่สุด สำหรับ a-z |
| LINQ OrderBy | O(n log n) | O(n) | เขียนสั้น แต่อยู่ใน Heap |
ข้อควรพิจารณา
- Case Sensitivity: ใช้ ToLower() หรือ OrdinalIgnoreCase
- Whitespace/Punctuation: ควร Filter ออกก่อนเปรียบเทียบ
- Unicode: Char Counting แบบ Array ไม่รองรับ Unicode เต็ม ต้องใช้ Dictionary
เวอร์ชันรองรับ Unicode
public static bool AreAnagramsUnicode(string s1, string s2)
{
var dict1 = s1.GroupBy(c => c).ToDictionary(g => g.Key, g => g.Count());
var dict2 = s2.GroupBy(c => c).ToDictionary(g => g.Key, g => g.Count());
return dict1.OrderBy(k => k.Key).SequenceEqual(dict2.OrderBy(k => k.Key));
}