表达式求值

论坛 期权论坛 脚本     
匿名技术用户   2020-12-29 10:44   30   0
#include<stack>
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;

//template<class T>
//input.txt文本文件内容:
//2 * (4 - 100) =
//3 * 5 + 9 / 3 =
//100 - 20 * (4 * 6 / 3) =
//(135 + 75) / (14 * 5) =
//120 - 60 / 5 * 5 =
//128 - 6 * 8 / 16 =
//330 / (65 - 50) =
//
//生成的output.txt文本文件内容:
//2 * (4 - 100) = -192
//3 * 5 + 9 / 3 = 18
//100 - 20 * (4 * 6 / 3) = -60
//(135 + 75) / (14 * 5) = 3
//120 - 60 / 5 * 5 = 60
//128 - 6 * 8 / 16 = 125
//330 / (65 - 50) = 22
typedef struct Dates
{
 string Exp;
 int Result;
}Datas;
typedef struct
{
 Datas *base;
 int length;
}AList;
class Express
{
private:
 AList List;
public:
 Express();
 void Read(char*name);
 bool Check(string Str);
 bool ck1(string Str);
 bool ck2(string Str);
 void Write(char*name);
 void calculate();
 void show();
 void show2();
 char Precede(char c1,char c2);
 int  Operator(int a, char theta, int b);
 bool IN(char ch);
 bool Matching(string Str);
};
bool Express::Matching(string Str)
{
 int flag = 1;
 Str += '#';
 int n = 0;
 char ch;
 stack<char>S;
 ch = Str[n]; n++;
 while (ch != '#'&&flag)
 {
  switch (ch)
  {
  case'(':
   S.push(ch); break;
  case')':
   if (!S.empty())
    S.pop();
   else
    flag = 0; break;
  }
  if (n < Str.length())
  {
   ch = Str[n]; n++;
  }
 }
 if (S.empty() && flag)return true;
 else return false;
}
void Express::show2()
{
 cout << "************************************题目列表如下(可见于input.txt)*****************************************" << endl;
 for (int i = 0; i < List.length; i++)
 {
  cout <<"                                        "<< List.base[i].Exp << "="  << endl;
 }
 cout << "****************************************************************************************************************" << endl;
}
bool Express::IN(char ch)
{
 if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#')
 {
  return true;
 }
 else
 {
  return false;
 }
}
int Express::Operator(int a, char theta, int b)
{
 switch (theta)
 {
 case '+': return a + b;
 case '-': return a - b;
 case '*': return a*b;
 case '/': return a / b;
 }
 return 0;
}
char Express::Precede(char c2, char c1)
{
 int i, j;
 char Table[8][8] = { ' ','+','-','*','/','(',')','#',

                   '+','>','>','<','<','<','>','>',

                     '-','>','>','<','<','<','>','>',

                   '*','>','>','>','>','<','>','>',

                   '/','>','>','>','>','<','>','>',

                   '(','<','<','<','<','<','=','> ',

                   ')','>','>','>','>','> ','>','>',

                   '#','<','<','<','<','<','<','=', };           //优先级表格

 for (i = 0; i < 8; i++)
  if (Table[0][i] == c1)          // 纵坐标寻找
   break;
 for (j = 0; j < 8; j++)           //横坐标寻找
  if (Table[j][0] == c2)
   break;
 return Table[j][i];
}
void Express::calculate()
{ 
 for (int i = 0; i < List.length; i++)
 {
  int a,d,b,n = 0;
  char x,c;
  stack<char> ch;
  stack<int>in;
  List.base[i].Exp += '#';
  ch.push('#');
  c = List.base[i].Exp[n]; n++;
  x = ch.top();
  while (c != '#' || x != '#')
  {
   if (!IN(c))
   {
    if (c >= '0'&&c <= '9')
    {
     d = 0;
     while (c >= '0'&&c <= '9')
     {
      d = d * 10 + c - '0';
      if (n < List.base[i].Exp.length())
      {
       c = List.base[i].Exp[n]; n++;
      }
     }
     in.push(d);
    }
   }
   else
   {
    switch (Precede(ch.top(), c))
    {
    case'<':
     ch.push(c); if (n < List.base[i].Exp.length()) { c = List.base[i].Exp[n]; n++; }
     break;
    case'>':
     x = ch.top();
     ch.pop();
     b = in.top();
     in.pop();
     a = in.top();
     in.pop();
     in.push(Operator(a,x, b));
     break;
    case'=':
     x = ch.top();
     ch.pop();
     if (n < List.base[i].Exp.length()) { c = List.base[i].Exp[n]; n++; }
     break;
    }
   }
  }
  List.base[i].Result = in.top();
  in.pop();
  List.base[i].Exp = List.base[i].Exp.substr(0,List.base[i].Exp.length() - 1);
 }
}
bool  Express::ck1(string Str)
{
 char*p;
 p = &Str[0];
 while (*p != NULL)
 {
  if ((*p>39 && *p<58)||*p=='=')
  {
   p++;
  }
  else
  {
   cout << "                                        " << "表达式存在无意义字符:" << Str << endl;
   return false;
  }
 }
 return true;
}
bool  Express::ck2(string Str)
{
 char*p;
 p = &Str[0];
 if (ck1(Str))
 {
  while (*p != NULL)
  {
   if (*p == '/' || *p == '*' || *p == '+' || *p == '-')
   {
    char*q;
    q = p;
    q++;
    if (*q == '/' || *q == '*' || *q == '+' || *q == '-')
    {
     cout << "                                        " << "两个运算符之间不能一起运算:" << Str << endl;
     return false;
    }
   }
   p++;
  }
  p--;
  if (*p == '/' || *p == '*' || *p == '+' || *p == '-')
  {
   cout<<"                                        " << "最后一个字符为运算符,无意义:" << Str << endl;
   return false;
  }
  else if(*p=='=')
  {
   p--;
   if (*p == '/' || *p == '*' || *p == '+' || *p == '-')
   {
    cout << "                                        " << "最后一个字符为运算符,无意义:" << Str << endl;
    return false;
   }
   return true;
  }
  else
  {
   return true;
  }
 }
 else
 {
  return false;
 }
}
bool Express::Check(string Str)
{
 char*p;
 char*q;
 char*T;
 string Temp;
 if (ck2(Str))
 {
  for (int i = 0; i < Str.length(); i++)
  {
   if (Str[i] == '(' || Str[i] == ')')
   {
    Temp += Str[i];
   }
  }
  if (Temp.length() == 0) { return true; }
  if (Temp.length() % 2 == 1)
  {
   cout << "                                        " <<"缺少括号:"  << Str<< endl;
   return false;
  }
  else
  {
   if (Matching(Str))
   {
    return true;
   }
   else
   {
    cout << "                                        " << "括号匹配出现问题:" << Str << endl;
    return false;
   }
   
  }
 }
 else
 {
  return false;
 }
 return true;
}
Express::Express()
{
 List.base = new Datas[100];
 List.length = 0;
}

void Express::show()
{
 cout << "************************************计算结果如下(可见于output.txt)****************************************" << endl;
 for (int i = 0; i < List.length; i++)
 {
  cout << "                                         " << List.base[i].Exp<<"="<<List.base[i].Result<<endl;
 }
 cout << "****************************************************************************************************************" << endl;
}
void Express::Read(char*name)
{
 
 ifstream in;
 in.open(name, ios::in);
 Dates D;
 if (in.fail())
 {
  cout << "打开文件失败,确认文件名为inexp 后缀名txt" << endl;
  exit(1);
 }
 while (!in.eof())
 {
  string x;
  in >> x;
  if (Check(x))
  {
   if (x.size() == 0)
   {
    break;
   }
   if (x.find('=') < 100)
   {
    D.Exp = x.substr(0, x.find('='));
   }
   else
   {
    D.Exp = x;
   }
   D.Result = 0;
   List.base[List.length] = D;
   List.length++;
  }
 }
 in.close();
}
void Express::Write(char*name)
{
 ofstream out;
 out.open(name, ios::out | ios::ate);
 if (out.fail())
 {
  cout << "请添加写入文件名outexp 后缀名txt" << endl;
  exit(1);
 }
 for (int i = 0; i < List.length;i++)
 {
  out <<List.base[i].Exp<< "=" << List.base[i].Result << endl;
 }
 out.close();
}
int main()
{
 int S;
 cout << "************************************错误表达式如下(已排除!)***********************************************" << endl;
 Express Exp;
 Exp.Read("input.txt");
 Exp.show2();
 cout << "是否进行计算?(!0)" << endl;
 cin >> S;
  if (S)
  {
   Exp.calculate();
   Exp.Write("output.txt");
  }
 Exp.show();
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP