Chuyển chuỗi sang số nguyên (String to Integer - atoi)
8. String to Integer (atoi)
Đề bài
Hãy hiện thực hàm myAtoi(string s) để chuyển đổi chuỗi s thành số nguyên 32-bit có dấu (tương tự hàm atoi trong C/C++).
Thuật toán chuyển đổi:
- Bỏ qua các khoảng trắng ở đầu (chỉ ký tự
' 'được tính là khoảng trắng). - Đọc dấu
+hoặc-(nếu có) để xác định dấu của kết quả. - Đọc liên tiếp các ký tự số cho tới khi gặp ký tự không phải số hoặc hết chuỗi.
- Chuyển phần chữ số vừa đọc thành số nguyên (ví dụ
"123" -> 123,"0032" -> 32). Nếu không đọc được chữ số nào thì kết quả là0. - Nếu kết quả vượt phạm vi 32-bit có dấu thì cắt về biên (clamp) tương ứng.
- Trả về kết quả.
Ví dụ 1:
Input: s = "42" Output: 42
Ví dụ 2:
Input: s = " -42" Output: -42
Ví dụ 3:
Input: s = "4193 with words" Output: 4193
Ví dụ 4:
Input: s = "words and 987" Output: 0
Ví dụ 5:
Input: s = "-91283472332" Output: -2147483648
Ràng buộc:
0 <= s.length <= 200sgồm chữ cái tiếng Anh (hoa/thường), chữ số (0-9), khoảng trắng' ', và dấu'+','-','.'(tuỳ test)
Tóm tắt đề
Chuyển chuỗi s sang số nguyên theo quy tắc giống atoi:
- Bỏ khoảng trắng đầu chuỗi.
- Nhận diện dấu
+/-(nếu có). - Đọc một dãy chữ số liên tục để tạo số.
- Nếu không có chữ số →
0. - Nếu vượt → trả về biên tương ứng.
Ý tưởng
- Duyệt
stừ trái qua phải. - Bỏ qua khoảng trắng đầu, sau đó xử lý dấu (nếu có).
- Gom các chữ số liên tiếp; gặp ký tự không phải số thì dừng.
- Chuyển dãy chữ số sang số và clamp vào phạm vi 32-bit có dấu.
Code
package leetcode func myAtoi(s string) int { maxInt, signAllowed, whitespaceAllowed, sign, digits := int64(2<<30), true, true, 1, []int{} for _, c := range s { if c == ' ' && whitespaceAllowed { continue } if signAllowed { if c == '+' { signAllowed = false whitespaceAllowed = false continue } else if c == '-' { sign = -1 signAllowed = false whitespaceAllowed = false continue } } if c < '0' || c > '9' { break } whitespaceAllowed, signAllowed = false, false digits = append(digits, int(c-48)) } var num, place int64 place, num = 1, 0 lastLeading0Index := -1 for i, d := range digits { if d == 0 { lastLeading0Index = i } else { break } } if lastLeading0Index > -1 { digits = digits[lastLeading0Index+1:] } var rtnMax int64 if sign > 0 { rtnMax = maxInt - 1 } else { rtnMax = maxInt } digitsCount := len(digits) for i := digitsCount - 1; i >= 0; i-- { num += int64(digits[i]) * place place *= 10 if digitsCount-i > 10 || num > rtnMax { return int(int64(sign) * rtnMax) } } num *= int64(sign) return int(num) }