DEV Community

Kanin James Kearpimy
Kanin James Kearpimy

Posted on

[KubeOps Academy] Palindrome with Rust ทำยังไงนะ!?

อยากให้ทุกคนลองเขียนชื่อตัวเองจาก หลังไปหน้า แล้วอ่านดู... อ่านรู้เรื่องกันมั้ยครับ? แล้วเคยสงสัยมั้ย ว่าทำไมชื่อคนบางคนไม่ว่าจะอ่านจากหลังไป

อะไรคือ palindrome?

Palindrome คือ ประโยคหรือคำ ทั้งในเชิงอักษร (ABC, abc) ตัวเลข (123321) และตัวอักขระ ที่เรียงต่อกันแล้วสามารถอ่านแล้วได้ความหมายเดิม ทั้งจากหลังไปหน้า และหน้าไปหลัง

ในทางคอมพิวเตอร์ ได้มีการทำ Palindrome มาใช้สำหรับการบีบอัด (Compression) DNA อีกด้วย อ่านต่อ
Why rust?

เราจะแก้โจทย์ Palindrome ได้อย่างไร?

การแก้ Palindrome นั้นมีวิธีคิดได้หลากหลายในทางกระบวนการวิธี เช่น ตัดครึ่งคำ จากนั้นนำฝั่งซ้าย - ขวา มาทาบกัน โดยบทความนี้จะนำวิธีการ ไล่คำจากด้านหลังและด้านหน้าทีละตัวอักษรพร้อมๆ กัน เพื่อเปรียบเทียบว่าเป็น Palindrome หรือป่าว

แนวคิด

Image description

จากภาพด้านบน ให้ลองคิดว่า ให้

  1. เรานำปากกา 2 ด้านมาวางไว้ที่ปลายสุดของทั้งสองฝั่ง
  2. จากนั้นให้เปรียบเทียบตัวอักษรที่ปลายของปากกาทั้งสอง
  3. เมื่อเปรียบเทียบแล้ว ให้ขยับปากกาเข้าหากัน
  4. เปรียบเทียบ ทำเช่นนี้ไปเรื่อยๆ 5.1 หากรอบใดที่ปลายตัวอักษรปลายปากกาไม่เท่ากัน สรุปได้ว่าคำนั้น ไม่ใช่ Palindrome 5.2 หากว่าเปรียบเทียบหมดแล้ว ตัวอักษรทุกตัวเท่านั้น สรุปได้ว่า คำนั้นคือ Palindrome

ลงมือเขียน Code กัน!!

โดยเราจะใช้ ภาษา Rust ซึ่งเป็นภาษา System Programming หนึ่งที่ค่อนข้างฝึกให้เราคิดถึง process เบื้องหลังการทำงานของ Computer

Import การจัดการ input/output ของภาษา Rust

use std::io::stdin;

ภายใน Function main ซึ่งถือเป็น function หลักของโปรแกรม เราจะแสดงข้อความออกทาง terminal ให้ผู้ใช้งานเข้าใจการทำงานคร่าวๆ และถ้าพร้อมให้ผู้ใช้พิมพ์คำที่อยากเช็ค Palindrome ลงมา

println!("Palindrome.");
    println!("If you want to exit. please type ==> :q\n");
    loop {
        let mut pre_string = String::new();
        println!("Please input your thing ==>");
        stdin().read_line(&mut pre_string).expect("Please put correct string.");

        let string: &str = &pre_string.trim().replace(" ", "");
        if string.to_uppercase() == END_GAME {
            println!("==========");
            println!("THANK YOU.");
            println!("==========");
            break;
        }
        if string == "" {
            println!("Please put correct string!\n");
            continue;
        }

        let is_palindrome: bool = check_palindrom(string);

        println!("is {} Palindrome? : {}\n", string, match is_palindrome { true => "YES", false => "NO" });
    }
Enter fullscreen mode Exit fullscreen mode

โดยจะทำการ loop วนจนกว่าผู้ใช้งานพิมพ์คำว่า "END" จึงจะหยุดการทำงาน

โดยขออธิบายการทำงานของ check_palindrome function สำหรับเช็ค palindrome ตามด้านล่าง

fn check_palindrom(string: &str) -> bool {
    let mut is_palindrome: bool = true;
    for (c1, c2) in string.chars().zip(string.chars().rev()) {
        if c1 != c2 {
            is_palindrome = false;
        }
    }
    return is_palindrome;
}
Enter fullscreen mode Exit fullscreen mode

วิธีการทำงานจะเหมือนแนวคิดด้านบน นั้นคือสร้าง loop ทั้งคำ จากนั้นให้มี c1 และ c2 โดยที่ c1 ชี้ที่ด้านซ้ายสุด และ c2 ชี้ด้านขวาสุด โดยใน ภาษา rust นั้นการทำ indexing ใน string จะมีความท้าทาย ทางผู้เขียนจึงใช้วิธีสร้าง string ขึ้นมา 2 ตัว โดย ชุดแรกเป็นคำเดิม แต่ ชุดที่สอง จะเป็นคำที่กลับด้าน จากนั้นให้ c1 loop ผ่านชุดแรก และ c2 loop ผ่านชุดที่สอง

และหากว่าทุกคำเท่ากัน จะถือว่าคำนั้นเป็น palindrome ด้วยการ return true ถือเป็นการจบกระบวนการเช็ค Palindrome

สรุปและต่อยอด

โดยจริงแล้ว Palindrome จะเหมาะกับการแก้ปัญหาสิ่งที่เป็น sequence ต่อกันและสามารถ map เข้าหากันได้จากด้านหน้าและด้านหลัง ซึ่งวิธีการเช็ค Palindrome ในบทความนี้ต้องการนำเสนอ แนวคิดการเช็คแบบไล่ หัว-ท้าย โดยไม่ต้องตัดคำตรงกลางทิ้ง ทุกคนคิดเห็นอย่างไรมาแบ่งปันกันได้นะครับ


KubeOps Academy คือ Long-Term Program ที่อยากสร้าง Cloud Native จาก Zero to Workforce. หากสนใจกิจกรรมอื่นๆ ที่น่าสนใจ ของ Community สามารถติดตามต่อได้ที่ KubeOps Skills ครับ

Discussion (0)