Google Search

Custom Search

ผลการค้นหา

วันอังคารที่ 10 กุมภาพันธ์ พ.ศ. 2552

String Comparison

การเปรียบเทียบตัวแปร string ในหลาย ๆ ภาษานั้นไม่สามารถใช้เครื่องหมายเดียวกับการเปรียบเทียบตัวเลขได้(เท่าที่เห็นนี่ก็มี C# ที่ใช้ == ในการเปรียบเทียบการเท่ากันได้

แต่การเปรียบเทียบการมาก่อนมาหลัง ไม่สามารถใช้เครื่องหมาย >, < ได้ โดยจะต้องใช้ function มาช่วย

C : int strcmp(char *, char *);
ในภาษา C นั้นจะใช้ function strcmp ซึ่งต้อง include string.h เข้ามาด้วย

หากใครเคยเขียน assembly มาจะเคยเห็นคำสั่ง cmp ซึ่งเป็นการ compare ค่าสองค่า โดยการนำมาลบกัน strcmp ก็คล้ายคลึงกัน นั่นคือการนำเอา string ตัวหน้ามาลบตัวหลัง โดยวิธีการลบกันก็คือนำตัวอักษรตัวแรกของทั่งคู่มาเปรียบเทียบกันก่อน(ตาม ASCII code - lexicographical compare) หากยังเท่ากันจะเปรียบเทียบตัวถัดไป โดยผลลัพธ์เป็นดังนี้ หาก string ตัวแรกมาก่อน function นี้จะ return ค่า -1 แต่ถ้ามาทีหลังจะ return +1 ถ้าเป็น string ตัวเดียวกันจะ return 0

char *s, *t;
int result;
//...
result = strcmp(s, t);
if(result < 0) {
// s precede t
} else if(result > 0) {
// t precede s
} else {
//s is equal t
}

สังเกตนะครับ ผมจะเทียบผลลัพธ์ว่ามากกว่าหรือน้อยกว่า 0

ลองมาดูวิธีการจำอย่างง่าย ๆ ของผมนะครับ ถ้า a > b ก็จะหมายความว่า a - b > 0 (ย้ายข้างธรรมดา คงนึกออกนะครับ) นั่นก็หมายความว่า ถ้า strcmp ได้ผลลัพธ์มากกว่า 0 ก็แสดงว่า string ตัวแรกมีค่ามากกว่าตัวหลัง

แล้วความหมายของการมากกว่าของ string คืออะไรล่ะ ให้ลองคิดถึง dictionary นะครับ คำในนั้นจะเรียงตามลำดับตัวอักษรอยู่แล้ว ถ้าเรากำหนดค่าให้คำเหล่านั้นตามลำดับเป็นเลข 1, 2, 3 ไปเรื่อย ๆ คำที่มาทีหลังก็จะมีค่ามากกว่าคำก่อนนั้นใช้มั้ยครับ ดังนั้น strcmp ก็เหมือนกับการเอาลำดับที่ของคำเหล่านั้นมาลบกัน

แล้วมาดูภาษาอื่นกันบ้างนะครับ

Java : public int compareTo(String);
ผลลัพธ์ของ method นี้ก็คล้าย ๆ กับ strcmp ใน C นะครับ เพียงแต่ว่าค่าที่ return กลับมาเป็นผลต่างของตัวอักษรตัวแรกที่ต่างกัน แต่ถ้าเปรียบเทียบกันจนมี string ตัวหนึงหมดก่อน ผลลัพธ์ที่ได้คือผลต่างความยาวของ string คู่นั้น

ดูตัวอย่างละกันครับ

String s, t;

s = "abc";
t = "abz";
System.out.println(s.compareTo(t)); // - 23
หรือ

System.out.println("a".compareTo("A")); // 32
System.out.println("abcdef".compareTo("ab")); // 4
C# : public int CompareTo(string); และ public static int Compare(string, string);
method เจ้าปัญหาของภาษานี้เลยละครับ วิธีการใช้งานของ method แรกนั้นก็เหมือนกับ Java เลยครับ เพียงแต่ว่าผลลัพธ์นั้นจะเป็นเหมือน strcmp ของ C ครับ คือผลลัพธืมีแค่ {-1, 0, 1}

string s = "abc";
string t = "abz";
Console.WriteLine(s.CompareTo(t)); // -1
Console.WriteLine(string.Compare(s, t); // -1
แต่ปัญหามันอยู่ที่ว่ามันดันเรียงเอาตัวอักษรตัวเล็กมาก่อนตัวอักษรตัวใหญ่(ซึ่ง ASCII code ของตัวใหญ่จะมาก่อนตัวเล็ก)

Console.WriteLine("A".CompareTo("a"));
Console.WriteLine(string.Compare("A", "a"));

ทั้งคู่ให้ผลลัพธ์เป็น + ทั้งคู่ครับ นั่นก็หมายความว่า A มาหลัง a (ซึ่งตรงข้ามกับ ASCII)

ยังไม่หมดแค่นั้นครับ ปัญหาแรกยังพอยอมรับได้ แต่อันต่อจากนี้ผมมึนครับ

Console.WriteLine(string.Compare("+", "-"));
Console.WriteLine(string.Compare("+789", "-789"));
อันล่าง return -1 แต่อันบนดัน return +1 ซึ่งมันควรจะได้ -1 เหมือนกันเพราะ '+'(ASCII code 43) มาก่อน '-'(ASCII code 45)

ผมก็ไม่รู้สาเหตุนะครับ เอาเป็นว่าอย่าใช้สอง method นี้ละกันครับ

แล้วก็จะมีคำถามตามมาว่าแล้วจะเปรียบเทียบ string ยังไงล่ะ ?

จริง ๆ แล้วยังเหลือ method อีกตัวนึงครับ นั่นก็คือ

public static int CompareOrdinal(string, string);
อันนี้จะให้ผลที่ถูกต้องแล้วนะครับ โดยผลที่ได้นั้นก็เหมือนกับ compareTo ของ Java

Console.WriteLine(string.CompareOrdinal("+", "-"));
Console.WriteLine(string.CompareOrdinal("+789", "-789"));
โดยทั้งคู่จะ return -2 เหมือนกันแบบเดียวกับ Java ดังนั้นเวลาใช้งานนี่ก็ลืม 2 method แรกไปได้เลย มาใช้แต่ static CompareOrdinal นะครับ

1 ความคิดเห็น:

jam กล่าวว่า...

ขอบคุณมากคับที่ทำให้รู้จัก strcmp

โฆษณา