โจทย์ปัญหา
Implement ฟังก์ชัน atoi (ASCII to Integer) แปลง String เป็น Integer โดย:
- ข้าม Whitespace นำหน้า
- อ่านเครื่องหมาย + หรือ - (ถ้ามี)
- อ่านตัวเลข 0-9 ต่อเนื่อง
- หยุดเมื่อเจอตัวอักษรที่ไม่ใช่ตัวเลข
- จัดการ Overflow (Clamp ไว้ที่ INT_MIN/INT_MAX)
ตัวอย่าง
| Input | Output | คำอธิบาย |
|---|---|---|
| "42" | 42 | ปกติ |
| " -42" | -42 | ข้าม Space, เครื่องหมาย - |
| "4193 with words" | 4193 | หยุดที่ Space |
| "words and 987" | 0 | ไม่เริ่มด้วยตัวเลข/เครื่องหมาย |
| "-91283472332" | -2147483648 | Underflow → INT_MIN |
แนวคิดการแก้ปัญหา
- ข้าม Leading Whitespaces
- ตรวจสอบเครื่องหมาย (+/-)
- สร้างตัวเลขทีละหลัก:
result = result * 10 + digit - ตรวจสอบ Overflow ก่อนคูณ/บวก:
if (result > INT_MAX/10 || (result == INT_MAX/10 && digit > INT_MAX%10)) - คืนค่า
result * sign
โค้ดตัวอย่าง (C++)
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int myAtoi(string str) {
int sign = 1;
long long base = 0; // ใช้ long long ป้องกัน overflow ระหว่างคำนวณ
int i = 0;
int n = str.size();
// 1. ข้าม Whitespace
while (i < n && str[i] == ' ') i++;
// 2. เครื่องหมาย
if (i < n && (str[i] == '+' || str[i] == '-')) {
sign = (str[i] == '-') ? -1 : 1;
i++;
}
// 3. อ่านตัวเลข
while (i < n && isdigit(str[i])) {
int digit = str[i] - '0';
// 4. ตรวจสอบ Overflow
if (base > INT_MAX / 10 || (base == INT_MAX / 10 && digit > INT_MAX % 10)) {
return (sign == 1) ? INT_MAX : INT_MIN;
}
base = base * 10 + digit;
i++;
}
return (int)(base * sign);
}
};
int main() {
Solution ob;
cout << ob.myAtoi("-45") << endl; // -45
cout << ob.myAtoi(" 56") << endl; // 56
cout << ob.myAtoi("100") << endl; // 100
cout << ob.myAtoi("2147483648") << endl; // 2147483647 (clamped)
return 0;
}
ผลลัพธ์
-45
56
100
2147483647
คำอธิบายเพิ่มเติม
- ความซับซ้อนด้านเวลา: O(n) (n = ความยาว String)
- ความซับซ้อนด้านพื้นที่: O(1)
- ใช้
long longสำหรับตัวแปรชั่วคราว ป้องกัน Overflow ระหว่างคำนวณ - Standard library มี
std::stoi,std::stol,std::stollแต่โยน Exception เมื่อ Overflow