Evaluating a string as a mathematical expression.

nims11

BIOS Terminator
here is what i want to achieve using C++
1.the user inputs a mathematical expression(like 3^2 + sin(1))
2.my program displays the result.

this seems simple but is actually very complex :???: as C++ doesnt have any feature like the eval() function in javascript.

after thinking a lot and coding, here is what i achieved -:
1. the user inputs the mathematical function in postfix form with each element separated with a space.
eg. 3^2 + sin(1) is written as 3 2 ^ 1 sin +

2. the program simulates a virtual stack and evaluate the result.

the Drawback-
1. user has to convert every mathematical to postfix form.
2. its a bit slow(noticeable in consecutive executions).

Please suggest how to process an infix(normal) expression and what you would have done to achieve it...:stirpot:
 

Liverpool_fan

Sami Hyypiä, LFC legend
First of all, post the code. Pastebin it or post it here with
PHP:
 tags.
You can use the algorithm to convert Infix to Postfix which can be evaluated by the compiler. Then obviously you can use the Postfix evaluator you wrote to process it.
You only need to split the operands/operators from the string, and then process them.  

Secondly usage of eval is not recommended in any language for processing user input. Eval of user input IS [URL="*stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/198031#198031"]EVIL[/URL]

And the entries here will help you for sure, but first write your own code.
[URL="*ubuntu-ky.ubuntuforums.org/showthread.php?t=1441700"]*ubuntu-ky.ubuntuforums.org/showthread.php?t=1441700[/URL]
 
OP
nims11

nims11

BIOS Terminator
here is my code. i compile it with mingw(DEV-cpp). any suggestions?
sorry my coding might not be very neat

Code:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
float tmpstk[100];
int toNum(string nstr) //converts string to integer
{
    int nod=nstr.length();
    int digits[nod];
for(int i=0;i<nod;i++)
    {
            switch(nstr.at(i))
            {
                           case '0':
                                digits[i]=0;
                                break;
                           case '1':
                                digits[i]=1;
                                break;
                           case '2':
                                digits[i]=2;
                                break;
                           case '3':
                                digits[i]=3;
                                break;
                           case '4':
                                digits[i]=4;
                                break;
                           case '5':
                                digits[i]=5;
                                break;
                           case '6':
                                digits[i]=6;
                                break;
                           case '7':
                                digits[i]=7;
                                break;
                           case '8':
                                digits[i]=8;
                                break;
                           case '9':
                                digits[i]=9;
                                break;
            }
}
int n=0;
for(int i=0;i<nod;i++)
{
        int tmp=(int)nod-1-i;
n += digits[i] * pow(10,tmp);
}
return n;
}

void shiftright(int noOperand) //shifts all the elements of tmpstk one place right
{
     for(int i=noOperand-1;i>0;i--)
     {
             tmpstk[i]=tmpstk[i-1];
     }
}
void shiftleft(int noOperand) //shifts all the elements of tmpstk one place right
{
     for(int i=1;i<noOperand;i++)
     {
             tmpstk[i-1]=tmpstk[i];
     }
}

int main()
{
   string sinF="sin", cosF="cos", tanF="tan", cotF="cot", secF="sec", cosecF="cosec";
    int noOfElts,i,noOperator=0,noOperand=0;
    for(i=0;i<100;i++) //initializing all the elements of tmpstk to 0
    tmpstk[i]=0;
    string stack[100];
    cout<<"***********POSTFIX EVALUATOR (BY NIMS13)***********"<<endl<<endl;
    cout<<"Enter Number Of elements in the Postfix Expression -: ";
    cin>>noOfElts;
    cout<<"Enter Valid Postfix Expression elements separated by space -\n";
    for(i=0;i<noOfElts;i++)
    cin>>stack[i];
    for(i=0;i<noOfElts;i++)
    {
       switch(stack[i].at(0))
       {
        case '+':
             case '-':
                     case '*':
                          case '/':
                          case 's':
                          case 'c':
                          case 't':
        break;
        default: noOperand++;
       }
}
    for(i=0;i<noOfElts;i++)
    {
                          int isoperator=0;
       switch(stack[i].at(0))
       {
                             case '^':
                                  isoperator=1;
                                  noOperator++;
                                  tmpstk[noOperand-2]=pow(tmpstk[noOperand-2],tmpstk[noOperand-1]);
                                  tmpstk[noOperand-1]=0;
                                  shiftright(noOperand);
                                  break;
                             case '+':
                                  isoperator=1;
                                  noOperator++;
                                  tmpstk[noOperand-2]=tmpstk[noOperand-2]+tmpstk[noOperand-1];
                                  tmpstk[noOperand-1]=0;
                                  shiftright(noOperand);
                                  break;
                              case '-':
                                  isoperator=1;
                                  noOperator++;
                                  tmpstk[noOperand-2]=tmpstk[noOperand-2]-tmpstk[noOperand-1];
                                  tmpstk[noOperand-1]=0;
                                  shiftright(noOperand);
                                  break;
                              case '*':
                                  isoperator=1;
                                  noOperator++;
                                  tmpstk[noOperand-2]=tmpstk[noOperand-2]*tmpstk[noOperand-1];
                                  tmpstk[noOperand-1]=0;
                                  shiftright(noOperand);
                                  break;
                              case '/':
                                  isoperator=1;
                                  noOperator++;
                                  tmpstk[noOperand-2]=tmpstk[noOperand-2]/tmpstk[noOperand-1];
                                  tmpstk[noOperand-1]=0;
                                  shiftright(noOperand);
                                  break;
                              case 's':
                                   isoperator=1;
                                   if(sinF==stack[i])
                                   tmpstk[noOperand-1] = sin(tmpstk[noOperand-1]);
                                   else if(secF==stack[i])
                                   tmpstk[noOperand-1] = 1/cos(tmpstk[noOperand-1]);
                                   break;
                              case 'c':
                                   isoperator=1;
                                   if(cosF==stack[i])
                                   tmpstk[noOperand-1] = cos(tmpstk[noOperand-1]);
                                   else if(cosecF==stack[i])
                                   tmpstk[noOperand-1] = 1/sin(tmpstk[noOperand-1]);
                                   else if(cotF==stack[i])
                                   tmpstk[noOperand-1] = 1/tan(tmpstk[noOperand-1]);
                                   break;
                              case 't':
                                   isoperator=1;
                                   if(tanF==stack[i])
                                   tmpstk[noOperand-1] = tan(tmpstk[noOperand-1]);
                                   break;
                                  
       }
       if(!isoperator)
       {
                      shiftleft(noOperand);
                      tmpstk[noOperand-1]=toNum(stack[i]);
       }
       for(int i=0;i<noOperand;i++)
       {
               cout<<tmpstk[i]<<" ";
       }
       cout<<endl;
    }
    cout<<tmpstk[noOperand-1];
    cin>>i;
    return 0;
}
 

Liverpool_fan

Sami Hyypiä, LFC legend
Had a quick look into your program.
Begin with a simple program really which could +,-,*,/. Other features can be added later.
In the function toNum the switch case is not needed you can simply do:
digits = int(nstr.at(i)) - int('0');
Also try to modularize the program, get as much code out of main() into a function.
Another thing you should do is to throw away the global variable, tmpstk and convert the string into number in a single function.
I don't see a seperate stack data structure in your program too. You are recommended to use a seperate stack for keeping the operands.
 
OP
nims11

nims11

BIOS Terminator
thanx for the advice, i will now look forward to your suggestions and seek ur suggestions in future.

thanx again
 
Top Bottom