Advertisement
Guest User

Untitled

a guest
May 16th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.92 KB | None | 0 0
  1. #pragma once
  2. #include <iostream>
  3. #include <string>
  4. #include "Stack.h"
  5. #include "Queue.h"
  6. #include <sstream>
  7. #define _CRT_SECURE_NO_WARNINGS
  8.  
  9. class Calculator
  10. {
  11. Queue<std::string> *postQueue;
  12. Stack<std::string> *postStack;
  13. std::string *stringArray;
  14. std::string *rev;
  15. int stringArraySize;
  16. int pqsize; //represents the postqueue size
  17. int pssize; //represents the poststack size
  18. public:
  19. Calculator() : stringArray(nullptr), stringArraySize(0), pqsize(0), pssize(0), postQueue(new Queue<std::string>), postStack(new Stack<std::string>) {};
  20. ~Calculator() { delete postQueue; delete postStack; deleteCharrArray(); }
  21. bool isValidString(std::string userString);
  22. void stringConvert(std::string userString);
  23. void deleteCharrArray();
  24. void postFixTransform();
  25. void postFixStoQ(Node<std::string> *operatorDNode, Node<std::string> *postTNode);
  26. void postFixEvaluation();
  27. void preFixTransform();
  28. void showQshowS(); //dummy function to verify the values
  29. void internalPreTransform();
  30. void preFixEval();
  31. };
  32.  
  33. void Calculator::deleteCharrArray()
  34. {
  35. delete[] stringArray;
  36. stringArray = nullptr;
  37. }
  38. bool Calculator::isValidString(std::string userString)
  39. {
  40. int uStringSize = userString.length();
  41. bool validstring = false;
  42. int spacecount = 0;
  43. for (int i = 0; i < uStringSize; i++) //count the number of spaces in the string
  44. {
  45. if (userString[i] == ' ')
  46. spacecount++;
  47. }
  48. int testsize = spacecount + 1;
  49. std::string *testArr = new std::string[testsize];
  50. std::stringstream ss(userString);
  51. for (int i = 0; i < testsize; i++)
  52. {
  53. ss >> testArr[i];
  54. }
  55. for (int i = 0; i < testsize; i++)
  56. {
  57. int currentlength = testArr[i].length();
  58. char *testchar = new char[currentlength];
  59. bool valueIsDigit = false;
  60. for (int j = 0; j < currentlength; j++)
  61. {
  62. testchar[j] = testArr[i][j];
  63. if (isdigit(testchar[j]))
  64. valueIsDigit = true;
  65. if (!valueIsDigit) //test for negative numbers //example -10 is passed in, the loop breaks on the minus symbol.
  66. break;
  67. }
  68. delete[] testchar;
  69. testchar = nullptr;
  70. if (valueIsDigit)
  71. {
  72. validstring = true;
  73. }
  74. else if (!valueIsDigit && i != testsize - 1) //issue with have ")" as last element //ERROR HERE
  75. {
  76. if (testArr[i] == "+")
  77. validstring = true;
  78. else if (testArr[i] == "-")
  79. validstring = true;
  80. else if (testArr[i] == "*")
  81. validstring = true;
  82. else if (testArr[i] == "/")
  83. validstring = true;
  84. else if (testArr[i] == "%")
  85. validstring = true;
  86. /*else if (testArr[i] == ")")
  87. {
  88. char nextvaluetest = 'a';//dummy value
  89. if (i < testsize - 1) //if i is not the last value in the string;
  90. nextvaluetest = testArr[i + 1][0];
  91. bool openparanthesisexists = false;
  92. for (int j = 0; j < i; j++) //look through previous entries in the array to find open paranthesis.
  93. {
  94. if (testArr[j] == "(")
  95. {
  96. openparanthesisexists = true;
  97. break;
  98. }
  99. }
  100. if (!openparanthesisexists)
  101. {
  102. delete[] testArr;
  103. validstring = false;
  104. return validstring;
  105. }
  106. else
  107. validstring = true;
  108. if (isdigit(nextvaluetest))
  109. {
  110. delete[] testArr;
  111. validstring = false;
  112. return validstring;
  113. }
  114. }*/
  115. else if (testArr[i] == "(")
  116. {
  117. char prevvaluetest = 'a'; //dummy value
  118. if (i != 0) //i is not the first element in the string
  119. prevvaluetest = testArr[i - 1][0];
  120. bool closedparanthesisexists = false;
  121. for (int j = i; j < testsize; j++) //check if there is a closing paranthesis for the open paranthesis
  122. {
  123. if (testArr[j] == ")")
  124. {
  125. closedparanthesisexists = true;
  126. break;
  127. }
  128. }
  129. if (!closedparanthesisexists)
  130. {
  131. delete[] testArr;
  132. validstring = false;
  133. return validstring;
  134. }
  135. else
  136. validstring = true;
  137. if (isdigit(prevvaluetest))
  138. {
  139. delete[] testArr;
  140. validstring = false;
  141. return validstring;
  142. }
  143. }
  144. else
  145. {
  146. validstring = false;
  147. delete[] testArr;
  148. return validstring;
  149. }
  150. }
  151. else if (!valueIsDigit && testArr[i] == ")") //allows for paranthesis to be the end of a function
  152. {
  153. char nextvaluetest = 'a';//dummy value
  154. if (i < testsize - 1) //if i is not the last value in the string;
  155. nextvaluetest = testArr[i + 1][0];
  156. bool openparanthesisexists = false;
  157. for (int j = 0; j < i; j++) //look through previous entries in the array to find open paranthesis.
  158. {
  159. if (testArr[j] == "(")
  160. {
  161. openparanthesisexists = true;
  162. break;
  163. }
  164. }
  165. if (!openparanthesisexists)
  166. {
  167. delete[] testArr;
  168. validstring = false;
  169. return validstring;
  170. }
  171. else
  172. validstring = true;
  173. if (isdigit(nextvaluetest))
  174. {
  175. delete[] testArr;
  176. validstring = false;
  177. return validstring;
  178. }
  179. }
  180. else
  181. {
  182. validstring = false;
  183. delete[] testArr;
  184. return validstring;
  185. }
  186. }
  187. return validstring;
  188. }
  189. void Calculator::stringConvert(std::string userString) //cponvert string to char array.
  190. {
  191. int uStringSize = userString.length();
  192. int spacecount = 0;
  193. for (int i = 0; i < uStringSize; i++) //count the number of spaces in the string
  194. {
  195. if (userString[i] == ' ')
  196. spacecount++;
  197. }
  198. stringArraySize = spacecount + 1; //the number of elements present in the string should be 1 more than the number of spaces
  199. stringArray = new std::string[stringArraySize];
  200. std::stringstream ss(userString); //string strea to help with storing with space as the delimiter
  201. for (int i = 0; i < stringArraySize; i++)
  202. {
  203. ss >> stringArray[i];
  204. }
  205. /*for (int i = 0; i < stringArraySize; i++)
  206. {
  207. std::cout << stringArray[i] << std::endl;
  208. }//sample output of the string*/
  209. }
  210. void Calculator::postFixTransform()
  211. {
  212. for (int i = 0; i < stringArraySize; i++) //consider changing these declarations to make the function more efficient
  213. {
  214. Node<std::string> *postTNode = new Node<std::string>;
  215. bool valueIsDigit = false;
  216. int currentlenth = stringArray[i].length(); //check if value is a numerical
  217. postTNode->setData(stringArray[i]); //the node that is going to be pushed has the string value;
  218. char *charrarray = new char[currentlenth];
  219. for (int j = 0; j < currentlenth; j++) //store the contents of stringarray i into a charr aray and use isdigit to check if numerical
  220. {
  221. charrarray[j] = stringArray[i][j];
  222. if (isdigit(charrarray[j]))
  223. valueIsDigit = true;
  224. }
  225. delete[] charrarray; //check if this is deleteing the value in ths tring when you debug
  226. charrarray = nullptr;
  227. if (valueIsDigit)
  228. {
  229. postQueue->addQueue(postTNode);
  230. pqsize++;
  231. }
  232. /*else if (!valueIsDigit) //temporary for stack and queue tests
  233. {
  234. postStack->push(postTNode);
  235. pssize++;
  236. }*/
  237. else if (!valueIsDigit) //NOW FOR THE ACTUAL ELSE IF //need to add a count to move the remaining values in stack back to queue.
  238. {
  239. Node<std::string> *operatorDNode = new Node <std::string>; //used for moving stack operators to queue;
  240. if (stringArray[i] == "*") //each if else is a check for the PMMDAS operators.
  241. {
  242. if (postStack->getTop() == "/" || postStack->getTop() == "%")
  243. {
  244. postFixStoQ(operatorDNode, postTNode);
  245. }
  246. else //condition for addition subtraction or a paranthesis
  247. {
  248. postStack->push(postTNode);
  249. pssize++;
  250. }
  251. }
  252. else if (stringArray[i] == "/")
  253. {
  254. if (postStack->getTop() == "*" || postStack->getTop() == "%")
  255. {
  256. postFixStoQ(operatorDNode, postTNode);
  257. }
  258. else //condition for addition subtraction or a paranthesis
  259. {
  260. postStack->push(postTNode);
  261. pssize++;
  262. }
  263. }
  264. else if (stringArray[i] == "%")
  265. {
  266. if (postStack->getTop() == "*" || postStack->getTop() == "/")
  267. {
  268. postFixStoQ(operatorDNode, postTNode);
  269. }
  270. else //condition for addition subtraction or a paranthesis
  271. {
  272. postStack->push(postTNode);
  273. pssize++;
  274. }
  275. }
  276. else if (stringArray[i] == "+")
  277. {
  278. if (postStack->getTop() == "-" || postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "+")
  279. {
  280. postFixStoQ(operatorDNode, postTNode);
  281. }
  282. else
  283. {
  284. postStack->push(postTNode);
  285. pssize++;
  286. }
  287. }
  288. else if (stringArray[i] == "-")
  289. {
  290. if (postStack->getTop() == "+" || postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "+")
  291. {
  292. postFixStoQ(operatorDNode, postTNode);
  293. }
  294. else
  295. {
  296. postStack->push(postTNode);
  297. pssize++;
  298. }
  299. }
  300. else if (stringArray[i] == ")")
  301. {
  302. while (postStack->getTop() != "(") //pop all the values from stack to queue up till the open paranthesis
  303. {
  304. operatorDNode->setData(postStack->getTop());
  305. postStack->pop();
  306. pssize--;
  307. postQueue->addQueue(operatorDNode);
  308. pqsize++;
  309. }
  310. postStack->pop(); //get rid of the "("
  311. pssize--;
  312. }
  313. else if (stringArray[i] == "(")
  314. {
  315. postStack->push(postTNode);
  316. pssize++;
  317. }
  318. operatorDNode = nullptr;
  319. }
  320. postTNode = nullptr;
  321. }
  322. for (int i = 0; i < pssize;) //pop the remaining stack values into the queue
  323. {
  324. Node<std::string> *remainingpop = new Node<std::string>;
  325. remainingpop->setData(postStack->getTop());
  326. pssize--;
  327. postQueue->addQueue(remainingpop);
  328. pqsize++;
  329. postStack->pop();
  330. remainingpop = nullptr;
  331. }
  332. }
  333. void Calculator::postFixStoQ(Node<std::string> *operatorDNode, Node<std::string> *postTNode)
  334. {
  335. operatorDNode->setData(postStack->getTop()); //set dummy node to hold stacks top operator
  336. postStack->pop(); //this might be deleting the data that is being transferred to queue, not the pointer.
  337. pssize--;
  338. postQueue->addQueue(operatorDNode); //add the newly removed operator to queue
  339. pqsize++;
  340. postStack->push(postTNode); //add the new operator to stack
  341. pssize++;
  342. }
  343. 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
  344. {
  345. std::string *QueueHolder = new std::string[pqsize];
  346. for (int i = 0; i < pqsize; i++)
  347. {
  348. std::cout << postQueue->getFirstData();
  349. QueueHolder[i] = postQueue->getFirstData();
  350. 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
  351. }
  352. std::cout << std::endl;
  353. 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
  354. {
  355. Node<std::string> *Queuereset = new Node<std::string>;
  356. Queuereset->setData(QueueHolder[i]);
  357. postQueue->addQueue(Queuereset);
  358. Queuereset = nullptr;
  359. }
  360. /*std::cout << "\nThis is your current Stack: \n";
  361. for (int i = 0; i < pssize; i++)
  362. {
  363. std::cout << postStack->getTop() << std::endl;
  364. postStack->pop(); //this wont't even perform with the current setup, so it is fine.
  365. }*/
  366. }
  367. void Calculator::postFixEvaluation() //need to add a check for when the evaluation is over(i think)
  368. {
  369. int operand1; //these variables will be used to convers from string to int and evaluate the expression
  370. int operand2; //operand1 will serve as both operand1 and the result from the operation performed on both it and 2
  371. std::string soperand1; //soperand1 will serve as the conversion for operand1, as well as the convertion of the result from the expression.
  372. std::string soperand2;
  373. 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.
  374. {
  375. Node<std::string> *postENode = new Node<std::string>;
  376. int currentlenth = postQueue->getFirstData().length();
  377. bool valueIsDigit = false;
  378. char *charrarray = new char[currentlenth];
  379. for (int j = 0; j < currentlenth; j++) //digit check for data i queue
  380. {
  381. charrarray[j] = postQueue->getFirstData()[j];
  382. if (isdigit(charrarray[j]))
  383. valueIsDigit = true;
  384. }
  385. delete[] charrarray;
  386. charrarray = nullptr;
  387. if (valueIsDigit) //moves the integer from the queue into stack prepping it for evaluation.
  388. {
  389. postENode->setData(postQueue->getFirstData());
  390. postQueue->removeFirst();
  391. pqsize--;
  392. postStack->push(postENode);
  393. pssize++;
  394. }
  395. else if (!valueIsDigit)
  396. {
  397. soperand2 = postStack->getTop();
  398. postStack->pop();
  399. pssize--;
  400. soperand1 = postStack->getTop();
  401. postStack->pop();
  402. pssize--;
  403. operand1 = std::stoi(soperand1);
  404. operand2 = std::stoi(soperand2);
  405. if (postQueue->getFirstData() == "+")
  406. {
  407. operand1 = operand1 + operand2;
  408. postQueue->removeFirst();
  409. pqsize--;
  410. }
  411. else if (postQueue->getFirstData() == "-")
  412. {
  413. operand1 = operand1 - operand2;
  414. postQueue->removeFirst();
  415. pqsize--;
  416. }
  417. else if (postQueue->getFirstData() == "*")
  418. {
  419. operand1 = operand1 * operand2;
  420. postQueue->removeFirst();
  421. pqsize--;
  422. }
  423. else if (postQueue->getFirstData() == "/")
  424. {
  425. if (operand2 == 0)
  426. throw - 1;
  427. operand1 = operand1 / operand2;
  428. postQueue->removeFirst();
  429. pqsize--;
  430. }
  431. else if (postQueue->getFirstData() == "%")
  432. {
  433. operand1 = operand1 % operand2;
  434. postQueue->removeFirst();
  435. pqsize--;
  436. }
  437. if (i != pqsize) //check for if the evaluation is on the last expression
  438. {
  439. soperand1 = std::to_string(operand1);
  440. postENode->setData(soperand1);
  441. postStack->push(postENode);
  442. pssize++;
  443. }
  444. }
  445. postENode = nullptr;
  446. }
  447. std::cout << "The result of your math expression using postfix is: " << operand1 << std::endl;
  448. }
  449. void Calculator::preFixTransform()
  450. {
  451. int x = stringArraySize;
  452. int n = 0;
  453. rev = new std::string[stringArraySize];
  454. while (x > 0)
  455. {
  456. rev[n] = stringArray[x - 1];
  457. x--;
  458. n++;
  459. }
  460. for (int i = 0; i < stringArraySize; i++)
  461. {
  462. if (rev[i] == ")")
  463. {
  464. rev[i] = "(";
  465. continue;
  466. }
  467. if (rev[i] == "(")
  468. {
  469. rev[i] = ")";
  470. }
  471. }
  472. internalPreTransform();
  473. x = pqsize;
  474. //showQshowS();
  475. while (x > 0)
  476. {
  477. //std::cout << postQueue->getFirstData();
  478. rev[x-1] = postQueue->getFirstData();
  479. postQueue->removeFirst();
  480. x--;
  481. }
  482. std::cout << std::endl;
  483. x = 0;
  484. while (x < pqsize)
  485. {
  486. Node<std::string> *revN = new Node<std::string>;
  487. revN->setData(rev[x]);
  488. postQueue->addQueue(revN);
  489. x++;
  490. }
  491. }
  492. void Calculator::internalPreTransform()
  493. {
  494. // we have the reversed string in rev
  495. //need to now take the reverse string and turn it into pseudo postfix by performing post fix with a equal or higher precedence
  496. for (int i = 0; i < stringArraySize; i++) //consider changing these declarations to make the function more efficient
  497. {
  498.  
  499. Node<std::string> *postTNode = new Node<std::string>;
  500. bool valueIsDigit = false;
  501. int currentlenth = rev[i].length(); //check if value is a numerical
  502. postTNode->setData(rev[i]); //the node that is going to be pushed has the string value;
  503. char *charrarray = new char[currentlenth];
  504. for (int j = 0; j < currentlenth; j++) //store the contents of stringarray i into a charr aray and use isdigit to check if numerical
  505. {
  506. charrarray[j] = rev[i][j];
  507. if (isdigit(charrarray[j]))
  508. valueIsDigit = true;
  509. }
  510. delete[] charrarray; //check if this is deleteing the value in ths tring when you debug
  511. charrarray = nullptr;
  512. if (valueIsDigit)
  513. {
  514. postQueue->addQueue(postTNode);
  515. pqsize++;
  516. }
  517. /*else if (!valueIsDigit) //temporary for stack and queue tests
  518. {
  519. postStack->push(postTNode);
  520. pssize++;
  521. }*/
  522. else if (!valueIsDigit) //NOW FOR THE ACTUAL ELSE IF //need to add a count to move the remaining values in stack back to queue.
  523. {
  524. Node<std::string> *operatorDNode = new Node <std::string>; //used for moving stack operators to queue;
  525. if (rev[i] == "*") //each if else is a check for the PMMDAS operators.
  526. {
  527.  
  528. postStack->push(postTNode);
  529. pssize++;
  530.  
  531. }
  532. else if (rev[i] == "/")
  533. {
  534.  
  535.  
  536. postStack->push(postTNode);
  537. pssize++;
  538.  
  539. }
  540. else if (rev[i] == "%")
  541. {
  542. postStack->push(postTNode);
  543. pssize++;
  544.  
  545. }
  546. else if (rev[i] == "+")
  547. {
  548. if (postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "*")
  549. {
  550. postFixStoQ(operatorDNode, postTNode);
  551. }
  552. else
  553. {
  554. postStack->push(postTNode);
  555. pssize++;
  556. }
  557. }
  558. else if (rev[i] == "-")
  559. {
  560. if (postStack->getTop() == "/" || postStack->getTop() == "%" || postStack->getTop() == "*")
  561. {
  562. postFixStoQ(operatorDNode, postTNode);
  563. }
  564. else
  565. {
  566. postStack->push(postTNode);
  567. pssize++;
  568. }
  569.  
  570. }
  571. else if (rev[i] == ")")
  572. {
  573. while (postStack->getTop() != "(") //pop all the values from stack to queue up till the open paranthesis
  574. {
  575. Node<std::string> *operatorSNode = new Node <std::string>;
  576. operatorSNode->setData(postStack->getTop());
  577. postStack->pop();
  578. pssize--;
  579. postQueue->addQueue(operatorSNode);
  580. pqsize++;
  581. operatorSNode = nullptr;
  582. }
  583. postStack->pop(); //get rid of the "("
  584. pssize--;
  585. }
  586. else if (rev[i] == "(")
  587. {
  588. postStack->push(postTNode);
  589. pssize++;
  590. }
  591. operatorDNode = nullptr;
  592. }
  593. postTNode = nullptr;
  594. }
  595. for (int i = 0; i < pssize;) //pop the remaining stack values into the queue
  596. {
  597. Node<std::string> *remainingpop = new Node<std::string>;
  598. remainingpop->setData(postStack->getTop());
  599. pssize--;
  600. postQueue->addQueue(remainingpop);
  601. pqsize++;
  602. postStack->pop();
  603. remainingpop = nullptr;
  604. }
  605. }
  606. void Calculator::preFixEval()
  607. {
  608. int operand1=0; //these variables will be used to convers from string to int and evaluate the expression
  609. int operand2=0; //operand1 will serve as both operand1 and the result from the operation performed on both it and 2
  610. std::string soperand1=""; //soperand1 will serve as the conversion for operand1, as well as the convertion of the result from the expression.
  611. std::string soperand2="";
  612. int digC = 0;
  613.  
  614. //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
  615. // 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
  616. for (int i = 0; i < pqsize;)
  617. {
  618. Node<std::string> *postENode = new Node<std::string>;
  619. int currentlenth = postQueue->getFirstData().length();
  620. bool valueIsDigit = false;
  621. char *charrarray = new char[currentlenth];
  622. if (pqsize > 0)
  623. {
  624.  
  625.  
  626. for (int j = 0; j < currentlenth; j++) //digit check for data i queue
  627. {
  628. charrarray[j] = postQueue->getFirstData()[j];
  629. if (isdigit(charrarray[j]))
  630. valueIsDigit = true;
  631. }
  632. if (valueIsDigit == true)
  633. digC++;
  634. else
  635. digC = 0;
  636.  
  637. postENode->setData(postQueue->getFirstData());
  638. postStack->push(postENode);
  639. pssize++;
  640. postQueue->removeFirst();
  641. pqsize--;
  642. }
  643.  
  644.  
  645. if (digC == 2)
  646. {
  647. digC--;
  648. soperand1 = postStack->getTop();
  649. postStack->pop();
  650. pssize--;
  651. soperand2 = postStack->getTop();
  652. postStack->pop();
  653. pssize--;
  654. operand1 = std::stoi(soperand1);
  655. operand2 = std::stoi(soperand2);
  656. std::string op = postStack->getTop();
  657. postStack->pop();
  658. pssize--;
  659. if (op == "+")
  660. {
  661. operand1 = operand2 + operand1;
  662. soperand1 = std::to_string(operand1);
  663. postENode->setData(soperand1);
  664. postStack->push(postENode);
  665. pssize++;
  666. }
  667. if (op == "-")
  668. {
  669. operand1 = operand2 - operand1;
  670. soperand1 = std::to_string(operand1);
  671. postENode->setData(soperand1);
  672. postStack->push(postENode);
  673. pssize++;
  674. }
  675. if (op == "/")
  676. {
  677. operand1 = operand2 / operand1;
  678. soperand1 = std::to_string(operand1);
  679. postENode->setData(soperand1);
  680. postStack->push(postENode);
  681. pssize++;
  682. }
  683. if (op == "%")
  684. {
  685. operand1 = operand2 % operand1;
  686. soperand1 = std::to_string(operand1);
  687. postENode->setData(soperand1);
  688. postStack->push(postENode);
  689. pssize++;
  690. }
  691. if (op == "*")
  692. {
  693. operand1 = operand2 * operand1;
  694. soperand1 = std::to_string(operand1);
  695. postENode->setData(soperand1);
  696. postStack->push(postENode);
  697. pssize++;
  698. }
  699. }
  700. postENode = nullptr;
  701. }
  702. std::cout <<std::endl<< "the result of the evaluation for prefix is: " << soperand1 << std::endl;
  703. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement