String Problem
โจทย์ที่ 5: Roman to Integer
โจทย์ https://leetcode.com/problems/roman-to-integer
อธิบายโจทย์แบบสั้นๆ มีตัวอักษร Roman มาให้ จงแปลงตัวอักษร Roman เป็นตัวเลข ตามกฎในตารางด้านล่างนี้
กฎการแปลงเลข Roman แบบสั้นๆ
- ถ้าตัวอักษรมีค่าเท่ากันหรือน้อยกว่า จะทำการบวกต่อกันเสมอ เช่น
III
= 3,VII
= 7,XXI
= 21 - ถ้าตัวอักษรเจอว่าตัวอักษรต่อไปมีค่ามากกว่า จะเป็นการ “ลบเลข” ออกจากตัวอักษร Roman ตัวต่อไป เช่น
IV
= 4,XL
= 40,XLI
= 41 (กฎนี้จะเป็นจริงกับ ตัวอักษรต่อไปที่ติดกันเท่านั้น) - การรันตีว่าจะไม่มีการเขียนผิดกฎเลข Roman
จากข้อมูลที่โจทย์ให้มา
Example 1:
Input: s = "III"
Output: 3
Explanation: III = 3.
Example 2:
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 3:
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
จาก Testcase ที่ให้มาได้อธิบายให้เห็นชัดเจนว่าหากเราแยกส่วนออกมาจะมีการบวกเลขยังไงบ้าง
จากปัญหา นี้ Idea ที่ต้องทำแน่ๆคือ
- Loop ไปยังทุกตัวอักษรใน String แต่ละตัว
- แต่ละตัวอักษรจะต้องตรวจสอบด้วยว่า ตัวอักษรตัวต่อไปมีมากกว่าหรือไม่ ซึ่งถ้ามากกว่าแปลว่า ตัวอักษรปัจจุบันจะต้องลบค่าแทนที่จะบวกค่าเข้าไป เช่น
IV
ที่มีค่าเท่ากับ 4- ตอนเจอ I (1) ก่อน เราก็จะเช็คว่า ตัวต่อไป คือ V (5) เจอว่ามีค่ามากกว่า I ที่เป็นตัวปัจจุบัน ดังนั้น เราจึงทำการ -1 ค่าปัจจุบันก่อน
- และพอเจอ V ก็จะพบว่า ไม่มีตัวอักษรต่อไป ดังนั้นจึงบวกค่าเข้าไปได้ปกติ ก็จะสามารถออกมาเป็น -1 + 5 = 4 ออกมาได้
Solution
class Solution {
public:
// สร้าง function สำหรับแปลงตัวอักษร Romanji
int romanValue(char r) {
switch (r) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
}
return -1; // ถ้าไม่เข้าเคสไหนเลยให้ return -1 เป็น fallback ไป
}
int romanToInt(string s) {
int total = 0;
for (int i = 0; i < s.length(); i++) {
// ดึงค่า Roman ตัวปัจจุบัน
int current = romanValue(s[i]);
// ดึงค่า Roman ตัวถัดไป (หากตัวถัดไปเป็นตัวสุดท้ายแล้วให้เป็นค่า 0 = ก็จะมากกว่าเสมอได้)
int next = (i + 1 < s.length()) ? romanValue(s[i + 1]) : 0;
// เช็คว่า ถ้าค่ าตัวปัจจุบัน น้อยกว่า ค่าตัวถัดไป = ต้องลบออก
if (current < next) {
total -= current;
} else {
// แต่ถ้าไม่ใช่ให้บวกตามปกติเข้าไป
total += current;
}
}
return total;
}
};