Skip to content

Instantly share code, notes, and snippets.

@Sergi0
Created November 15, 2011 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sergi0/1365663 to your computer and use it in GitHub Desktop.
Save Sergi0/1365663 to your computer and use it in GitHub Desktop.
RPN updated version
#define _PREP_AOP_ { if (args.size() < 2) return i + 1; arg2 = args.top(); args.pop(); arg1 = args.top(); args.pop(); }
#define _CHECK_ADD_RES_ { if (args.top() - arg2 != arg1) return i + 1; }
#define _CHECK_SUB_RES_ { if (args.top() + arg2 != arg1) return i + 1; }
#define _CHECK_MUL_ARG_ { if (arg2 != 0 && arg1 > LONG_MAX / arg2) return i + 1; }
#define _CHECK_DIV_ARG_ { if (arg2 == 0 || (arg1 == LONG_MIN && arg2 == -1)) return i + 1; }
int RPN(char *str, int rdx, long &res)
{
if (str == NULL || str[0] == NULL)
return false;
stack<long> args;
long arg1;
long arg2;
long num;
for (size_t i = 0; str[i] != 0; ++i)
{
switch(str[i])
{
case ' ':
continue;
break;
case '+':
_PREP_AOP_;
args.push(arg1 + arg2);
_CHECK_ADD_RES_;
break;
case '-':
if (str[i + 1] != 0 && isdigit(str[i + 1]))
continue;
_PREP_AOP_;
args.push(arg1 - arg2);
_CHECK_SUB_RES_;
break;
case '*':
_PREP_AOP_;
_CHECK_MUL_ARG_;
args.push(arg1 * arg2);
break;
case '/':
_PREP_AOP_;
_CHECK_DIV_ARG_;
args.push(arg1 / arg2);
break;
default:
{
if (isdigit(str[i]) == 0)
return i + 1;
char *stop;
num = strtol(str + i, &stop, rdx);
if (*stop == 0 || num == LONG_MAX || num == LONG_MIN)
return i + 1;
bool bMinus = (i != 0 && str[i - 1] == '-');
args.push(bMinus ? -num : num);
i = stop - str;
}
}
}
if (args.size() == 1)
{
res = args.top();
return 0;
}
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment