Given a string s, convert it into integer format without utilizing any built-in functions. Refer the below steps to know about atoi() function.
- Skip any leading whitespaces.
- Check for a sign ('+' or '-'), default to positive if no sign is present.
- Read the integer by ignoring leading zeros until a non-digit character is encountered or end of the string is reached. If no digits are present, return 0.
- If the integer is greater than 231 – 1, then return 231 – 1 and if the integer is smaller than -231, then return -231.
Examples:
Input: s = "-123"
Output: -123Input: s = " -"
Output: 0
Explanation: No digits are present, therefore 0.Input: s = " 1231231231311133"
Output: 2147483647
Explanation: The converted number is greater than 231 - 1, therefore print 231 - 1 = 2147483647.Input: s = "-999999999999"
Output: -2147483648
Explanation: The converted number is smaller than -231, therefore print -231 = -2147483648.Input: s = " -0012gfg4"
Output: -12
Explanation: Nothing is read after -12 as a non-digit character 'g' was encountered.
Table of Content
Iterative Approach - O(n) Time and O(1) Space
Traverse the string from left to right, skipping whitespaces, handling the optional sign, and building the number digit by digit. At each step, ensure the value stays within 32-bit integer limits to avoid overflow.
How to check if the number is greater than 231 - 1 or smaller than -231 ?
The naive way is to use a data type larger than 32 bits like long or BigInteger to store the number. However, we can also use a 32-bit integer by appending the digits one-by-one and, for each digit, checking whether appending it will cause overflow.
Since we construct the number as a positive value and apply the sign at the end, we only need to check against 231 - 1. While appending a digit to the current number, we can have 3 cases:
Case 1: current number < (231 - 1)/10 then simply append the digit to the current number as it will not cause overflow.
Case 2: current number > (231 - 1)/10 then return 231 - 1 in case of overflow.
Case 3: current number = (231 - 1)/10 then in this case, only digits from 0 to 7 can be appended safely. If the next digit is greater than 7, return 231 - 1.
#include <iostream>
#include <climits>
using namespace std;
int myAtoi(string &s) {
int sign = 1, res = 0, idx = 0;
// Ignore leading whitespaces
while (idx < s.size() && s[idx] == ' ') {
idx++;
}
// Store the sign of number
if (idx < s.size() && s[idx] == '-' || s[idx] == '+') {
if(s[idx++] == '-')
sign = -1;
}
// Construct the number digit by digit
while (idx < s.size() && s[idx] >= '0' && s[idx] <= '9') {
// handling overflow/underflow test case
if (res > INT_MAX / 10 || (res == INT_MAX / 10 && s[idx] - '0' > 7)) {
return sign == 1 ? INT_MAX : INT_MIN;
}
// Append current digit to the result
res = 10 * res + (s[idx++] - '0');
}
return res * sign;
}
int main() {
string s = " -0012g4";
cout << myAtoi(s);
return 0;
}
class GfG {
static int myAtoi(String s) {
int sign = 1, res = 0, idx = 0;
// Ignore leading whitespaces
while (idx < s.length() && s.charAt(idx) == ' ') {
idx++;
}
// Store the sign of number
if (idx < s.length() && (s.charAt(idx) == '-'
|| s.charAt(idx) == '+')) {
if (s.charAt(idx++) == '-') {
sign = -1;
}
}
// Construct the number digit by digit
while (idx < s.length() && s.charAt(idx) >= '0'
&& s.charAt(idx) <= '9') {
// Handling overflow/underflow test case
if (res > Integer.MAX_VALUE / 10 ||
(res == Integer.MAX_VALUE / 10 && s.charAt(idx) - '0' > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
// Append current digit to the result
res = 10 * res + (s.charAt(idx++) - '0');
}
return res * sign;
}
public static void main(String[] args) {
String s = " -0012g4";
System.out.println(myAtoi(s));
}
}
def myAtoi(s):
sign = 1
res = 0
idx = 0
n = len(s)
# Ignore leading whitespaces
while idx < n and s[idx] == ' ':
idx += 1
# Store the sign of number
if idx < n and (s[idx] == '+' or s[idx] == '-'):
if s[idx] == '-':
sign = -1
idx += 1
# Construct the number digit by digit
while idx < n and '0' <= s[idx] <= '9':
digit = ord(s[idx]) - ord('0')
res = 10 * res + digit
# Handle overflow and underflow
if res > 2**31 - 1:
return (2**31 - 1) if sign == 1 else -2**31
idx += 1
return res * sign
if __name__ == "__main__":
s = " -0012g4"
print(myAtoi(s))
using System;
class GfG {
public static int myAtoi(string s) {
int sign = 1, res = 0, idx = 0;
// Ignore leading whitespaces
while (idx < s.Length && s[idx] == ' ') {
idx++;
}
// Store the sign of number
if (idx < s.Length && (s[idx] == '-' || s[idx] == '+')) {
if (s[idx] == '-')
sign = -1;
idx++;
}
// Construct the number digit by digit
while (idx < s.Length && s[idx] >= '0' && s[idx] <= '9') {
// Handling overflow/underflow test case
if (res > Int32.MaxValue / 10 ||
(res == Int32.MaxValue / 10 && s[idx] - '0' > 7)) {
return sign == 1 ? Int32.MaxValue : Int32.MinValue;
}
// Append current digit to the result
res = 10 * res + (s[idx] - '0');
idx++;
}
return res * sign;
}
static void Main() {
string s = " -0012g4";
Console.WriteLine(myAtoi(s));
}
}
function myAtoi(s) {
let sign = 1, res = 0, idx = 0;
// Ignore leading whitespaces
while (idx < s.length && s[idx] === ' ') {
idx++;
}
// Store the sign of number
if (idx < s.length && (s[idx] === '-' || s[idx] === '+')) {
if (s[idx] === '-') {
sign = -1;
}
idx++;
}
// Construct the number digit by digit
while (idx < s.length && s[idx] >= '0' && s[idx] <= '9') {
// Handling overflow/underflow test case
if ((res > Math.pow(2, 31) / 10) || ((res === Math.floor(Math.pow(2, 31) / 10)) && (s[idx] - '0' > 7))) {
return sign === 1 ? (Math.pow(2, 31) - 1) : -Math.pow(2, 31);
}
// Append current digit to the result
res = 10 * res + (s[idx] - '0');
idx++;
}
return (res * sign == -0 ? 0 : res * sign);
}
// Driver code
const s = " -0012g4";
console.log(myAtoi(s));
Output
-12
Recursive Approach - O(n) Time and O(n) Space
Process the string recursively by skipping whitespaces, determining the sign, and building the number one digit at a time. At each recursive step, check for overflow and stop when a non-digit character is encountered or the string ends.
#include <iostream>
#include <string>
#include <climits>
using namespace std;
// Parse digits recursively with overflow handling
int parseDigits(const string &s, int idx, int res, int sign) {
if (idx >= s.size() || s[idx] < '0' || s[idx] > '9')
return res * sign;
int digit = s[idx] - '0';
if (res > (INT_MAX - digit) / 10)
return sign == 1 ? INT_MAX : INT_MIN;
return parseDigits(s, idx + 1, res * 10 + digit, sign);
}
int myAtoi(string &s) {
int idx = 0;
// Skip leading spaces
while (idx < s.size() && s[idx] == ' ')
idx++;
int sign = 1;
// Handle sign
if (idx < s.size() && (s[idx] == '-' || s[idx] == '+')) {
if (s[idx] == '-')
sign = -1;
idx++;
}
return parseDigits(s, idx, 0, sign);
}
int main() {
string s = " -0012g4";
cout << myAtoi(s) << endl;
return 0;
}
class GfG {
// Parse digits recursively with overflow handling
static int parseDigits(String s, int idx, int res, int sign) {
if (idx >= s.length() || s.charAt(idx) < '0' || s.charAt(idx) > '9')
return res * sign;
int digit = s.charAt(idx) - '0';
if (res > (Integer.MAX_VALUE - digit) / 10)
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
return parseDigits(s, idx + 1, res * 10 + digit, sign);
}
static int myAtoi(String s) {
int idx = 0;
// Skip leading spaces
while (idx < s.length() && s.charAt(idx) == ' ')
idx++;
int sign = 1;
// Handle sign
if (idx < s.length() && (s.charAt(idx) == '-' || s.charAt(idx) == '+')) {
if (s.charAt(idx) == '-')
sign = -1;
idx++;
}
return parseDigits(s, idx, 0, sign);
}
public static void main(String[] args) {
System.out.println(myAtoi(" -0012g4"));
}
}
# Parse digits recursively with overflow handling
def parseDigits(s, idx, res, sign):
if idx >= len(s) or s[idx] < '0' or s[idx] > '9':
return res * sign
digit = ord(s[idx]) - ord('0')
if res > (2**31 - 1 - digit) // 10:
return (2**31 - 1) if sign == 1 else -(2**31)
return parseDigits(s, idx + 1, res * 10 + digit, sign)
def myAtoi(s):
idx = 0
# Skip leading spaces
while idx < len(s) and s[idx] == ' ':
idx += 1
sign = 1
# Handle sign
if idx < len(s) and (s[idx] == '-' or s[idx] == '+'):
if s[idx] == '-':
sign = -1
idx += 1
return parseDigits(s, idx, 0, sign)
if __name__ == "__main__":
print(myAtoi(" -0012g4"))
using System;
class GfG {
// Parse digits recursively with overflow handling
static int parseDigits(string s, int idx, int res, int sign) {
if (idx >= s.Length || s[idx] < '0' || s[idx] > '9')
return res * sign;
int digit = s[idx] - '0';
if (res > (int.MaxValue - digit) / 10)
return sign == 1 ? int.MaxValue : int.MinValue;
return parseDigits(s, idx + 1, res * 10 + digit, sign);
}
static int myAtoi(string s) {
int idx = 0;
// Skip leading spaces
while (idx < s.Length && s[idx] == ' ')
idx++;
int sign = 1;
// Handle sign
if (idx < s.Length && (s[idx] == '-' || s[idx] == '+')) {
if (s[idx] == '-')
sign = -1;
idx++;
}
return parseDigits(s, idx, 0, sign);
}
static void Main() {
Console.WriteLine(myAtoi(" -0012g4"));
}
}
// Parse digits recursively with overflow handling
function parseDigits(s, idx, res, sign) {
if (idx >= s.length || s[idx] < '0' || s[idx] > '9')
return res * sign;
let digit = s[idx] - '0';
if (res > Math.floor((2147483647 - digit) / 10))
return sign === 1 ? 2147483647 : -2147483648;
return parseDigits(s, idx + 1, res * 10 + digit, sign);
}
function myAtoi(s) {
let idx = 0;
// Skip leading spaces
while (idx < s.length && s[idx] === ' ')
idx++;
let sign = 1;
// Handle sign
if (idx < s.length && (s[idx] === '-' || s[idx] === '+')) {
if (s[idx] === '-')
sign = -1;
idx++;
}
return parseDigits(s, idx, 0, sign);
}
console.log(myAtoi(" -0012g4"));
Output
-12
Related Articles:
Write your own atoi() that takes a string (which represents a floating point value) as an argument and returns its value as double.