1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#include <iostream>
#include <fstream>
#include <stack>
#include <ctype.h>
#include <sstream>
//----------------------------
// Added for pow function
#include <cmath>
using namespace std;
int prec(char elem)
{
switch(elem)
{
case '^' : return 3;
case '*' : return 2;
case '/' : return 2;
case '+' : return 1;
case '-' : return 1;
case '(' : return 0;
default : return -1;
}
}
int eval(char opn1, char elem, char opn2)
{
int result;
switch(elem)
{
//--------------------------------------------------
// Added the breaks
case '+' : result = opn1 + opn2;break;
case '-' : result = opn1 - opn2;break;
case '*' : result = opn1 * opn2;break;
case '/' : result = opn1 / opn2;break;
//--------------------------------------------------
// This has to be a the pow function because
// ^ is XOR not to the power
case '^' : result = int(pow(float(opn1),float(opn2)));break;
}
return result;
}
void in_to_post(string st)
{
string post;
char tok,opn1,opn2;
int result;
stack <char> ifx;
stack <char> pfx;
stringstream output, out2;
//------------------------------------------------------
// i should be just < not <= st.length()
for(int i = 0; i < st.length(); i++)
{
if(st[i] == ' ') i++;
if(st[i] == '^' || st[i] == '*' || st[i] == '/' ||
st[i] == '+' || st[i] == '-')
{
while(!ifx.empty() && prec(st[i]) <= prec(ifx.top()))
{
output << ifx.top();
ifx.pop();
}
ifx.push(st[i]);
}
else if(st[i] == '(')
{
ifx.push(st[i]);
}
else if(st[i] == ')')
{
while(ifx.top() != '(')
{
output << ifx.top();
ifx.pop();
}
ifx.pop();
}
else
{
output << st[i];
}
}
while(!ifx.empty())
{
output << ifx.top();
ifx.pop();
}
cout << output.str() <<endl;
post = output.str();
for(int i = 0; i < post.length(); i++)
{
tok = post[i];
if(isdigit(tok))
{
pfx.push(tok);
}
else
{
opn2 = pfx.top();
pfx.pop();
opn1 = pfx.top();
//---------------------------------------------
// Added the pop
pfx.pop();
//-----------------------------------------------------
// Cheated here by substacting the 0x30, but this
// is where your real issues start. This will work for
// the first equation because the value of the result and
// all intermeditate results are less than 8 bits. As soon
// as you try the second equation, the 5^6 (15,625) blows
// that apart and the code is broken. Once you start to
// populate pfx, the values stored must be integers and
// not chars. In that case the 0x30s would come out of
// the function call below and other spots below. But then
// where do you do that? If all of the numbers in the
// x.data file are never larger that one character than
// down here maybe, if not than you would have to change
// the loop above and the parsing becomes more complex.
//
// Take a look and see if just making the changes have pfx
// a stack<int> is OK.
result = eval(opn1-0x30, tok, opn2-0x30);
pfx.push(result+0x30);
}
}
while(!pfx.empty())
{
out2 << pfx.top()-0x30;
pfx.pop();
}
cout << out2.str() << endl;
}
int main()
{
string st, post;
ifstream infix;
stringstream output;
infix.open("x.data");
while(getline(infix, st))
{
cout << st << endl;
in_to_post(st);
}
infix.close();
return 0;
}
|
$ ./a.out
2 + 3 * 5
235*+
17 <------- Right
2 + 3 * 5 ^ 6
2356^*+
29 <------- Wrong because of 5^6
2 + 3 - 5 + 6 - 4 + 2 - 1
23+5-6+4-2+1-
3 <------- Right
2 + 3 * ( 5 - 6 ) - 4
2356-*+4-
-5 <------- Right
2 + 3 ^ 5 * 6 - 4
235^6*+4-
-80 <------- Wrong
2 + 3 * 6 ^ 2
2362^*+
-146 <------- Wrong
( ( ( ( 2 + 3 - 4 ) / 2 + 8 ) * 3 * ( 4 + 5 ) / 2 / 3 + 9 ) )
23+4-2/8+3*45+*2/3/9+
3 <------- Wrong because of fractions
$ |