Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iostream>
- #include <string>
- #include "Stack.h"
- #include "Queue.h"
- #include <sstream>
- #define _CRT_SECURE_NO_WARNINGS
- class Calculator
- {
- Queue<std::string> *postQueue;
- Stack<std::string> *postStack;
- std::string *stringArray;
- std::string *rev;
- int stringArraySize;
- int pqsize; //represents the postqueue size
- int pssize; //represents the poststack size
- public:
- Calculator() : stringArray(nullptr), stringArraySize(0), pqsize(0), pssize(0), postQueue(new Queue<std::string>), postStack(new Stack<std::string>) {};
- ~Calculator() { delete postQueue; delete postStack; deleteCharrArray(); }
- bool isValidString(std::string userString);
- void stringConvert(std::string userString);
- void deleteCharrArray();
- void postFixTransform();
- void postFixStoQ(Node<std::string> *operatorDNode, Node<std::string> *postTNode);
- void postFixEvaluation();
- void preFixTransform();
- void showQshowS(); //dummy function to verify the values
- void internalPreTransform();
- void preFixEval();
- };
- void Calculator::deleteCharrArray()
- {
- delete[] stringArray;
- stringArray = nullptr;
- }
- bool Calculator::isValidString(std::string userString)
- {
- int uStringSize = userString.length();
- bool validstring = false;
- int spacecount = 0;
- for (int i = 0; i < uStringSize; i++) //count the number of spaces in the string
- {
- if (userString[i] == ' ')
- spacecount++;
- }
- int testsize = spacecount + 1;
- std::string *testArr = new std::string[testsize];
- std::stringstream ss(userString);
- for (int i = 0; i < testsize; i++)
- {
- ss >> testArr[i];
- }
- for (int i = 0; i < testsize; i++)
- {
- int currentlength = testArr[i].length();
- char *testchar = new char[currentlength];
- bool valueIsDigit = false;
- for (int j = 0; j < currentlength; j++)
- {
- testchar[j] = testArr[i][j];
- if (isdigit(testchar[j]))
- valueIsDigit = true;
- if (!valueIsDigit) //test for negative numbers //example -10 is passed in, the loop breaks on the minus symbol.
- break;
- }
- delete[] testchar;
- testchar = nullptr;
- if (valueIsDigit)
- {
- validstring = true;
- }
- else if (!valueIsDigit && i != testsize - 1) //issue with have ")" as last element //ERROR HERE
- {
- if (testArr[i] == "+")
- validstring = true;
- else if (testArr[i] == "-")
- validstring = true;
- else if (testArr[i] == "*")
- validstring = true;
- else if (testArr[i] == "/")
- validstring = true;
- else if (testArr[i] == "%")
- validstring = true;
- /*else if (testArr[i] == ")")
- {
- char nextvaluetest = 'a';//dummy value
- if (i < testsize - 1) //if i is not the last value in the string;
- nextvaluetest = testArr[i + 1][0];
- bool openparanthesisexists = false;
- for (int j = 0; j < i; j++) //look through previous entries in the array to find open paranthesis.
- {
- if (testArr[j] == "(")
- {
- openparanthesisexists = true;
- break;
- }
- }
- if (!openparanthesisexists)
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- else
- validstring = true;
- if (isdigit(nextvaluetest))
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- }*/
- else if (testArr[i] == "(")
- {
- char prevvaluetest = 'a'; //dummy value
- if (i != 0) //i is not the first element in the string
- prevvaluetest = testArr[i - 1][0];
- bool closedparanthesisexists = false;
- for (int j = i; j < testsize; j++) //check if there is a closing paranthesis for the open paranthesis
- {
- if (testArr[j] == ")")
- {
- closedparanthesisexists = true;
- break;
- }
- }
- if (!closedparanthesisexists)
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- else
- validstring = true;
- if (isdigit(prevvaluetest))
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- }
- else
- {
- validstring = false;
- delete[] testArr;
- return validstring;
- }
- }
- else if (!valueIsDigit && testArr[i] == ")") //allows for paranthesis to be the end of a function
- {
- char nextvaluetest = 'a';//dummy value
- if (i < testsize - 1) //if i is not the last value in the string;
- nextvaluetest = testArr[i + 1][0];
- bool openparanthesisexists = false;
- for (int j = 0; j < i; j++) //look through previous entries in the array to find open paranthesis.
- {
- if (testArr[j] == "(")
- {
- openparanthesisexists = true;
- break;
- }
- }
- if (!openparanthesisexists)
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- else
- validstring = true;
- if (isdigit(nextvaluetest))
- {
- delete[] testArr;
- validstring = false;
- return validstring;
- }
- }
- else
- {
- validstring = false;
- delete[] testArr;
- return validstring;
- }
- }
- return validstring;
- }
- void Calculator::stringConvert(std::string userString) //cponvert string to char array.
- {
- int uStringSize = userString.length();
- int spacecount = 0;
- for (int i = 0; i < uStringSize; i++) //count the number of spaces in the string
- {
- if (userString[i] == ' ')
- spacecount++;
- }
- stringArraySize = spacecount + 1; //the number of elements present in the string should be 1 more than the number of spaces
- stringArray = new std::string[stringArraySize];
- std::stringstream ss(userString); //string strea to help with storing with space as the delimiter
- for (int i = 0; i < stringArraySize; i++)
- {
- ss >> stringArray[i];
- }
- /*for (int i = 0; i < stringArraySize; i++)
- {
- std::cout << stringArray[i] << std::endl;
- }//sample output of the string*/
- }
- void Calculator::postFixTransform()
- {
- for (int i = 0; i < stringArraySize; i++) //consider changing these declarations to make the function more efficient
- {
- Node<std::string> *postTNode = new Node<std::string>;
- bool valueIsDigit = false;
- int currentlenth = stringArray[i].length(); //check if value is a numerical
- postTNode->setData(stringArray[i]); //the node that is going to be pushed has the string value;
- char *charrarray = new char[currentlenth];
- for (int j = 0; j < currentlenth; j++) //store the contents of stringarray i into a charr aray and use isdigit to check if numerical
- {
- charrarray[j] = stringArray[i][j];
- if (isdigit(charrarray[j]))
- valueIsDigit = true;
- }
- delete[] charrarray; //check if this is deleteing the value in ths tring when you debug
- charrarray = nullptr;
- if (valueIsDigit)
- {
- postQueue->addQueue(postTNode);
- pqsize++;
- }
- /*else if (!valueIsDigit) //temporary for stack and queue tests
- {
- postStack->push(postTNode);
- pssize++;
- }*/
- else if (!valueIsDigit) //NOW FOR THE ACTUAL ELSE IF //need to add a count to move the remaining values in stack back to queue.
- {
- Node<std::string> *operatorDNode = new Node <std::string>; //used for moving stack operators to queue;
- if (stringArray[i] == "*") //each if else is a check for the PMMDAS operators.
- {
- if (postStack->getTop() == "/" || postStack->getTop() == "%")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else //condition for addition subtraction or a paranthesis
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (stringArray[i] == "/")
- {
- if (postStack->getTop() == "*" || postStack->getTop() == "%")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else //condition for addition subtraction or a paranthesis
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (stringArray[i] == "%")
- {
- if (postStack->getTop() == "*" || postStack->getTop() == "/")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else //condition for addition subtraction or a paranthesis
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (stringArray[i] == "+")
- {
- if (postStack->getTop() == "-" || postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "+")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (stringArray[i] == "-")
- {
- if (postStack->getTop() == "+" || postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "+")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (stringArray[i] == ")")
- {
- while (postStack->getTop() != "(") //pop all the values from stack to queue up till the open paranthesis
- {
- operatorDNode->setData(postStack->getTop());
- postStack->pop();
- pssize--;
- postQueue->addQueue(operatorDNode);
- pqsize++;
- }
- postStack->pop(); //get rid of the "("
- pssize--;
- }
- else if (stringArray[i] == "(")
- {
- postStack->push(postTNode);
- pssize++;
- }
- operatorDNode = nullptr;
- }
- postTNode = nullptr;
- }
- for (int i = 0; i < pssize;) //pop the remaining stack values into the queue
- {
- Node<std::string> *remainingpop = new Node<std::string>;
- remainingpop->setData(postStack->getTop());
- pssize--;
- postQueue->addQueue(remainingpop);
- pqsize++;
- postStack->pop();
- remainingpop = nullptr;
- }
- }
- void Calculator::postFixStoQ(Node<std::string> *operatorDNode, Node<std::string> *postTNode)
- {
- operatorDNode->setData(postStack->getTop()); //set dummy node to hold stacks top operator
- postStack->pop(); //this might be deleting the data that is being transferred to queue, not the pointer.
- pssize--;
- postQueue->addQueue(operatorDNode); //add the newly removed operator to queue
- pqsize++;
- postStack->push(postTNode); //add the new operator to stack
- pssize++;
- }
- void Calculator::showQshowS() //CURRENT ERROR IS IN THIS FUNCTION PREVENTS THE POST FIX EVALUATION FROM PROPERLY GOING //1:47 p.m. code may be fixed
- {
- std::string *QueueHolder = new std::string[pqsize];
- for (int i = 0; i < pqsize; i++)
- {
- std::cout << postQueue->getFirstData();
- QueueHolder[i] = postQueue->getFirstData();
- postQueue->removeFirst(); //this line is causing errors in the code. Though it is being using to show the queue values it is also removing that data. 1:20 p.m. 5/14
- }
- std::cout << std::endl;
- for (int i = 0; i < pqsize; i++) //loop to reset the queue 1:29 5/14 //Fixed: issue with this loop may have been the fact the node was being messed around with
- {
- Node<std::string> *Queuereset = new Node<std::string>;
- Queuereset->setData(QueueHolder[i]);
- postQueue->addQueue(Queuereset);
- Queuereset = nullptr;
- }
- /*std::cout << "\nThis is your current Stack: \n";
- for (int i = 0; i < pssize; i++)
- {
- std::cout << postStack->getTop() << std::endl;
- postStack->pop(); //this wont't even perform with the current setup, so it is fine.
- }*/
- }
- void Calculator::postFixEvaluation() //need to add a check for when the evaluation is over(i think)
- {
- int operand1; //these variables will be used to convers from string to int and evaluate the expression
- int operand2; //operand1 will serve as both operand1 and the result from the operation performed on both it and 2
- std::string soperand1; //soperand1 will serve as the conversion for operand1, as well as the convertion of the result from the expression.
- std::string soperand2;
- for (int i = 0; i < pqsize;) //these parameters may need to be changed //1:55 p.m. changed from i++ to have pqsize be the delimiter.
- {
- Node<std::string> *postENode = new Node<std::string>;
- int currentlenth = postQueue->getFirstData().length();
- bool valueIsDigit = false;
- char *charrarray = new char[currentlenth];
- for (int j = 0; j < currentlenth; j++) //digit check for data i queue
- {
- charrarray[j] = postQueue->getFirstData()[j];
- if (isdigit(charrarray[j]))
- valueIsDigit = true;
- }
- delete[] charrarray;
- charrarray = nullptr;
- if (valueIsDigit) //moves the integer from the queue into stack prepping it for evaluation.
- {
- postENode->setData(postQueue->getFirstData());
- postQueue->removeFirst();
- pqsize--;
- postStack->push(postENode);
- pssize++;
- }
- else if (!valueIsDigit)
- {
- soperand2 = postStack->getTop();
- postStack->pop();
- pssize--;
- soperand1 = postStack->getTop();
- postStack->pop();
- pssize--;
- operand1 = std::stoi(soperand1);
- operand2 = std::stoi(soperand2);
- if (postQueue->getFirstData() == "+")
- {
- operand1 = operand1 + operand2;
- postQueue->removeFirst();
- pqsize--;
- }
- else if (postQueue->getFirstData() == "-")
- {
- operand1 = operand1 - operand2;
- postQueue->removeFirst();
- pqsize--;
- }
- else if (postQueue->getFirstData() == "*")
- {
- operand1 = operand1 * operand2;
- postQueue->removeFirst();
- pqsize--;
- }
- else if (postQueue->getFirstData() == "/")
- {
- if (operand2 == 0)
- throw - 1;
- operand1 = operand1 / operand2;
- postQueue->removeFirst();
- pqsize--;
- }
- else if (postQueue->getFirstData() == "%")
- {
- operand1 = operand1 % operand2;
- postQueue->removeFirst();
- pqsize--;
- }
- if (i != pqsize) //check for if the evaluation is on the last expression
- {
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- }
- postENode = nullptr;
- }
- std::cout << "The result of your math expression using postfix is: " << operand1 << std::endl;
- }
- void Calculator::preFixTransform()
- {
- int x = stringArraySize;
- int n = 0;
- rev = new std::string[stringArraySize];
- while (x > 0)
- {
- rev[n] = stringArray[x - 1];
- x--;
- n++;
- }
- for (int i = 0; i < stringArraySize; i++)
- {
- if (rev[i] == ")")
- {
- rev[i] = "(";
- continue;
- }
- if (rev[i] == "(")
- {
- rev[i] = ")";
- }
- }
- internalPreTransform();
- x = pqsize;
- //showQshowS();
- while (x > 0)
- {
- //std::cout << postQueue->getFirstData();
- rev[x-1] = postQueue->getFirstData();
- postQueue->removeFirst();
- x--;
- }
- std::cout << std::endl;
- x = 0;
- while (x < pqsize)
- {
- Node<std::string> *revN = new Node<std::string>;
- revN->setData(rev[x]);
- postQueue->addQueue(revN);
- x++;
- }
- }
- void Calculator::internalPreTransform()
- {
- // we have the reversed string in rev
- //need to now take the reverse string and turn it into pseudo postfix by performing post fix with a equal or higher precedence
- for (int i = 0; i < stringArraySize; i++) //consider changing these declarations to make the function more efficient
- {
- Node<std::string> *postTNode = new Node<std::string>;
- bool valueIsDigit = false;
- int currentlenth = rev[i].length(); //check if value is a numerical
- postTNode->setData(rev[i]); //the node that is going to be pushed has the string value;
- char *charrarray = new char[currentlenth];
- for (int j = 0; j < currentlenth; j++) //store the contents of stringarray i into a charr aray and use isdigit to check if numerical
- {
- charrarray[j] = rev[i][j];
- if (isdigit(charrarray[j]))
- valueIsDigit = true;
- }
- delete[] charrarray; //check if this is deleteing the value in ths tring when you debug
- charrarray = nullptr;
- if (valueIsDigit)
- {
- postQueue->addQueue(postTNode);
- pqsize++;
- }
- /*else if (!valueIsDigit) //temporary for stack and queue tests
- {
- postStack->push(postTNode);
- pssize++;
- }*/
- else if (!valueIsDigit) //NOW FOR THE ACTUAL ELSE IF //need to add a count to move the remaining values in stack back to queue.
- {
- Node<std::string> *operatorDNode = new Node <std::string>; //used for moving stack operators to queue;
- if (rev[i] == "*") //each if else is a check for the PMMDAS operators.
- {
- postStack->push(postTNode);
- pssize++;
- }
- else if (rev[i] == "/")
- {
- postStack->push(postTNode);
- pssize++;
- }
- else if (rev[i] == "%")
- {
- postStack->push(postTNode);
- pssize++;
- }
- else if (rev[i] == "+")
- {
- if (postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "*")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (rev[i] == "-")
- {
- if (postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "*")
- {
- postFixStoQ(operatorDNode, postTNode);
- }
- else
- {
- postStack->push(postTNode);
- pssize++;
- }
- }
- else if (rev[i] == ")")
- {
- while (postStack->getTop() != "(") //pop all the values from stack to queue up till the open paranthesis
- {
- Node<std::string> *operatorSNode = new Node <std::string>;
- operatorSNode->setData(postStack->getTop());
- postStack->pop();
- pssize--;
- postQueue->addQueue(operatorSNode);
- pqsize++;
- operatorSNode = nullptr;
- }
- postStack->pop(); //get rid of the "("
- pssize--;
- }
- else if (rev[i] == "(")
- {
- postStack->push(postTNode);
- pssize++;
- }
- operatorDNode = nullptr;
- }
- postTNode = nullptr;
- }
- for (int i = 0; i < pssize;) //pop the remaining stack values into the queue
- {
- Node<std::string> *remainingpop = new Node<std::string>;
- remainingpop->setData(postStack->getTop());
- pssize--;
- postQueue->addQueue(remainingpop);
- pqsize++;
- postStack->pop();
- remainingpop = nullptr;
- }
- }
- void Calculator::preFixEval()
- {
- int operand1=0; //these variables will be used to convers from string to int and evaluate the expression
- int operand2=0; //operand1 will serve as both operand1 and the result from the operation performed on both it and 2
- std::string soperand1=""; //soperand1 will serve as the conversion for operand1, as well as the convertion of the result from the expression.
- std::string soperand2="";
- int digC = 0;
- //for checking make two bool values, one for if the digit is already a int, and another that if the next digit coming in is a int
- // take from the que pass to stack always check if there are two integers stacked ontop of each other, if there are, then perform operations
- for (int i = 0; i < pqsize;)
- {
- Node<std::string> *postENode = new Node<std::string>;
- int currentlenth = postQueue->getFirstData().length();
- bool valueIsDigit = false;
- char *charrarray = new char[currentlenth];
- if (pqsize > 0)
- {
- for (int j = 0; j < currentlenth; j++) //digit check for data i queue
- {
- charrarray[j] = postQueue->getFirstData()[j];
- if (isdigit(charrarray[j]))
- valueIsDigit = true;
- }
- if (valueIsDigit == true)
- digC++;
- else
- digC = 0;
- postENode->setData(postQueue->getFirstData());
- postStack->push(postENode);
- pssize++;
- postQueue->removeFirst();
- pqsize--;
- }
- if (digC == 2)
- {
- digC--;
- soperand1 = postStack->getTop();
- postStack->pop();
- pssize--;
- soperand2 = postStack->getTop();
- postStack->pop();
- pssize--;
- operand1 = std::stoi(soperand1);
- operand2 = std::stoi(soperand2);
- std::string op = postStack->getTop();
- postStack->pop();
- pssize--;
- if (op == "+")
- {
- operand1 = operand2 + operand1;
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- if (op == "-")
- {
- operand1 = operand2 - operand1;
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- if (op == "/")
- {
- operand1 = operand2 / operand1;
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- if (op == "%")
- {
- operand1 = operand2 % operand1;
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- if (op == "*")
- {
- operand1 = operand2 * operand1;
- soperand1 = std::to_string(operand1);
- postENode->setData(soperand1);
- postStack->push(postENode);
- pssize++;
- }
- }
- postENode = nullptr;
- }
- std::cout <<std::endl<< "the result of the evaluation for prefix is: " << soperand1 << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement