PROGRAM 2
// FILENAME: PROGRAM2.CPP AUTHOR: ANTHONY F. ORTIZ #include #include #include #include #include // THIS IS THE DECLARATION FOR A CLASS CALLED STACK. template class STACK { private: // THE STACK IS A LINKED LIST WITH NO HEADER. struct NODE { ELEMENT_TYPE ELEMENT; NODE * NEXT; NODE (ELEMENT_TYPE E = 0, NODE * N = 0): ELEMENT (E), NEXT (N) {} }; NODE * STACK_TOP; STACK (STACK & VALUE); // DISABLED. public: // DEFAULT STACK SIZE IS MEANINGLESS. STACK (unsigned int MAX_SIZE = 100) : STACK_TOP (0) {}; // DESTRUCTOR. ~STACK (); // OPERATORS. const STACK & operator = (const STACK & VALUE); // MEMBER FUNCTIONS. void PUSH (const ELEMENT_TYPE & X); void POP (); ELEMENT_TYPE POP_AND_TOP (); const ELEMENT_TYPE & TOP () const; int IS_EMPTY () const {return STACK_TOP == 0;} }; // THIS IS THE IMPLEMENTATION FOR A CLASS CALLED STACK. template inline void STACK :: PUSH (const ELEMENT_TYPE & X) { NODE * P = new NODE (X, STACK_TOP); if (P == 0) cout << "OUT OF MEMORY."; else STACK_TOP = P; } template inline const ELEMENT_TYPE & STACK :: TOP () const { if (IS_EMPTY ()) cout << "EMPTY STACK."; return STACK_TOP -> ELEMENT; } template inline void STACK :: POP () { NODE * P; if (IS_EMPTY ()) cout << "EMPTY STACK."; else { P = STACK_TOP -> NEXT; delete STACK_TOP; STACK_TOP = P; } } template inline ELEMENT_TYPE STACK :: POP_AND_TOP () { ELEMENT_TYPE TOP_ELEMENT = TOP (); if (! IS_EMPTY ()) POP (); return TOP_ELEMENT; } template STACK :: ~STACK () { NODE * P = STACK_TOP; while (P != 0) { NODE * AFTER_P = P -> NEXT; delete P; P = AFTER_P; } } // THIS IS THE DECLARATION FOR A CLASS CALLED EVALUATE. class EVALUATE { public: // CONSTRUCTOR. EVALUATE () {}; // DESTRUCTOR. ~EVALUATE () {}; // READS THE INFIX AS A STRING. READ_INFIX (); // CONVERTS THE INFIX TO A NUMBER STACK AND A // ARITHMETIC SYMBOL STACK. CONVERT_TO_STACKS (); // EVALUATES THE ARITHMETIC EXPRESSION. EVALUATE_POSTFIX (); // PRINTS THE POSTFIX EVALUATION. PRINT_POSTFIX (); private: // THIS IS THE STRING WHICH WILL TEMPORARY HOLD THE // INFIX EXPRESSION UNTIL IT IS CONVERTED TO // A NUMBER AND ARITHMETIC SYMBOL STACK. char INFIX [100]; // THIS WILL HOLD THE INFIX NUMBERS. STACK INPUT_NUMBERS; // THIS WILL HOLD THE INFIX ARITHMETIC SYMBOLS. STACK INPUT_SYMBOLS; // THIS WILL HOLD THE RESULT OF THE POSTFIX EVALUATION. int RESULT; }; // THIS IS THE IMPLEMENTATION OF A CLASS CALLED EVALUATE. // READS THE INFIX AS A STRING. EVALUATE :: READ_INFIX () { // CLEAR SCREEN AND ENTER THE ARITHMETIC EXPRESSION. // THIS PART IS NOT ERROR CHECKED SO THE USER MUST // ENTER A BLANK BEFORE EACH NUMBER AND SYMBOL. ALSO // THE USER MUST ENTER A EQUALS SIGN. OTHERWISE, THE // RESULT IS UNPREDICTABLE. clrscr (); cout << "ENTER A NUMERIC EXPRESSION. PLEASE TYPE A SPACE "; cout << "AFTER EACH NUMBER OR SYMBOL " << endl; cout << "AND END WITH A '='. "; cout << endl << endl; gets (INFIX); cout << endl << endl; return 0; } // CONVERT THE INFIX STRING INTO A NUMBER AND ARITHMETIC SYMBOL STACK. EVALUATE :: CONVERT_TO_STACKS () { // THIS VARIABLE HOLDS THE CHARACTER COUNT FOR THE STRING. int COUNT = 0; // THIS VARIABLE HOLDS THE COUNT OF THE INDIVIDUAL DIGITS OF EACH // NUMBER IN THE STRING. int COUNT2 = 0; // THIS VARIABLE HOLDS THE DIGITS OF A NUMBER SO IT CAN LATER BE // CHANGED TO A NUMBER USING THE ATOI FUNCTION. char NUMBER [10]; // THIS HOLDS THE NUMBERS AND THE SYMBOLS TEMPORARILY FOR THE // INFIX EXPRESSION. BECAUSE THE STACKS WILL HAVE THE INFIX IN THE // REVERSE ORDER THAT I WANT THEM IN, I WILL LATER USE POP AND PUSH // STACK FUNCTIONS TO PUT THEM IN THE CLASS'S INPUT STACKS. THEY // WILL THEN BE IN THE CORRECT ORDER. STACK TEMP_SYMBOLS; STACK TEMP_NUMBERS; // STOP LOOP WHEN INFIX = END OF STRING MARKER. while (INFIX [COUNT] != '\0') { // IF THE CHARACTER IS A DIGIT, CONVERT IT TO A NUMBER. if (int (INFIX [COUNT]) <= 57 && int (INFIX [COUNT]) >= 48) { // PUT THE INFIX CHARACTER STRING INTO THE NUMBER // CHARACTER STRING. NUMBER [COUNT2] = INFIX [COUNT]; // COUNT THE NUMBER OF DIGITS IN THE NUMBER STRING. COUNT2 = COUNT2 + 1; // IF THE NEXT CHARACTER EQUALS A SPACE, THEN // CONVERT CHARACTER STRING TO A INTEGER NUMBER AND // PLACE IT ON THE NUMBER STACK. if (INFIX [COUNT + 1] == ' ' || INFIX [COUNT + 1] == '\0') { NUMBER [COUNT2] = '\0'; TEMP_NUMBERS.PUSH (atol (NUMBER)); // INITIALIZE NEXT CHARACTER NUMBER TO 0. COUNT2 = 0; } } // IF INFIX CHARACTER IS A MATH OPERATOR, PUT IT INTO // THE SYMBOL STACK. else if (INFIX [COUNT] == '+' || INFIX [COUNT] == '-' || INFIX [COUNT] == '*' || INFIX [COUNT] == '/' || INFIX [COUNT] == '=') { TEMP_SYMBOLS.PUSH (INFIX [COUNT]); } // COUNT THE NEXT CHARACTER IN THE INFIX STRING. COUNT = COUNT + 1; } // PUT THE SYMBOLS IN THE TEMP STACK VARIABLE INTO INPUT STACK // SYMBOL VARIABLE. THIS WILL PUT THE SYMBOLS IN THE CORRECT ORDER. while (!TEMP_SYMBOLS.IS_EMPTY ()) { INPUT_SYMBOLS.PUSH (TEMP_SYMBOLS.POP_AND_TOP ()); } // PUT THE NUMBERS IN THE TEMP STACK VARIABLE INTO INPUT STACK // NUMBER VARIABLE. THIS WILL PUT THE NUMBERS IN THE CORRECT ORDER. while (!TEMP_NUMBERS.IS_EMPTY ()) { INPUT_NUMBERS.PUSH (TEMP_NUMBERS.POP_AND_TOP ()); } return 0; } // EVALUATE THE ARITHMETIC EXPRESSION. EVALUATE :: EVALUATE_POSTFIX () { // THIS STACK VARIABLE WILL HOLD THE EVALUATIONS OF THE // NUMBERS, IF THERE IS ANY. STACK OUTPUT_NUMBERS; // THIS STACK VARIABLE WILL HOLD THE SYMBOLS. STACK OUTPUT_SYMBOLS; // POP THE FIRST NUMBER FROM THE INPUT STACK (NUMBERS) AND PUT IT IN // THE OUTPUT STACK VARIABLE (NUMBERS). OUTPUT_NUMBERS.PUSH (INPUT_NUMBERS.POP_AND_TOP ()); // STOP LOOP WHEN INPUT STACK SYMBOL EQUALS '='. while (INPUT_SYMBOLS.TOP () != '=') { // POP ANOTHER NUMBER FROM THE INPUT STACK (NUMBERS) AND PUT // IT IN THE OUTPUT STACK VARIABLE (NUMBERS. OUTPUT_NUMBERS.PUSH (INPUT_NUMBERS.POP_AND_TOP ()); // POP THE SYMBOL FROM THE INPUT STACK (SYMBOLS) AND PUT IT // IN THE OUTPUT STACK VARIABLE (SYMBOLS). OUTPUT_SYMBOLS.PUSH (INPUT_SYMBOLS.POP_AND_TOP ()); // IF THE TOP OF THE OUPUT SYMBOL STACK = '*' THEN // POP THE NUMBERS FROM THE OUTPUT STACK (NUMBERS) // AND MULTIPLY THEM. THEN POP THE THE SYMBOL FROM THE // OUTPUT STACK (SYMBOLS). if (OUTPUT_SYMBOLS.TOP () == '*') { long int NUMBER1 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER2 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER3 = NUMBER2 * NUMBER1; OUTPUT_NUMBERS.PUSH (NUMBER3); OUTPUT_SYMBOLS.POP_AND_TOP (); } // IF THE TOP OF THE OUPUT SYMBOL STACK = '/' THEN // POP THE NUMBERS FROM THE OUTPUT STACK (NUMBERS) // AND DIVIDE THEM. THEN POP THE THE SYMBOL FROM THE // OUTPUT STACK (SYMBOLS). else if (OUTPUT_SYMBOLS.TOP () == '/') { long int NUMBER1 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER2 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER3 = NUMBER2 / NUMBER1; OUTPUT_NUMBERS.PUSH (NUMBER3); OUTPUT_SYMBOLS.POP_AND_TOP (); } } // PUT THE LAST SYMBOL FROM THE INPUT STACK (SYMBOLS) INTO // THE OUTPUT STACK (SYMBOLS). OUTPUT_SYMBOLS.PUSH (INPUT_SYMBOLS.POP_AND_TOP ()); // NOW THE NUMBERS AND SYMBOLS ARE AGAIN IN THE WRONG ORDER SO // REVERSE THE ORDER BY POPING THEM OUT OF THE OUTPUT STACKS // FOR NUMBERS AND SYMBOLS AND PUT THEM BACK IN THE INPUT // STACK FOR NUMBERS AND SYMBOLS. while (!OUTPUT_SYMBOLS.IS_EMPTY ()) { INPUT_SYMBOLS.PUSH (OUTPUT_SYMBOLS.POP_AND_TOP ()); } while (!OUTPUT_NUMBERS.IS_EMPTY ()) { INPUT_NUMBERS.PUSH (OUTPUT_NUMBERS.POP_AND_TOP ()); } // REPEAT THE ABOVE PROCESS FOR ADDITION AND SUBTRACTION. // POP THE FIRST NUMBER FROM THE INPUT STACK (NUMBERS) AND PUT IT IN // THE OUTPUT STACK VARIABLE (NUMBERS). OUTPUT_NUMBERS.PUSH (INPUT_NUMBERS.POP_AND_TOP ()); // STOP LOOP WHEN INPUT STACK SYMBOL EQUALS '='. while (INPUT_SYMBOLS.TOP () != '=') { // POP ANOTHER NUMBER FROM THE INPUT STACK (NUMBERS) AND PUT // IT IN THE OUTPUT STACK VARIABLE (NUMBERS. OUTPUT_NUMBERS.PUSH (INPUT_NUMBERS.POP_AND_TOP ()); // POP THE SYMBOL FROM THE INPUT STACK (SYMBOLS) AND PUT IT // IN THE OUTPUT STACK VARIABLE (SYMBOLS). OUTPUT_SYMBOLS.PUSH (INPUT_SYMBOLS.POP_AND_TOP ()); // IF THE TOP OF THE OUPUT SYMBOL STACK = '+' THEN // POP THE NUMBERS FROM THE OUTPUT STACK (NUMBERS) // AND ADD THEM. THEN POP THE THE SYMBOL FROM THE // OUTPUT STACK (SYMBOLS). if (OUTPUT_SYMBOLS.TOP () == '+') { long int NUMBER1 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER2 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER3 = NUMBER2 + NUMBER1; OUTPUT_NUMBERS.PUSH (NUMBER3); OUTPUT_SYMBOLS.POP_AND_TOP (); } // IF THE TOP OF THE OUPUT SYMBOL STACK = '-' THEN // POP THE NUMBERS FROM THE OUTPUT STACK (NUMBERS) // AND SUBTRACT THEM. THEN POP THE THE SYMBOL FROM THE // OUTPUT STACK (SYMBOLS). else if (OUTPUT_SYMBOLS.TOP () == '-') { long int NUMBER1 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER2 = OUTPUT_NUMBERS.POP_AND_TOP (); long int NUMBER3 = NUMBER2 - NUMBER1; OUTPUT_NUMBERS.PUSH (NUMBER3); OUTPUT_SYMBOLS.POP_AND_TOP (); } } // POP THE LAST NUMBER FROM THE OUTPUT STACK FOR NUMBERS AND // PUT IT IN THE VARIABLE CALLED RESULT. RESULT = OUTPUT_NUMBERS.POP_AND_TOP (); return 0; } // PRINT THE POSTFIX RESULT. EVALUATE :: PRINT_POSTFIX () { cout << "THE RESULT OF THE POSTFIX IS " << RESULT << endl; return 0; } // THIS PROGRAM EVALUATES A POSTFIX EXPRESSION. int main () { // DECALARE THE VARIABLE FOR THE EVALUATE CLASS. EVALUATE AEXPRESSION; // READ IT IN AS A STRING FROM THE KEYBOARD. AEXPRESSION.READ_INFIX (); // CONVERT IT TO TWO INPUT STACKS, ONE FOR NUMBERS, THE OTHER FOR // SYMBOLS. AEXPRESSION.CONVERT_TO_STACKS (); // EVALUATE THEM BY PUTTING THE INPUT STACKS INTO OUTPUT STACKS. AEXPRESSION.EVALUATE_POSTFIX (); // PRINT THE RESULT. AEXPRESSION.PRINT_POSTFIX (); return 0; } // OUTFILE: PROG2.OUT ENTER A NUMERIC EXPRESSION. PLEASE TYPE A SPACE AFTER EACH NUMBER OR SYMBOL AND END WITH A '='. 1 + 2 - 3 / 1 * 10 = THE RESULT OF THE POSTFIX IS -27
BACK TO CS3240 PAGE.