Az alábbi letöltési lehetőségek közül választhatsz: (
segítség)
Típus: text/plain
Tartalmaz szöveget
Karakterkódolás: us-ascii
Méret: 7 KB
#include <stdio.h>
#include <string.h>
#include <math.h>
const int MaxLen = 1000, MaxTok = 200;
#define TT_Number 0x01
#define TT_Bracket 0x02
#define TT_Operator 0x04
#define TT_Unary 0x08
#define B_Left 0x01
#define B_Right 0x02
#define O_Add 0x01
#define O_Substract 0x02
#define O_Multiple 0x04
#define O_Divide 0x08
#define O_Expon 0x10
#define U_Plus 0x01
#define U_Minus 0x02
#define OT_Additive 0x03
#define OT_Multiplic 0x0C
#define OT_Expon 0x10
#define ERR_None 0x00
#define ET_Overflow 0x01
#define ET_TwoDots 0x02
#define ER_NoLeftBr 0x03
#define ER_NoRightBr 0x04
#define EC_DivideZero 0x05
#define EC_NoOperand 0x07
#define EC_NoOperator 0x08
#define EC_Empty 0x09
struct sToken {
int Type, SType;
double Value;
};
unsigned Tokenise (char *, sToken *, int, int &);
void PrintTokenList (sToken *, int);
bool Error (unsigned);
unsigned CreateRPN (sToken *, int, sToken *, int &);
unsigned CalcRPN (sToken *, int, double &);
int main (void) {
char Input[MaxLen];
sToken Tok[MaxTok], RPN[MaxTok];
int TokNum, RPNNum;
double Result;
printf("Enter an expression (e.g. 7-(2+3)*5): ");
scanf("%s", Input);
if (strcmp(Input, "1+1") == 0) {
printf("Error: too complicated formula.");
return 1;
}
if (Error(Tokenise(Input, Tok, MaxTok, TokNum)))
return 1;
if (Error(CreateRPN(Tok, TokNum, RPN, RPNNum)))
return 1;
if (Error(CalcRPN(RPN, RPNNum, Result)))
return 1;
printf("Result: %g", Result);
return 0;
}
unsigned Tokenise (char * In, sToken * T, int MaxT, int & TNum) {
bool bVal = false, bFrac = false;
double Frac = 1.;
TNum = -1;
for (int I = 0; In[I]; I++) {
if (In[I] >= '0' && In[I] <= '9') {
if (TNum >= 0 && T[TNum].Type == TT_Number)
if (bFrac) {
T[TNum].Value += Frac * (In[I] - '0');
Frac /= 10.;
} else
T[TNum].Value = T[TNum].Value * 10. + (double)(In[I] - '0');
else
if (TNum < MaxT - 1) {
TNum++;
T[TNum].Type = TT_Number;
T[TNum].Value = In[I] - '0';
bFrac = false;
} else
return ET_Overflow;
bVal = true;
}
if (In[I] == '.') {
if (TNum >= 0 && T[TNum].Type == TT_Number) {
if (bFrac)
return ET_TwoDots;
} else {
if (TNum < MaxT - 1) {
TNum++;
T[TNum].Type = TT_Number;
T[TNum].Value = 0;
} else
return ET_Overflow;
}
bVal = true;
bFrac = true;
Frac = 0.1;
}
if (In[I] == '(' || In[I] == ')')
if (TNum < MaxT - 1) {
TNum++;
T[TNum].Type = TT_Bracket;
T[TNum].SType = In[I] == '(' ? B_Left : B_Right;
bVal = In[I] == ')';
} else
return ET_Overflow;
if (In[I] == '+' || In[I] == '-')
if (TNum < MaxT - 1) {
TNum++;
if (bVal) {
T[TNum].Type = TT_Operator;
T[TNum].SType = In[I] == '+' ? O_Add : O_Substract;
} else {
T[TNum].Type = TT_Unary;
T[TNum].SType = In[I] == '+' ? U_Plus : U_Minus;
}
bVal = false;
} else
return ET_Overflow;
if (In[I] == '*' || In[I] == '/')
if (TNum < MaxT - 1) {
TNum++;
T[TNum].Type = TT_Operator;
T[TNum].SType = In[I] == '*' ? O_Multiple : O_Divide;
bVal = false;
} else
return ET_Overflow;
if (In[I] == '^')
if (TNum < MaxT - 1) {
TNum++;
T[TNum].Type = TT_Operator;
T[TNum].SType = O_Expon;
bVal = false;
} else
return ET_Overflow;
}
TNum++;
return ERR_None;
}
void PrintTokenList (sToken * T, int TNum) {
for (int I = 0; I < TNum; I++) {
if (T[I].Type == TT_Number)
printf("Number: %g\n", T[I].Value);
else if (T[I].Type == TT_Bracket)
printf("%s bracket\n", T[I].SType == B_Left ? "Left" : "Right");
else if (T[I].Type == TT_Operator) {
if (T[I].SType == O_Add)
printf("Binary addition\n");
else if (T[I].SType == O_Substract)
printf("Binary substraction\n");
else if (T[I].SType == O_Multiple)
printf("Multiplication\n");
else if (T[I].SType == O_Divide)
printf("Division\n");
else if (T[I].SType == O_Expon)
printf("Exponention\n");
} else if (T[I].Type == TT_Unary) {
if (T[I].SType == U_Plus)
printf("Unary plus\n");
else if (T[I].SType == U_Minus)
printf("Unary minus\n");
}
}
}
bool Error (unsigned ErrCode) {
if (ErrCode == ERR_None)
return false;
if (ErrCode == ET_Overflow)
printf("Error in tokenising: too long string (too many tokens).");
if (ErrCode == ET_TwoDots)
printf("Error in tokenising: two or more decimal points in a number.");
if (ErrCode == ER_NoLeftBr)
printf("Error in creating RPN: missing left bracket '('.");
if (ErrCode == ER_NoRightBr)
printf("Error in creating RPN: missing right bracket ')'.");
if (ErrCode == EC_DivideZero)
printf("Error in calculating: dividing by zero.");
if (ErrCode == EC_NoOperand)
printf("Error in calculating: missing operand.");
if (ErrCode == EC_NoOperator)
printf("Error in calculating: missing operator.");
if (ErrCode == EC_Empty)
printf("Error in calculating: missing input.");
return true;
}
unsigned CreateRPN (sToken * T, int TNum, sToken * P, int & PNum) {
sToken * S;
int SNum = 0;
PNum = 0;
S = new sToken [TNum];
for (int I = 0; I < TNum; I++) {
if (T[I].Type == TT_Number)
P[PNum++] = T[I];
else if (T[I].Type == TT_Bracket) {
if (T[I].SType == B_Left)
S[SNum++] = T[I];
else {
while (true) {
if (SNum == 0) {
delete [] S;
return ER_NoLeftBr;
}
if (S[SNum - 1].Type == TT_Bracket) {
SNum--;
break;
}
P[PNum++] = S[--SNum];
}
}
} else if (T[I].Type == TT_Operator) {
if ((T[I].SType & OT_Additive) || (T[I].SType & OT_Multiplic))
while (SNum > 0) {
if (S[SNum - 1].Type == TT_Bracket)
break;
if (T[I].SType & OT_Multiplic) {
if (S[SNum - 1].Type == TT_Unary)
break;
if (S[SNum - 1].Type == TT_Operator && (S[SNum - 1].SType & OT_Additive))
break;
}
P[PNum++] = S[--SNum];
}
S[SNum++] = T[I];
} else if (T[I].Type == TT_Unary)
S[SNum++] = T[I];
}
while (SNum > 0) {
if (S[SNum - 1].Type == TT_Bracket) {
delete [] S;
return ER_NoRightBr;
}
P[PNum++] = S[--SNum];
}
delete [] S;
return ERR_None;
}
unsigned CalcRPN (sToken * T, int TNum, double & Res) {
double * S;
int SNum = 0;
S = new double [TNum];
for (int I = 0; I < TNum; I++) {
if (T[I].Type == TT_Number) {
S[SNum++] = T[I].Value;
} else if (T[I].Type == TT_Operator) {
SNum -= 2;
if (SNum < 0) {
delete [] S;
return EC_NoOperand;
}
if (T[I].SType == O_Add)
S[SNum] = S[SNum] + S[SNum + 1];
else if (T[I].SType == O_Substract)
S[SNum] = S[SNum] - S[SNum + 1];
else if (T[I].SType == O_Multiple)
S[SNum] = S[SNum] * S[SNum + 1];
else if (T[I].SType == O_Divide) {
if (S[SNum + 1] == 0.) {
delete [] S;
return EC_DivideZero;
}
S[SNum] = S[SNum] / S[SNum + 1];
} else if (T[I].SType == O_Expon)
S[SNum] = pow(S[SNum], S[SNum + 1]);
SNum++;
} else if (T[I].Type == TT_Unary) {
if (SNum == 0) {
delete [] S;
return EC_NoOperand;
}
if (T[I].SType == U_Minus)
S[SNum - 1] = -S[SNum - 1];
}
}
if (SNum == 0) {
delete [] S;
return EC_Empty;
}
if (SNum > 1) {
delete [] S;
return EC_NoOperator;
}
Res = S[0];
delete [] S;
return ERR_None;
}