Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6040237
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T06:29:05+00:00 2026-05-23T06:29:05+00:00

I inadvertently let my students overconstrain a shared class used to solve the following

  • 0

I inadvertently let my students overconstrain a shared class used to solve the following problem. I realized it might be a problem denizens of this site might enjoy.

The first team/function, getNodes, takes a string representing a prefix expression using signed integers and the four operations +, -, *, and / and produces the corresponding null terminated linked list of tokens, using the class Node, with tokens linked through the “right” pointer.

The second team/function, getTree, takes a similar string, passes it to getNodes, and relinks the resultant nodes to be an expression tree.

The third team/function, evaluate, takes a similar string, passes it to getTree, and evaluates the resultant expression tree to form an answer.

The over-constrained exptree.h follows. The problem has to be solved by writing just the three functions defined above, no additional functions.

#ifndef EXPTREE_H_
#define EXPTREE_H_

using namespace std;

enum Ops{ADD, SUB, MUL, DIV, NUM};

class Node {
   private:
        int num;
        Ops op;
        Node *left, *right;

    public:
        friend Node *getNodes(string d);
        friend Node *getTree(string d);
        friend int evaluate (string);
    };

int evaluate(string d);
Node *getNodes(string d);
Node *getTree(string d);
#endif

The only libraries that can be used are these

#include <iostream>
#include <vector>
#include <string>
#include "exptree.h" 

For those of you worried about my students, I will be pointing out today how just a couple of more well placed functions would allow this problem to be easily solved. I know the expression tree can code rational numbers and not just integers. I’ll be pointing that out today as well.

Here is the driver program I gave them based on their specs.

#include <iostream>
#include <string>
#include "exptree.h"
using namespace std;
void test(string s, int target) {
    int result = evaluate(s);
    if (result == target)
        cout << s << " correctly evaluates to " << target << endl;
    else
        cout << s << "(" << result 
             << ") incorrectly evaluates to " << target << endl;
}
int main() {
    test("42", 42);
    test("* - / 4 2 1 42", 42);
    test("* - / -4 +2 -1 2", -2);
    test("* - / -4 +2 -1 2            ", -2);
    test("* 9 6", 54);
    return 0;
}

Can you write the three functions in as elegant a fashion as possible to solve this nightmarish problem?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T06:29:05+00:00Added an answer on May 23, 2026 at 6:29 am

    For what its worth, here is the solution I coded up just before I posted the question

    #include <iostream>
    #include <vector>
    #include "exptree.h"
    using namespace std;
    
    Node *getNodes(string s) {
        const int MAXINT =(int)(((unsigned int)-1) >> 1), MININT = -MAXINT -1;
        Node *list;
        int sign, num;
    
        s += " ";                                                   // this simplifies a lot of logic, allows trailing white space to always close off an integer
        list = (Node *) (num = sign = 0);
        for (int i=0; i<s.size(); ++i) {
            char c = s[i];                                          // more efficient and cleaner reference to the current character under scrutiny
            if (isdigit(c)) {
                if (sign == 0) sign = 1;                            // if sign not set, then set it. A blank with a sign==0 now signifies a blank that can be skipped
                num = 10*num + c - '0';
            } else if (((c=='+') || (c=='-')) && isdigit(s[i+1])) { // another advantage of adding blank to string above so don't need a special case
                sign = (c=='+') ? 1 : -1;
            } else if ( !isspace(c) &&  (c != '+')  && (c != '-')  && (c != '*')  && (c != '/')) {
                cout << "unexpected character " << c << endl;
                exit(1);
            } else if  (!isspace(c) || (sign != 0)) {                                                       // have enough info to create next Node
                list->left = (list == 0) ? (list = new Node) : (list->left->right = new Node);              // make sure left pointer of first Node points to last Node
                list->left->right = 0;                                                                      // make sure list is still null terminated
                list->left->op = (c=='+' ? ADD : (c=='-' ? SUB : (c=='*' ? MUL : (c=='/' ? DIV : NUM))));   // choose right enumerated type
                list->left->num = (list->left->op==NUM) ? sign*num : MININT;                                // if interior node mark number for evaluate function
                num = sign = 0;                                                                             // prepare for next Node
            }
        }
        return list;
    }
    
    Node *getTree(string s) {
        Node *nodes = getNodes(s), *tree=0, *root, *node;
        vector<Node *> stack;
    
        if (nodes == 0) return tree;
        root = tree = nodes;
        nodes = nodes->right;
        for (node=nodes; node != 0; node=nodes) {
            nodes = nodes->right;
            if (root->op != NUM) {              // push interior operator Node on stack til time to point to its right tree
                stack.push_back(root);
                root = (root->left = node);     // set interior operator Node's left tree and prepare to process that left tree
            } else {                            
                root->left = root->right = 0;   // got a leaf number Node so finish it off
                if (stack.size() == 0) break;
                root = stack.back();            // now pop operator Node off the stack
                stack.pop_back();
                root = (root->right = node);    // set its left tree and prepare to process that left tree
            }
        }
        if ((stack.size() != 0) || (nodes != 0)) {
            cout << "prefix expression has missing or extra terms" << endl;
            exit(1);
        }
        return tree;
    }
    
    int evaluate(string s) {
        // MININT is reserved value signifying operator waiting for a left side value, low inpact since at edge of representable integers
        const int MAXINT =(int)(((unsigned int)-1) >> 1), MININT = -MAXINT -1;
        Node *tree = getTree(s);
        vector<Node *> stack;
        int v = 0;                              // this is value of a leaf node (a number) or the result of evaluating an interior node
        if (tree == 0) return v;
        do {
            v = tree->num;
            if (tree->op != NUM) {
                stack.push_back(tree);
                tree = tree->left;              // prepare to process the left subtree      
            } else while (stack.size() != 0) {  // this while loop zooms us up the right side as far as we can go (till we come up left side or are done)
                delete tree;                    // done with leaf node or an interior node we just finished evaluating
                tree = stack.back();            // get last interior node from stack
                if (tree->num == MININT) {      // means returning up left side of node, so save result for later
                    tree->num = v;
                    tree = tree->right;         // prepare to evaluate the right subtree
                    break;                      // leave the "else while" for the outer "do while" which handles evaluating an expression tree
                } else {                        // coming up right side of an interior node (time to calculate)
                    stack.pop_back();           // all done with interior node
                    v = tree->op==ADD ? tree->num+v : (tree->op==SUB ? tree->num-v : (tree->op==MUL ? tree->num*v : tree->num/v)) ;
                }
            }
        } while (stack.size() != 0);
        return v;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got this class, let's call it Refund (because that's what it's called). I
I inadvertently posted revisions to this previous post when I meant to update subsequent
I inadvertently marked all the messages in my inbox as read with this python
I've fixed this issue before (inadvertently) and I'm coming across this again. Hopefully someone
I inadvertently ended up with these values being used in an XCode build: IPHONEOS_DEPLOYMENT_TARGET
I'm migrating a VSS repository to SVN and inadvertently included all of the _vti_cnf,
In one of my builds for an iPhone app, I had inadvertently created a
I have a Sitecore/ASP.NET projects that I'm developing. Today at some point I inadvertently
Possible Duplicate: Inadvertent use of = instead of == C++ compilers let you know
I have inadvertently svn-deleted a file with svn del --targets del.txt . Now, I'd

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.