搜索
熱搜: 活動 交友 discuz
查看: 9189|回復: 0
打印 上一主題 下一主題

[求助] 幫我看看哪裡錯了

[複製鏈接]
跳轉到指定樓層
1#
發表於 2009-5-2 15:52:36 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*  
    A Simple expression evaluator which uses infix to postfix notation
    to evaluate an expression. Still has bugs which need to be fixed!!!
    V.0.2 -> To handle operator anomolies such as:
    -7*-4    and  2*(-5+6)
*/

#include <iostream>
#include <sstream>
#include <string>
#include <stack>
#include <vector>
#include <math.h>
#define PI 3.14159265

using namespace std;
//function declarations
void Convert(const string & Infix, string & Postfix);
bool IsOperand(char ch);
bool TakesPrecedence(char OperatorA, char OperatorB);

/*My functions I've added*/
string Change_me(string);
string Insert_comma(string);
bool Check_valid(string);
double Eval(string[]);
void Next(string);

int main()
{
   
   char Reply;

   do
      {
      string Infix, Postfix; // local to this loop

      cout <<"\n    Enter your expression with No spaces!\n\n";
      cout <<"     e.g. (4+2)*3/2 "<< endl;
      cout <<"    Unknown variables such as 'a' and 'x' are not allowed:\n\n>>";
      cin >> Infix;
      
        if(Check_valid(Infix)==true)
        {

         string temp;
         temp = Change_me(Infix);
         //cout<<temp;
         //cin.get();

         Convert(temp, Postfix);
      
         cout << "The equivalent postfix expression is:" << endl
         <<Insert_comma(Postfix);

         string hold;
         hold = Insert_comma(Postfix);
         
         cout<<"\n\nThe answer is:";
         Next(hold);

         cout << endl << "\nDo another (y/n)? ";
         cin >> Reply;
        }
        else
        {
            cout<<"***Syntax error***\n";
            cout << endl << "Do another (y/n)? ";
            cin >> Reply;
            
        }      
         
      }while (tolower(Reply) == 'y');

   return 0;
}


/* Given:  ch   A character.
   Task:   To determine whether ch represents an operand (here understood
           to be a single letter or digit).
   Return: In the function name: true, if ch is an operand, false otherwise.
*/
bool IsOperand(char ch)
{
   if (((ch >= 'a') && (ch <= 'z')) ||
      ((ch >= 'A') && (ch <= 'Z')) ||
      ((ch >= '0') && (ch <= '9')))
      return true;
   else
      return false;
}


/* Given:  OperatorA    A character representing an operator or parenthesis.
           OperatorB    A character representing an operator or parenthesis.
   Task:   To determine whether OperatorA takes precedence over OperatorB.
   Return: In the function name: true, if OperatorA takes precedence over
           OperatorB.
*/
bool TakesPrecedence(char OperatorA, char OperatorB)
{
   if (OperatorA == '(')
      return false;
   else if (OperatorB == '(')
      return false;
   else if (OperatorB == ')')
      return true;
   else if ((OperatorA == '^') && (OperatorB == '^'))
      return false;
   else if (OperatorA == '^')
      return true;
   else if (OperatorB == '^')
      return false;
   else if ((OperatorA == '*') || (OperatorA == '/'))
      return true;
   else if ((OperatorB == '*') || (OperatorB == '/'))
      return false;
   else
      return true;
      
}

/* Given:  Infix    A string representing an infix expression (no spaces).
   Task:   To find the postfix equivalent of this expression.
   Return: Postfix  A string holding this postfix equivalent.
*/
void Convert(const string & Infix, string & Postfix)
{
   stack<char> OperatorStack;
   char TopSymbol, Symbol;
   int k;

   for (k = 0; k < Infix.size(); k++)
      {
      Symbol = Infix[k];
      if (IsOperand(Symbol))
         Postfix = Postfix + Symbol;
      else
         {
         while ((! OperatorStack.empty()) &&
            (TakesPrecedence(OperatorStack.top(), Symbol)))
            {
            TopSymbol = OperatorStack.top();
            OperatorStack.pop();
            Postfix = Postfix + TopSymbol;
            }
         if ((! OperatorStack.empty()) && (Symbol == ')'))
            OperatorStack.pop();   // discard matching (
         else
            OperatorStack.push(Symbol);
         }
      }

   while (! OperatorStack.empty())
      {
      TopSymbol = OperatorStack.top();
      OperatorStack.pop();
      Postfix = Postfix + TopSymbol;
      }
}
/*---------------------------------------------
  My function needed to tokenise the expression

  --------------------------------------------*/  
      
string Change_me(string my_string)
{
   
    for(int i = 0; i <my_string.length(); i++)
    {
      if(isdigit(my_string)!=0)
      {
          if(isdigit(my_string[i+1])==0)
          {  
              my_string.insert(i+1, "v");
              //v is just an arbitary choice
              //it could be any other letter
              //but it has to be a LETTER
                 
          }   
      }   
    }
    //Changed -7*-7 case
    for (int i = 0; i <my_string.length(); i++)
    {
        if(my_string=='-')
        {
            if((my_string[i-1]!='v')&&(my_string[i-1]!=')'))
            {
               my_string.replace(i,1,"y");
            }
        }
    }

    return my_string;
}

/*-----------------------------------------
  My function needed to tokenise expression
  -----------------------------------------*/
string Insert_comma(string my_string)
{
    for(int i = 0; i <my_string.length(); i++)
    {
      if((my_string=='*')||
         (my_string=='-')||
         (my_string=='/')||
         (my_string=='+')||
         (my_string=='^')||
         (my_string=='c'))
          {
            my_string.insert(i+1, ",");
            //Insert a comma after all
            //found operators
          }
           else if(my_string=='v')
           {
              my_string.replace(i,1,",");
              //replace the v with a comma
              //for clarity
           }               
    }
    //Changed
    for (int i = 0; i <my_string.length(); i++)
    {
        if(my_string=='y')
        {
             my_string.replace(i,1,"-");
         }
     }   
    return my_string;
}   

/*-----------------------------------------
  My function to check that no variables
  were entered
  -----------------------------------------*/
bool Check_valid(string my_string)
{
    //Changed check that consecutive '+', '-'
    //signs do not exist
    for (int i = 0; i<my_string.length(); i++)
    {
        if((my_string=='+')||(my_string=='-'))
        {
            if((my_string[i+1]=='+')||(my_string[i+1]=='-'))
            {
                return false;
            }
        }
    }            
        
        
    string array="0123456789+-*/()^c";

    int count=0;
    for (int i=0; i<my_string.length(); i++)
    {
        for(int j=0; j<array.length(); j++)
        {
            if(my_string==array[j])
            {
               count++;
            }
        }
    }
   
    if (count == my_string.length())
    {
      return true;   
    }
    else
    {   
      return false;   
    }
            
}  

/*-----------------------------------
  My function to actually evaluate
  postfix expression
  ----------------------------------*/

void Next(string my_string)
{
  vector <string> array;
  string tempy;
  
  int comma_count=0;
  for (int a=0; a<my_string.length();a++)
  {
      if(my_string[a]==',')
      {
          comma_count++;
      }
  }        

  //Evaluate tokens using the "," as a delimiter
  while (my_string.find(",", 0) != string::npos)
  {
    //lifted from the FAQ
    //does the string have a comma in it?
    size_t pos = my_string.find(",", 0);
    tempy = my_string.substr(0, pos);      
    my_string.erase(0, pos + 1);           
    array.push_back(tempy); //store in vector              
  }

  //array.push_back(my_string);//the last token is all alone
  
  stack <string> my_stack;//initialise stack
  string temp[100];
  string ch;
  
  for (int i=0; i<comma_count; i++)
  {
      
      string s;
      s=array; //make it easier to read
      
      if ((s!="+")&&
          (s!="*")&&
          (s!="-")&&
          (s!="/")&&
          (s!="^")&&
          (s!="c"))
           {
             my_stack.push(s);
             //push numbers onto the stack
           }
         else //i.e if it encounters an operator
         {
               my_stack.push(s);//push operator onto stack
               temp[0]= my_stack.top();//store value
               my_stack.pop(); //erase from the stack
            
               temp[1]= my_stack.top();//store value
               my_stack.pop();//erase from the stack
               
               temp[2]= my_stack.top();//store value
               my_stack.pop();//erase from the stack
            

               double z;
               z = Eval(temp);
               ostringstream outs;  // Declare an output string stream.
               outs << z;   // Convert value into a string.
               ch = outs.str();

               my_stack.push(ch);
  
           }               
  }
  cout<<ch;  
  cin.get();
}
/*------------------------------
  My function to do the math:
  Converts string to double
  then back to string
  ------------------------------*/
double Eval(string temp[])
{
    string a,b,c;
    a=temp[2]; b=temp[0]; c=temp[1];
    double x,y,z,t;
    istringstream ins,inse;
    ins.str(a);inse.str(c);
    ins >> x;
    inse >> y;
   
     if (b=="+")
     {
        z = x + y;
        return z;
     }
     else if (b=="-")
     {
        z = x - y;
        return z;
     }
     else if (b=="*")
     {
        z = x * y;
        return z;
     }
     else if (b=="/")
     {
        z = x / y;
        return z;
     }      
     else if (b=="^")
     {
        z = pow(x,y);
        return z;
     }   
      else if (b=="c")
     {
        t = cos (x*PI/180);
        z = y + t;
        return z;
     }                                                               
}

這是我在網路上找的的程式,她加減乘除和次方的部分都可以跑,但是我加了cosine之後只要打入c(60)就會跳出程式,有沒有人可以幫我看看為什麼?

[ 本帖最後由 anglin1024 於 2009-5-2 17:29 編輯 ]
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2024-5-17 21:56 , Processed in 0.016455 second(s), 17 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表