Thread: Help parsing equation from string array

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    3

    Help parsing equation from string array

    I'd really appreciate it if anyone could help me develop an algorithm to solve equations using PEMDAS from an array of string with each of the terms in it and an array of integers representing each of the operands (including open and close parenthesis).

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User blackcoder41's Avatar
    Join Date
    Jan 2010
    Location
    Philippines
    Posts
    14
    Code:
    // Ex6_09Extended.cpp
    // A program to implement a calculator accepting parentheses
    
    #include <iostream>                   // For stream input/output
    #include <cstdlib>                    // For the exit() function
    #include <cctype>                     // For the isdigit() function
    #include <cstring>                    // For the strcpy() function
    using std::cin;
    using std::cout;
    using std::endl;
    
    void eatspaces(char* str);            // Function to eliminate blanks
    double expr(char* str);               // Function evaluating an expression
    double term(char* str, int& index);   // Function analyzing a term
    double number(char* str, int& index); // Function to recognize a number
    char* extract(char* str, int& index); // Function to extract a substring
    const int MAX = 80;                   // Maximum expression length, 
                                          // including '\0'
    int main()
    {
       char buffer[MAX] = {0};    // Input area for expression to be evaluated
    
       cout << endl
            << "Welcome to your friendly calculator."
            << endl
            << "Enter an expression, or an empty line to quit."
            << endl;
    
       for(;;)
       {
          cin.getline(buffer, sizeof buffer);   // Read an input line
          eatspaces(buffer);                    // Remove blanks from input
    
          if(!buffer[0])                        // Empty line ends calculator
             return 0;
    
          cout << "\t= " << expr(buffer)        // Output value of expression
               << endl << endl;
       }
    }
    
    
    // Function to eliminate spaces from a string
    void eatspaces(char* str)
    {
       int i = 0;                             // 'Copy to' index to string
       int j = 0;                             // 'Copy from' index to string
    
       while((*(str + i) = *(str + j++)) != '\0')  // Loop while character
                                                   // copied is not \0
          if(*(str + i) != ' ')                    // Increment i as long as
             i++;                                  // character is not a space
       return;
    }
    
    // Function to evaluate an arithmetic expression
    double expr(char* str)
    {
      double value = 0.0;                  // Store result here
      int index = 0;                       // Keeps track of current character position
    
      value = term(str, index);            // Get first term
    
      for(;;)                              // Indefinite loop, all exits inside
      {
        switch(*(str + index++))           // Choose action based on current character
        {
          case '\0':                       // We're at the end of the string
             return value;                 // so return what we have got
    
          case '+':                        // + found so add in the
             value += term(str, index);    // next term
             break;
    
          case '-':                        // - found so subtract
             value -= term(str, index);    // the next term
             break;
    
          default:                         // If we reach here the string
             cout << endl                  // is junk
                  << "Arrrgh!*#!! There's an error"
                  << endl;
             exit(1);
        }
      }
    }
    
    // Function to get the value of a term
    double term(char* str, int& index)
    {
      double value = 0.0;                  // Somewhere to accumulate 
                                           // the result
    
      value = number(str, index);          // Get the first number in the term
    
      // Loop as long as we have a good operator
      while((*(str + index) == '*') || (*(str + index) == '/'))
      {
    
        if(*(str + index) == '*')          // If it's multiply,
          value *= number(str, ++index);   // multiply by next number
    
        if(*(str + index) == '/')          // If it's divide,
          value /= number(str, ++index);   // divide by next number
      }
      return value;                        // We've finished, so return what 
                                           // we've got
    }
    
    // Function to recognize a number in a string
    double number(char* str, int& index)
    {
      double value = 0.0;                  // Store the resulting value
    
      if(*(str + index) == '(')           // Start of parentheses
      {
        char* psubstr = 0;               // Pointer for substring
        psubstr = extract(str, ++index); // Extract substring in brackets
        value = expr(psubstr);           // Get the value of the substring
        delete[]psubstr;                 // Clean up the free store
        return value;                    // Return substring value
      }
    
      while(isdigit(*(str + index)))       // Loop accumulating leading digits
        value = 10*value + (*(str + index++) - '0');
    
                                           // Not a digit when we get to here
      if(*(str + index) != '.')            // so check for decimal point
        return value;                      // and if not, return value
    
      double factor = 1.0;                 // Factor for decimal places
      while(isdigit(*(str + (++index))))   // Loop as long as we have digits
      {
        factor *= 0.1;                     // Decrease factor by factor of 10
        value = value + (*(str + index) - '0')*factor;   // Add decimal place
      }
    
      return value;                        // On loop exit we are done
    }
    
    // Function to extract a substring between parentheses 
    // (requires cstring)
    char* extract(char* str, int& index)
    {
      char buffer[MAX];                   // Temporary space for substring
      char* pstr = 0;                     // Pointer to new string for return
      int numL = 0;                       // Count of left parentheses found
      int bufindex = index;               // Save starting value for index
    
      do
      {
        buffer[index - bufindex] = *(str + index);
        switch(buffer[index - bufindex])
        {
          case ')':
            if(numL == 0)
            {
              size_t size = index - bufindex;
              buffer[index - bufindex] = '\0';  // Replace ')' with '\0' 
              ++index;
              pstr = new char[index - bufindex];
              if(!pstr)
              {
                cout << "Memory allocation failed,"
                     << " program terminated.";
                exit(1);
              }
              strcpy_s(pstr, index-bufindex, buffer); // Copy substring to new memory
              return pstr;                 // Return substring in new memory
            }
            else
              numL--;                      // Reduce count of '(' to be matched
              break;
    
          case '(':
            numL++;                        // Increase count of '(' to be 
                                       // matched
            break;
          }
      } while(*(str + index++) != '\0'); // Loop - don't overrun end of string
    
      cout << "Ran off the end of the expression, must be bad input."
           << endl;
      exit(1);
      return pstr;
    }

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    blackcoder41: feanor114 asked for help, not for what could well amount to a solution. If feanor114 had asked for a solution, you still should not have given one, at least not until it is clear that feanor114 had already arrived at a solution, and you wish to demonstrate a better solution.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    @blackcoder41
    Please read the forum rules.
    Spoon-feeding a COMPLETE answer in response to a first post without any OP effort is just an enabling behaviour for help vampires
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  4. Another overloading "<<" problem
    By alphaoide in forum C++ Programming
    Replies: 18
    Last Post: 09-30-2003, 10:32 AM