String to Integer conversion (atoi)

[Question]: Convert given string into Integer with given condition

  1. Discards all leading whitespaces
  2. Maintain Sign
  3.  ab123a  -> 0
  4. -+123  -> 0
  5. +-123  -> 0
  6.  123abc-  -> 123
  7.  -99999999999999999  -> -2147483648
  8.  00999999999999999  -> 2147483647
  9.  2147483648  -> 2147483647
  10.  -2147483648 -> -2147483648
// TC: O(N)
// SC: O(1)
func myAtoi(_ s: String) -> Int {
    var result = 0// Outpuut
    var sign = 1 // 1 means positive -1 means negative(further multiply)
    var isStarted = false // To skip invalid character.
    for char in s {
        if char == " " {
            if isStarted {
                break
            }
        } else if (char == "-" || char == "+") {
            if isStarted {
                break
            }
            isStarted = true
            if char == "-" {
                sign = -1
            }
        } else if char >= "0" && char <= "9" {
            isStarted = true
            if let val = char.wholeNumberValue {
                result = result*10+val
            }
            if result > Int32.max {
                return sign == 1 ? Int(Int32.max) : Int(Int32.min)
            }
        } else {
            break
        }
    }
    return result*sign
}

let atoiString = "  43   "//"        42       "// "   -42"//"4193 with words"
let atoiOutput = myAtoi(atoiString)
print("output is--  ", atoiOutput)// 43
Approach #2 Using Recursion
func myAtoiUsingRecursion(_ s: String) -> Int {
    var output = 0
    var startIndex = 0
    var sign:Int = 1
    var isStarted = false
    return myAtoiRec(s, &startIndex, &output, s.count, &sign, &isStarted)
}
func myAtoiRec(_ s: String,
               _ strIndex: inout Int,
               _ result: inout Int,
               _ strCount: Int,
               _ sign: inout Int,
               _ isStarted: inout Bool) -> Int {
    
    if strIndex == strCount { return result*sign }
    let curChar = s[s.index(s.startIndex, offsetBy: strIndex)]
    if curChar == " " {
        if isStarted { return result*sign }
    } else if (curChar == "-" || curChar == "+") {
        if isStarted { return result*sign }
        isStarted = true
        if curChar == "-" {
            sign = -1
        }
    } else if curChar >= "0" && curChar <= "9" {
        isStarted = true
        if let val = curChar.wholeNumberValue {
            result = result*10+val
        }
        if result > Int32.max {
            return sign == 1 ? Int(Int32.max) : Int(Int32.min)
        }
    } else {
        return result*sign
    }
    strIndex+=1
    return myAtoiRec(s, &strIndex, &result, strCount, &sign, &isStarted)
}

Plain Atoi Solution

// Plain AsciiToInterger function..
func myAtoiRec(_ s: String,_ strIndex: inout Int, _ result: inout Int, _ strCount: Int) -> Int {
    if strIndex == strCount { return result }
    if let val = s[s.index(s.startIndex, offsetBy: strIndex)].wholeNumberValue {
        result = result*10+val
        strIndex+=1
    }
    return myAtoiRec(s, &strIndex, &result, strCount)
}

Leave a Comment

Your email address will not be published. Required fields are marked *