Binary Expression Tree

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Binary Expression Tree

 
0
  #1
Apr 20th, 2009
Hey everyone,

I'm trying to make it so that my ^ operator is right justified within this binary expression tree.

For example, 2^3^4 should be evaluated as 2^(3^4). So I should get 2^81, instead of the usual 2^12.

Here is the code I have so far. Everything works, except the ^ is still left associative. I know this is a hard one, so if you don't have time to help me out it's no problem.

Thanks!

  1. // btreeEx.h
  2.  
  3. // queue.h
  4. // linked list implementation of Queue ADT
  5. #include <cstddef> // for NULL
  6. #include <new> // for bad_alloc exception
  7. #include <iostream>
  8. using namespace std;
  9.  
  10. template <class T>
  11. struct Node; // forward reference, Node defined below
  12.  
  13. template<class T>
  14. class Queue
  15. {
  16. private:
  17. Node<T> * front; // pointer to front of Queue
  18. Node<T> * rear; // pointer to rear of Queue
  19. int length; // logical length of Queue
  20. public:
  21. Queue(); // default c-tor
  22. ~Queue(); // d-tor
  23.  
  24. void makeMT(); // make Queue logically empty
  25. // Post: front and rear have been reset to the empty state
  26. bool isMT() const; // test for Queue being empty
  27. // returns true if the queue is empty; false otherwise
  28. bool isFull() const; // test for Queue being full
  29. // Returns true if the queue is full; false otherwise
  30. void enqueue(T item); // enqueue an item
  31. // Post: parameter item is at the rear of the queue
  32. void dequeue(T & item); // dequeue an item
  33. // Post: front of queue has been removed and a copy returned in item
  34. int getLength() const; // returns length queue
  35. // Post: Queue is unchanged
  36. void replaceItem(T old, T nu); // replaces all occurrences of old with nu
  37. // Pre: queue has been initialized
  38. // Post: each occurrence of old in queue has been changed to nu
  39. void prntQueue() const; // displays contents of queue
  40. // Pre: queue has been initialized
  41. // Post: contents of queue have been printed
  42.  
  43. }; // end Queue
  44.  
  45. // implementations
  46. /*template <class T>
  47. struct Node
  48. {
  49.   T info;
  50.   Node<T> * next;
  51. }; */
  52.  
  53. template<class T> // default class c-tor
  54. Queue<T>::Queue() : front(NULL), rear(NULL), length(0)
  55. { }
  56.  
  57. template<class T> // d-tor
  58. Queue<T>::~Queue()
  59. {
  60. makeMT();
  61. }
  62.  
  63. template<class T>
  64. void Queue<T>::makeMT()
  65. {
  66. Node <T> * temp;
  67.  
  68. while ( front != NULL ) {
  69. temp = front;
  70. front = front->next;
  71. delete temp;
  72. } // endwhile
  73. rear = NULL;
  74. length = 0;
  75. return;
  76. } // end makeMT()
  77.  
  78. template<class T>
  79. bool Queue<T>::isMT() const
  80. {
  81. return ( length == 0 ); // alternative is to return ( front == NULL );
  82. } // end isMT()
  83.  
  84. template<class T>
  85. bool Queue<T>::isFull() const
  86. {
  87. Node<T> * location;
  88. try {
  89. location = new Node<T>;
  90. delete location;
  91. return false;
  92. } // endtry
  93. catch(bad_alloc exception)
  94. {
  95. return true;
  96. } // endcatch
  97. } // end isFull()
  98.  
  99. template<class T>
  100. void Queue<T>::enqueue(T item)
  101. {
  102. Node<T> * newNode;
  103.  
  104. newNode = new Node<T>;
  105. newNode->info = item;
  106. newNode->next = NULL;
  107. if ( rear == NULL )
  108. front = newNode;
  109. else
  110. rear->next = newNode;
  111. rear = newNode;
  112. length++;
  113. } // end enqueue()
  114.  
  115. template<class T>
  116. void Queue<T>::dequeue(T & item)
  117. {
  118. Node<T> * temp;
  119.  
  120. temp = front;
  121. item = front->info;
  122. front = front->next;
  123. if ( front == NULL )
  124. rear = NULL;
  125. delete temp;
  126. length--;
  127. return;
  128. } // end dequeue()
  129.  
  130. template<class T>
  131. int Queue<T>::getLength() const
  132. {
  133. return length;
  134. } // end getLength()
  135.  
  136. template<class T>
  137. void Queue<T>::replaceItem(T old, T nu)
  138. {
  139. Node<T> * location = front;
  140.  
  141. while ( location != NULL ) {
  142. if ( location->info == old )
  143. location->info = nu;
  144. location = location->next;
  145. } // endwhile
  146. } // end replaceItem()
  147.  
  148. template<class T>
  149. void Queue<T>::prntQueue() const
  150. {
  151. Node<T> * location = front;
  152.  
  153. cout << "\n Printing contents of queue:\n";
  154. while ( location != NULL ) {
  155. cout << "\t" << location->info;
  156. location = location->next;
  157. } // endwhile
  158. cout << endl;
  159. return;
  160. } // end prntQueue()
  161. // end Queue implementations
  162.  
  163.  
  164. // stkxcptn.h - header file for PopOnMTStack and PushOnFullStack exception class
  165.  
  166. //#include <iostream>
  167. //using namespace std;
  168.  
  169. class PopOnMTStack
  170. {
  171. private :
  172. string msg;
  173.  
  174. public :
  175. PopOnMTStack() // default c-tor
  176. {
  177. msg = string("\n Stack underflow - operation aborted");
  178. }
  179. const string message() const
  180. {
  181. return msg;
  182. }
  183. }; // end PopOnMTStack
  184.  
  185. class PushOnFullStack
  186. {
  187. private :
  188. string msg;
  189.  
  190. public :
  191. PushOnFullStack() // default c-tor
  192. {
  193. msg = string("\n Stack overflow - operation aborted");
  194. }
  195. const string message() const
  196. {
  197. return msg;
  198. }
  199. }; // end PopOnMTStack
  200.  
  201. // stack.h
  202. // header file for Stack ADT using a templated linked list
  203. //#pragma once
  204.  
  205. //#include "stkxcptn.h"
  206. template <class T>
  207. struct Node; // forward reference - struct Node is defined below
  208.  
  209. template<class T>
  210. class Stack
  211. {
  212. private:
  213. Node<T> * top;
  214.  
  215. public:
  216. Stack();
  217. ~Stack();
  218.  
  219. void makeMT();
  220. // Function: sets stack to an empty state
  221. // Post: Stack is empty
  222.  
  223. bool isFull() const;
  224. // Function: determines whether the stack is full
  225. // Pre: Stack has been initialized
  226. // Post: Function value = false (assuming new succeeds)
  227.  
  228. bool isMT() const;
  229. // Function: determines whether the stack is empty
  230. // Pre: Stack has been initialized
  231. // Post: Function value = (stack is empty)
  232.  
  233. void push(T item);
  234. // Function: adds item to the top of the stack
  235. // Pre: Stack has been initialized
  236. // Post: If (stack is full), PushOnFullStack exception is thrown;
  237. // otherwise, item is at the top of the stack
  238.  
  239. void pop(T & item);
  240. // Function: removes top item from the stack and returns it in item
  241. // Pre: Stack has been initialized
  242. // Post: If (stack is MT), PopOnMTStack exception is thrown;
  243. // otherwise, top element has been removed from stack
  244.  
  245. void prntStack() const;
  246. // Function: displays contents of the stack
  247. // Pre: Stack has been initialized
  248. // Post: Stack is walked and members printed
  249. }; // end Stack
  250.  
  251. // Stack ADT - implementation using a templated linked list
  252.  
  253. //#include <cstddef>
  254. //#include <new>
  255. template <class T>
  256. struct Node
  257. {
  258. T info; // Node data of type T
  259. Node * next; // link to next Node
  260.  
  261. Node<T>() : info(0), next(NULL) // default c-tor for Node
  262. { }
  263.  
  264. Node<T>( const T & e, Node * nx = NULL ) // parameterized c-tor for Node
  265. : info(e), next(nx)
  266. { }
  267. }; // end Node
  268.  
  269. template<class T>
  270. Stack<T>::Stack() : top(NULL)
  271. { }
  272.  
  273. template <class T>
  274. Stack<T>::~Stack()
  275. {
  276. Node<T> * temp;
  277.  
  278. while ( top != NULL ) {
  279. temp = top;
  280. top = top->next;
  281. delete temp;
  282. } // endwhile
  283. } // end ~Stack()
  284.  
  285. template<class T>
  286. void Stack<T>::pop(T & item)
  287. {
  288. if ( isMT() )
  289. throw PopOnMTStack();
  290. else {
  291. Node<T> * temp;
  292. temp = top;
  293. item = top->info;
  294. top = top->next;
  295. delete temp;
  296. } // endif
  297. } // end pop()
  298.  
  299. template<class T>
  300. bool Stack<T>::isFull() const
  301. {
  302. Node<T> * location;
  303. try {
  304. location = new Node<T>;
  305. delete location;
  306. return false;
  307. } // endtry
  308. catch(bad_alloc exception)
  309. {
  310. return true;
  311. } // endcatch
  312. } // end isFull()
  313.  
  314. template <class T>
  315. void Stack<T>::push(T item)
  316. {
  317. if ( isFull() )
  318. throw PushOnFullStack();
  319. else {
  320. Node<T> * ptr;
  321. ptr = new Node<T>(item);
  322. ptr->next = top;
  323. top = ptr;
  324. } // endif
  325. } // end push()
  326.  
  327. template <class T>
  328. void Stack<T>::makeMT()
  329. {
  330. Node<T> * temp;
  331.  
  332. while ( top != NULL ) {
  333. temp = top;
  334. top = top->next;
  335. delete temp;
  336. } // endwhile
  337. } // end makeMT()
  338.  
  339. template <class T>
  340. bool Stack<T>::isMT() const
  341. {
  342. return ( top == NULL );
  343. } // end isMT()
  344.  
  345. template <class T>
  346. void Stack<T>::prntStack() const
  347. {
  348. Node<T> * ptr = top;
  349. cout << "\n Walking the stack: "
  350. while ( ptr != NULL ) {
  351. cout << "\t" << ptr->info;
  352. ptr = ptr->next;
  353. } // endwhile
  354. return;
  355. } // end prntStack()
  356.  
  357.  
  358. // file tree.h contains the definition of class Tree
  359. // class is templated
  360.  
  361. #include <fstream>
  362. #include <cmath> // for pow()
  363. #include <string> // Assign #19
  364. const char LAST_SYMBOL = '=';
  365. enum OpType { OPERATOR, OPERAND };
  366. struct InfoNode
  367. {
  368. OpType whichType; // type field
  369. union // anonymous union
  370. {
  371. char operation;
  372. double operand; // Assign #19 - change type from int to double
  373. };
  374. };
  375. typedef InfoNode T;
  376. template <class T>
  377. struct TreeNode;
  378. // Assumption: T is a type for which the operators "<"
  379. // and "==" are defined - either an appropriate built-in type or
  380. // a class that overloads these operators
  381.  
  382. enum OrderType { PRE_ORDER, IN_ORDER, POST_ORDER };
  383.  
  384. template <class T>
  385. class Tree
  386. {
  387. private:
  388. TreeNode<T> * root;
  389. // The following queues are used for traversals
  390. Queue<T> preQue;
  391. Queue<T> inQue;
  392. Queue<T> postQue;
  393. public:
  394. Tree(); // constructor
  395. ~Tree(); // destructor
  396. Tree(const Tree<T> & oTree);
  397. // copy constructor
  398. void operator=(const Tree<T> & oTree);
  399. // Overloads the assignment operator
  400. void makeMT();
  401. // Function: Initializes tree to the empty state
  402. // Post: Tree is empty
  403. bool isMT() const;
  404. // Function: Determines whether the tree is empty
  405. // Post: Function value = (tree is empty)
  406. bool isFull() const;
  407. // Function: Determines whether the tree is full
  408. // Post: Function value = (tree is full)
  409. int numberOfNodes() const;
  410. // Function: Determines the number of elements in the tree
  411. // Post: Function value = number of elements in the tree
  412. void retrieveItem(T & item, bool & found);
  413. // Function: Retrieves item whose key matches item's key (if present)
  414. // Pre: Key of item has been initialized
  415. // Post: If there is an item someItem whose key matches item's
  416. // key, then found is true and item is a copy of someItem;
  417. // otherwise found is false and item is unchanged
  418. // The tree is unchanged
  419. void insertItem(T item);
  420. // Function: Adds item to the tree
  421. // Pre: Tree is not full; item is not in the tree
  422. // Post: item is in the tree
  423. // Binary search property is maintained
  424. void removeItem(T item);
  425. // Function: Deletes the item whose key matches item's key
  426. // Pre: Key of item has been initialized
  427. // One and only one item in the tree has a key matching
  428. // item's key
  429. // Post: No element in tree has key matching item's key
  430. void resetTree(OrderType order);
  431. // Function: Initializes current position for an iteration
  432. // through the tree in order specified
  433. // Post: Current position is prior to root of the tree
  434. void getNextItem (T & item, OrderType order, bool & fini);
  435. // Function: Gets the next element in the tree in the order specified
  436. // in order
  437. // Pre: Current position is defined
  438. // Item at current position is not last in the tree
  439. // Post: Current position is one position beyond current position at
  440. // entry to getNextItem()
  441. // fini = (current position is last in tree)
  442. // item is a copy of element at current position
  443. void printTree(std::ofstream & outFile) const;
  444. // Function: Prints the values in the tree in ascending key
  445. // order on outFile
  446. // Pre: outFile has been opened for writing
  447. // Post: Values in the three have been printed in ascending key order
  448. // outFile is still open
  449. template <class T>
  450. friend void buildExprTree(Tree<T> & expr);
  451. template <class T>
  452. friend double eval(Tree<T> & expr);
  453. }; // end Tree
  454.  
  455. //#include "Tree.cpp"
  456.  
  457. // Implementation file for Binary Search Tree;
  458. // recursive insertion and deletion functions
  459.  
  460. template <class T>
  461. struct TreeNode
  462. {
  463. T info;
  464. TreeNode * left;
  465. TreeNode * right;
  466. TreeNode() // default c-tor for TreeNode
  467. { }
  468. };
  469.  
  470. template <class T>
  471. int countNodes(Tree<T> * tree)
  472. { // Post: returns the number of nodes in the tree
  473. if (tree == NULL)
  474. return 0;
  475. else
  476. return countNodes(tree->left) + countNodes(tree->right) + 1;
  477. }
  478.  
  479. template <class T>
  480. int Tree<T>::numberOfNodes() const
  481. { // calls recursive function CountNodes to count nodes in the tree
  482. return countNodes(root);
  483. }
  484.  
  485. // Recursively searches tree for item
  486. // Post: If there is an element someItem whose key matches item's, found
  487. // is true and item is set to a copy of someItem; otherwise found
  488. // is false and item is unchanged
  489. template <class T>
  490. void retrieve(TreeNode<T> * tree, T & item, bool & found)
  491. {
  492. if (tree == NULL)
  493. found = false; // item is not found
  494. else if ( item < tree->info ) // Search left subtree
  495. retrieve(tree->left, item, found); // Search right subtree
  496. else if ( item > tree->info )
  497. retrieve(tree->right, item, found);
  498. else {
  499. item = tree->info; // item is found
  500. found = true;
  501. } // endif
  502. }
  503.  
  504. template <class T>
  505. void Tree<T>::retrieveItem(T& item, bool& found)
  506. { // calls recursive function Retrieve to search the tree for item
  507. retrieve(root, item, found);
  508. }
  509.  
  510. template <class T>
  511. void insert(TreeNode<T> * & tree, T item) // inserts item into tree
  512. { // Post: item is in tree; search property is maintained
  513. if ( tree == NULL ) { // insertion place found
  514. tree = new TreeNode<T>;
  515. tree->right = NULL;
  516. tree->left = NULL;
  517. tree->info = item;
  518. }
  519. else if ( item < tree->info )
  520. insert(tree->left, item); // insert in left subtree
  521. else
  522. insert(tree->right, item); // nsert in right subtree
  523. }
  524.  
  525. template <class T>
  526. void Tree<T>::insertItem(T item)
  527. { // calls recursive function Insert to insert item into tree
  528. insert(root, item);
  529. }
  530.  
  531. template <class T>
  532. // Deletes the node pointed to by tree
  533. // Post: User's data in the node pointed to by tree is no longer in the tree.
  534. // If tree is a leaf node or has only non-NULL child pointer the node
  535. // pointed to by tree is deleted; otherwise, the user's data is replaced
  536. // by its logical predecessor and the predecessor's node is deleted
  537. void removeNode(TreeNode<T> * & tree)
  538. {
  539. T data;
  540. TreeNode<T>* tempPtr;
  541.  
  542. tempPtr = tree;
  543. if ( tree->left == NULL ) {
  544. tree = tree->right;
  545. delete tempPtr;
  546. }
  547. else if ( tree->right == NULL ) {
  548. tree = tree->left;
  549. delete tempPtr;
  550. }
  551. else {
  552. getPredecessor(tree->left, data);
  553. tree->info = data;
  554. remove(tree->left, data); // Delete predecessor node
  555. }
  556. }
  557.  
  558. template <class T>
  559. void remove(TreeNode<T>*& tree, T item)
  560. { // deletes item from tree - Post: item is not in tree
  561. if (item < tree->info )
  562. remove(tree->left, item); // Look in left subtree
  563. else if ( item > tree->info )
  564. remove(tree->right, item); // Look in right subtree
  565. else
  566. removeNode(tree); // Node found; call removeNode
  567. }
  568.  
  569. template <class T>
  570. void Tree<T>::removeItem(T item)
  571. { // calls recursive function remove() to delete item from tree
  572. remove(root, item);
  573. }
  574.  
  575. template<class T>
  576. void getPredecessor(TreeNode<T> * tree, T & data)
  577. { // sets data to the info member of the right-most node in tree
  578. while ( tree->right != NULL )
  579. tree = tree->right;
  580. data = tree->info;
  581. }
  582.  
  583. template <class T>
  584. void Tree<T>::printTree(std::ofstream & outFile) const
  585. { // calls recursive function print() to print items in the tree
  586. print(root, outFile);
  587. }
  588.  
  589. template<class T>
  590. void print(TreeNode<T> * tree, std::ofstream & outFile)
  591. { // prints info member of items in tree in sorted order on outFile
  592. if ( tree != NULL ) {
  593. print(tree->left, outFile); // Print left subtree
  594. outFile << tree->info;
  595. print(tree->right, outFile); // Print right subtree
  596. } // endif
  597. }
  598.  
  599. template <class T>
  600. Tree<T>::Tree()
  601. {
  602. root = NULL;
  603. }
  604.  
  605. template<class T>
  606. void destroy(TreeNode<T> * & tree)
  607. { // Post: tree is empty; nodes have been deallocated
  608. if ( tree != NULL ) {
  609. destroy(tree->left);
  610. destroy(tree->right);
  611. delete tree;
  612. } // endif
  613. }
  614.  
  615. template <class T>
  616. Tree<T>::~Tree()
  617. { // calls recursive function destroy() to destroy the tree
  618. destroy(root);
  619. }
  620.  
  621. template <class T>
  622. void copyTree(TreeNode<T> * & copy, TreeNode<T> * origTree )
  623. { // Post: copy is root of a tree that is a dup of tree pointed to by origTree
  624. if ( origTree == NULL )
  625. copy = NULL;
  626. else {
  627. copy = new TreeNode<T>;
  628. copy->info = origTree->info;
  629. copyTree(copy->left, origTree->left);
  630. copyTree(copy->right, origTree->right);
  631. } // endif
  632. }
  633.  
  634. template <class T>
  635. Tree<T>::Tree(const Tree<T> & origTree)
  636. { // calls recursive function copyTree() to copy origTree into root
  637. copyTree(root, origTree.root);
  638. }
  639.  
  640. template <class T>
  641. void Tree<T>::operator=(const Tree<T> & origTree)
  642. { // calls recursive function CopyTree to copy origTree into root
  643. if ( &origTree == this )
  644. return; // Ignore assigning self to self
  645. destroy(root); // Deallocate existing tree nodes
  646. copyTree(root, origTree.root);
  647. }
  648.  
  649. // function prototypes for auxiliary functions
  650. template <class T>
  651. void buildExprTree(Tree<T> & expr); // builds preorder binary expression tree
  652.  
  653. template <class T>
  654. void preorder(TreeNode<T> *, Queue<T> &); // enqueues tree items in preorder
  655.  
  656. template <class T>
  657. void inorder(TreeNode<T> *, Queue<T> &); // enqueues tree items in inorder
  658.  
  659. template <class T>
  660. void postorder(TreeNode<T> *, Queue<T> &); // enqueues tree items in postorder
  661.  
  662. template <class T>
  663. void Tree<T>::resetTree(OrderType order)
  664. { // calls function to create a queue of the tree elements in specified order
  665. switch ( order ) {
  666. case PRE_ORDER : preorder(root, preQue);
  667. break;
  668. case IN_ORDER : inorder(root, inQue);
  669. break;
  670. case POST_ORDER: postorder(root, postQue);
  671. break;
  672. } // endswitch
  673. }
  674.  
  675. template <class T>
  676. void preorder(TreeNode<T> * tree, Queue<T> & preQue)
  677. { // Post: preQue contains the tree items in preorder
  678. if ( tree != NULL ) {
  679. preQue.enqueue(tree->info);
  680. preorder(tree->left, preQue);
  681. preorder(tree->right, preQue);
  682. } // endif
  683. }
  684.  
  685. template <class T>
  686. void inorder(TreeNode<T>* tree, Queue<T>& inQue)
  687. { // Post: inQue contains the tree items in inorder
  688. if ( tree != NULL ) {
  689. inorder(tree->left, inQue);
  690. inQue.enqueue(tree->info);
  691. inorder(tree->right, inQue);
  692. } // endif
  693. }
  694.  
  695. template <class T>
  696. void postorder(TreeNode<T> * tree, Queue<T> & postQue)
  697. { // Post: postQue contains the tree items in postorder
  698. if ( tree != NULL ) {
  699. postorder(tree->left, postQue);
  700. postorder(tree->right, postQue);
  701. postQue.enqueue(tree->info);
  702. } // endif
  703. }
  704.  
  705. // Returns the next item in the desired order
  706. // Post: For the desired order, item is the next item in the queue
  707. // If item is the last one in the queue, fini is true; otherwise
  708. // fini is false
  709. template <class T>
  710. void Tree<T>::getNextItem(T & item, OrderType order, bool & fini)
  711. {
  712. fini = false;
  713. switch ( order ) {
  714. case PRE_ORDER : preQue.dequeue(item);
  715. if ( preQue.isMT() )
  716. fini = true;
  717. break;
  718. case IN_ORDER : inQue.dequeue(item);
  719. if ( inQue.isMT() )
  720. fini = true;
  721. break;
  722. case POST_ORDER: postQue.dequeue(item);
  723. if ( postQue.isMT() )
  724. fini = true;
  725. break;
  726. } // endswitch
  727. }
  728.  
  729. void parseStr(string s, char & sym, double & d); // Assign #19 - prototype
  730.  
  731. template <class T>
  732. void buildExprTree(Tree<T> & expr)
  733. {
  734. buildTree(expr.root);
  735. }
  736.  
  737. // buildTree.cpp
  738. // buildTree() builds a binary expression tree
  739. // Note: operands are NOT restricted to single digits
  740. void buildTree(TreeNode<T> * & tree)
  741. {
  742. string inStr; // Assign #19
  743. double opnd; // Assign #19
  744.  
  745. enum MoveType { RIGHT, LEFT };
  746. MoveType nextMove = LEFT;
  747.  
  748. TreeNode<T> * nptr = new TreeNode<T>;
  749. TreeNode<T> * last;
  750. char symbol;
  751.  
  752. Stack <TreeNode<T> *> stack;
  753. cin >> symbol;
  754. cout << " operator: " << symbol << endl; // first symbol is operator
  755. nptr->info.whichType = OPERATOR;
  756. nptr->info.operation = symbol;
  757. tree = nptr;
  758. // instead of
  759. // cin >> symbol; // this version uses single-digit operands – we have
  760. cin >> inStr; // Assign #19 - uses type double operands
  761. parseStr(inStr, symbol, opnd); // Assign #19
  762.  
  763. while ( symbol != LAST_SYMBOL ) {
  764. last = nptr;
  765. nptr = new TreeNode<T>;
  766.  
  767. if ( ispunct(symbol) ) {
  768. cout << " operator: " << symbol << endl;
  769. nptr->info.whichType = OPERATOR;
  770. nptr->info.operation = symbol;
  771. }
  772. else {
  773. //cout << " operand: " << symbol << endl;
  774. cout << " operand: " << opnd << endl; // Assign #19
  775. nptr->info.whichType = OPERAND;
  776. //nptr->info.operand = int(symbol - '0');
  777. nptr->info.operand = opnd; // Assign #19
  778. nptr->right = NULL;
  779. nptr->left = NULL;
  780. } // endif
  781.  
  782. switch ( nextMove ) {
  783. case LEFT : last->left = nptr;
  784. stack.push(last);
  785. break;
  786. case RIGHT : stack.pop(last);
  787. last->right = nptr;
  788. break;
  789. } // endswitch
  790.  
  791. if ( nptr->info.whichType == OPERATOR )
  792. nextMove = LEFT;
  793. else
  794. nextMove = RIGHT;
  795. // instead of cin >> symbol;
  796. cin >> inStr; // Assign #19 - uses type double operands
  797. parseStr(inStr, symbol, opnd); // Assign #19
  798. } // endwhile
  799. return;
  800. } // end buildTree()
  801.  
  802. void parseStr(string s, char & sym, double & d) // Assign #19
  803. {
  804. const char * p = s.c_str(); // convert to C-style string
  805. if ( p[0] == '+' || p[0] == '^' || p[0] == '/' || p[0] == '*' ||
  806. p[0] == '-' || p[0] == LAST_SYMBOL ) { // symbol is an operator
  807. sym = p[0];
  808. d = 0.0;
  809. } // endif-thenpart
  810. else { // input is type double operand
  811. d = atof(p); // convert input to type double operand
  812. sym = '1'; // can make symbol any non-operator
  813. } // endif-elsepart
  814. } // end parseStr()
  815.  
  816. template <class T> //int eval(Tree<T> & expr)
  817. double eval(Tree<T> & expr) // Assign #19
  818. {
  819. return eval(expr.root);
  820. }
  821.  
  822. // Pre: ptr is a pointer to a binary expression tree
  823. // Post: Function value = the value of the expression
  824. // represented by the binary tree pointed to by ptr
  825. //int eval(TreeNode<T> * ptr)
  826. double eval(TreeNode<T> * ptr) // Assign #19
  827. { // function to evaluate a binary expression tree
  828. switch ( ptr->info.whichType ) {
  829. case OPERAND : return ptr->info.operand;
  830. case OPERATOR :
  831. switch ( ptr->info.operation ) {
  832.  
  833. case '+' : return ( eval(ptr->left) + eval(ptr->right) );
  834.  
  835. case '-' : return ( eval(ptr->left) - eval(ptr->right) );
  836.  
  837. case '*' : return ( eval(ptr->left) * eval(ptr->right) );
  838.  
  839. case '/' : return ( eval(ptr->left) / eval(ptr->right) );
  840.  
  841. case '^' : return ( pow(eval(ptr->left), eval(ptr->right)) );
  842. } // endswitch
  843. } // endswitch
  844. return 0.0;
  845. } // end eval()
  846.  
  847. //tstexpr.cpp
  848. /* ------------------------------------------------------------------------------
  849.  * program to test binary tree expression evaluation
  850.  * CS 320 - Data Structures
  851.  */
  852.  
  853. #include "btreeEx.h"
  854. void main()
  855. {
  856. Tree<T> e;
  857.  
  858. cout << "\n Use a Binary Tree for Preorder Expression Evaluation\n";
  859. cout << "\n Enter expression terminated by an equal sign, e.g.: - * 6.2 3.1 5.8 =\n";
  860.  
  861. buildExprTree(e);
  862. cout << "\n The value of the expression is " << eval(e);
  863.  
  864. cout << "\n -- Done --\n";
  865. return;
  866. }
Last edited by Duki; Apr 20th, 2009 at 6:12 pm.
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,625
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 715
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Binary Expression Tree

 
0
  #2
Apr 21st, 2009
>For example, 2^3^4 should be evaluated as 2^(3^4).
>So I should get 2^81, instead of the usual 2^12.
Erm, it looks to me like the input is supposed to be prefix rather than infix. If you're getting 2^12 for your result, then I suspect you aren't entering the correct expression. You can test it for yourself:

^ ^ 2 3 4 = 2^12
^ 2 ^ 3 4 = 2^81
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: Binary Expression Tree

 
0
  #3
Apr 23rd, 2009
You're right about the input. However, the input has to stay as ^ ^ 2 3 4. I need a special case maybe, to take care of the double ^?
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,625
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 715
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Binary Expression Tree

 
0
  #4
Apr 24th, 2009
>However, the input has to stay as ^ ^ 2 3 4.
That's stupid. You want to input a a prefix expression but evaluate it differently from the prefix notation rules. Would you be kind enough to explain why you need to do this?
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: Binary Expression Tree

 
0
  #5
Apr 25th, 2009
That's stupid. You want to input a a prefix expression but evaluate it differently from the prefix notation rules. Would you be kind enough to explain why you need to do this?
hahah, no kidding.

This is, I guess, considered to be a programming challenge from my professor. The only thing I could think of would be to add a exception-handling block for when two ^ are found... but I have no clue if even that will work.

Honestly, I don't think anyone in the class has this figured out. I might turn in my assignment without this part included, hoping he'll mark it off. Quite silly, I agree.
Last edited by Duki; Apr 25th, 2009 at 7:59 pm.
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,625
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 715
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Binary Expression Tree

 
1
  #6
Apr 26th, 2009
>Honestly, I don't think anyone in the class has this figured out
I'm not surprised. Assuming you've given me the same requirements your teacher gave you, there's really no way you can solve the problem adequately. Since he changed the rules, you need to know the new rules before you can follow them.

You currently have one case:
  1. ^ ^ 2 3 4 = 2^81
What about the case you've replaced?
  1. ^ 2 ^ 3 4 = ?
What about the infinite recursion you should be able to handle correctly? What are the rules for three operators? Four? Fifty? What if they're not all adjacent? You lack sufficient information.
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 476
Reputation: nucleon has a spectacular aura about nucleon has a spectacular aura about 
Solved Threads: 91
nucleon's Avatar
nucleon nucleon is offline Offline
Posting Pro in Training

Re: Binary Expression Tree

 
0
  #7
Apr 26th, 2009
The whole point of prefix notation is to represent the formula in such a way as to eliminate the complications of precedence and association. To reinstate these complications is sidiotic.

I feel the most likely case here is that you are misunderstanding the assignment. It makes perfect sense to process exponentiation as right-associative; but it does not make sense to reinterpret prefix notation. So perhaps the input is supposed to be infix notation?
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: Binary Expression Tree

 
0
  #8
Apr 26th, 2009
I know the problem sounds a little (understatement maybe) odd.
I understand what you're saying nucleon, and that would seem a lot more logical. However, I'm sure I haven't misunderstood the project.

>Narue
This is probably going to make you flip out. But in the case of input such as: 2 ^ 3 ^ 4, the left associativity should be used. In any case with subsequent ^, right associativity should be used (e.g., ^ ^ 2 3 4).

heheh, ^.^;
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,625
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 715
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Binary Expression Tree

 
0
  #9
Apr 27th, 2009
>But in the case of input such as: 2 ^ 3 ^ 4, the left associativity should be used
>used. In any case with subsequent ^, right associativity should be (e.g., ^ ^ 2 3 4).
Then I'd guess your teacher wants you to use prefix evaluation for the former and postfix evaluation for the latter. When you see adjacent operators, move them behind the correct number of operands:
* = Operand or operator not applicable

* ^ ^ 2 3 4 *

Find adjacent operators:
* ^ ^ 2 3 4 *

Count the operands that apply:
* ^ ^ 2 3 4 *

Move the operators to postfix position:
* 2 3 4 ^ ^ *

Evaluate:
Push 2
Push 3
Push 4
Found ^: Pop 4, 3, Evaluate
Push 81
Found ^, Pop 81, 2, Evaluate
Push 2^81
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 1,169
Reputation: Duki has a spectacular aura about Duki has a spectacular aura about Duki has a spectacular aura about 
Solved Threads: 9
Duki's Avatar
Duki Duki is offline Offline
Veteran Poster

Re: Binary Expression Tree

 
0
  #10
Apr 27th, 2009
Ah, nice. I'll give that a try. Thanks!
It is practically impossible to teach good programming style to students that have had prior exposure to Basic; as potential programmers they are mentally mutilated beyond hope of regeneration.

-Edsger Dijkstra
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC