Simple readable c solution


  • 3
    L
    1. find first non white space char;

    2. parse optional sign;

    3. parse digit one by one:
      3a) if see any invalid digit, return result so far;
      3b) check for overflow before accumulating the result;

      int myAtoi(char* str) {
      char* p = str;
      while (*p != '\0' && *p == ' ') ++p;

       int sign = 1;
       if (*p == '-') {
           ++p;
           sign = -1;
       } else if (*p == '+') {
           ++p;
       }
       
       int res = 0;
       while (*p != '\0') {
           if (*p < '0' || *p > '9') break;
           
           int d = *p - '0';
           // check overflow
           if (res > (INT_MAX-d)/10) return sign > 0 ? INT_MAX : INT_MIN;
           
           res = res*10 + d;
           ++p;
       }
       return sign*res;
      

      }


  • 0
    T

    you should also consider:
    1 'e' or 'E' is valid.
    2 if result is bigger than INT_MAX, result = INT_MAX
    3 if result is small than INT_MIN result = INT_MIN
    4 if scientific notation‘s result Is out of range, you should only return the part that before 'e' or 'E'
    my code was accepted just now. I have not optimized it.

    int myAtof(char* str)
    {
    double val = 0.0, power = 1.0, expVal = 0.0;
    int sign, i = 0, eSign;

    // delete space or tab
    while (str[i] == ' ' || str[i] == '\t')
    	++i;
    
    // + or -
    sign = str[i] == '-' ? -1 : 1;
    
    if (str[i] == '+' || str[i] == '-') ++i;
    
    // part that before .
    while (isdigit(str[i]))
    {
    	if (val < 1.7976931348623158e+308)
    	{
    		val = val * 10 + str[i] - '0';
    		++i;
    	}
    	else
    	{
    		printf("out of range!");
    		return 1.7976931348623158e+308;
    	}
    }
    
    if (str[i] == '.') ++i;
    
    //  part that after .
    while (isdigit(str[i]))
    {
    	if (val <= 1.7976931348623158e+308)
    	{
    		val = val * 10 + str[i] - '0';
    		power *= 10;
    		++i;
    	}
    	else
    	{
    		printf("out of range!");
    		return 1.7976931348623158e+308;
    	}
    }
    val = (val / power) * sign;
    
    if (str[i] == 'e' || str[i] == 'E')
    	++i;
    
    // sign of exponent
    eSign = str[i] == '-' ? -1 : 1;
    
    if (str[i] == '+' || str[i] == '-')
    	++i;
    
    while (isdigit(str[i]))
    {
    	if (expVal <= 1.7976931348623158e+308)
    	{
    		expVal = expVal * 10 + str[i] - '0';
    		++i;
    	}
    	else
    	{
    		printf("out of range!");
    		return 1.7976931348623158e+308;
    	}
    }
    
    if (eSign == 1)
    {
    	double temp;
    	temp = val * pow(10, expVal);
    	if (temp < 2147483647 && temp > -2147483648)
    		val = temp;
    }
    else
    {
    	double temp;
    	temp = val * pow(10, -expVal);
    	if (temp < 2147483647 && temp > -2147483648)
    		val = temp;
    
    }
    if (val > 2147483647 )
    {
    	printf("out of range!");
    	val = 2147483647;
    }
    if ( val < -2147483648.0)
    {
    	val = -2147483648.0;
    }
    return (int)val;
    

    }


  • 0
    M

    Check overflow before accumulating is smart.


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.