My C language Solution with too many if-else. Whether I can reduce these if statements?

• ``````#define isDigit(c)  ( c >= '0' && c <= '9')

int myAtoi(char* str) {
int len = strlen(str);
bool minus = false;
int idx = 0;

while(idx < len)
{
if(str[idx] != ' ')
{
break;
}
else
{
idx++;
}
}

if(idx == len)
{
return 0;
}

if( str[idx] == '-')
{
minus = true;
idx++;
}
else if(str[idx] == '+')
{
idx++;
}
else if(!isDigit(str[idx]))
{
return 0;
}

int tmp ;
int result = 0;
while(idx < len && isDigit(str[idx]))
{
tmp = str[idx++] - '0';
if(minus)
{
if( result < ( (INT_MIN +  tmp) / 10 ))
{
return  INT_MIN ;
}
result = result * 10 - tmp;
}
else
{
if( result > ( (INT_MAX -tmp) / 10 ))
{
return  INT_MAX;
}
result = result * 10 + tmp;
}
}
return result;
}``````

• There are many tricks in plain-old null-terminated strings that you can make use of in cases like this. You can access the c_string of the string as :

``````const char* cstr = str.c_str();
``````

For example your code for skipping white spaces before any other character is:

``````while(idx < len)
{
if(str[idx] != ' ')
{
break;
}
else
{
idx++;
}
}
``````

can be reduced to

``````while (*cstr && (*cstr==' ' || *cstr=='\t')) ++cstr; // skip white space
``````

Sign comprehension in your code is

``````if( str[idx] == '-')
{
minus = true;
idx++;
}
else if(str[idx] == '+')
{
idx++;
}
``````

I would suggest something like this to get the sign and advance the pointer at the same time.

``````if (*cstr=='-' || cstr=='+')
negative = *cstr++ =='-' ? true: false;
``````

No need to detect the first character after the sign as a special case.

``````else if(!isDigit(str[idx]))
``````

Since you are starting with result = 0; it can be naturally handled by the following loop.

Here is the best part ;) ... No need to handle sign within the loop which construct the integer. Making the integer without the sign is clearer. A condition like below let you construct the integer value without worrying about it's sign and hence the overflow condition.

``````while (*cstr &&                      // while there is more
*cstr>='0' && *cstr<='9' &&    // numbers from 0~9
res< (long)INT_MAX+1)       // without result overflowing
``````

Since you want to increment the cstr pointer if this condition holds and keep building the number you might as well use a for loop instead.

``````for (;
*cstr &&                      // while there is more
*cstr>='0' && *cstr<='9' &&  // numbers from 0~9
res< (long)INT_MAX+1       // without result overflowing
; ++cstr)
res = res*10 + *cstr - '0' ;
``````

Finally you are left to apply the sign and clamp the result to INT_MIN and INT_MAX if it's out of range. There is no way around these without if-else but ternary operator looks elegant and quite readable too.

``````res = negative ? -res: res;       // apply sign
return res > INT_MAX ? INT_MAX :  // clamp on to MIN, MAX boundaries
res < INT_MIN ? INT_MIN : res ;
``````

You can find my complete solution here

Hope you learned some tricks with c-style strings ! ;)

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