C++表达式求值详解

编辑: admin 分类: c#语言 发布时间: 2021-12-12 来源:互联网
目录
  • 一.细节处理:
    • 1.注意负数 因此要进行字符串预处理
    • 2.考虑除数为0
    • 3.原字符串再加上一个定界符 '#'
    • 4.优先级:
  • 二.知识要点:
    • 三.完整源码:
      • 四.测试结果:
        • 总结

          一.细节处理:

          1.注意负数 因此要进行字符串预处理

          string format(string str) 
          {
          	int len = str.length();
          	for (int i = 0; i < len; i++)
          	{
          		if (str[i] == '-')
          		{
          			if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
          			else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
          		}
          	}
          	return str;
          }

          2.考虑除数为0

                              case '/':
          					if (0 != y) { res = x / y; }
          					else { cout << "非法表达式"; return -1; }
          					break;

          3.原字符串再加上一个定界符 '#'

          str=str+'#'

          4.优先级:

          1."("未入栈前为3 入栈后为0 2.”)"和"#"为0 3.”+" "-"为1 4.”*"和"/"为2

          二.知识要点:

          中缀表达式转为后缀表达式

          1. 首先设置存储运算符和存储操作数两个栈 即Symbol[N]和Num[N]且分别对应top2,top1

          top1=-1 Symbol[0]='#' //运算符栈设置定界符 top2=0

          2.入栈和出栈的规则 字符串为str

          一.若str[i]>='0&&str[i]<='9',则入操作数栈并继续扫描以一个字符 即Num[++top1]=str[i++]-'0';

          二.否则 将当前字符str1与运算符栈的栈顶元素str2进行优先级比较 ,自写比较函数

          例如: str1==‘+' 则若str2==# ,(,) 则返回1 说明str1比str2优先级高

          1. 此时若str1优先级大于str2 则将str1入运算符栈并继续扫描 即 Symbol[++top2]=str[i++]

          2.优先级相等则返回0 此时将运算符栈顶元素弹出,并继续扫描下一个字符即 top2-- i++

          3.若str1优先级小于str2返回-1,此时将运算符栈顶元素弹出 即op=Symbol[top2--]

          并弹出操作数栈的两个元素 即y=Num[top1--],x=Num[top1--] 之后进行计算操作

          三.最后 return Num[top1]

          三.完整源码:

          #define _CRT_SECURE_NO_WARNINGS
          #include<bits/stdc++.h>
          using namespace std;
          class Expression
          {
          public:
          	Expression(string str);
          	~Expression();
          	int Compute();
          private:
          	int Comp(char str1, char str2);
          	string str1;
          };
          Expression::Expression(string str)
          {
          	this->str1 = str + '#';//以定界符开头
          }
          Expression :: ~Expression() {}
          //将中缀表达转为后缀表达
          int Expression::Compute()
          {
          	int Num[100], Symbol[100];//定义存操作数和运算符的两个栈
          	int i, k, x, y, res;
          	char op;
          	Symbol[0] = '#';
          	int top1 = -1, top2 = 0;
          	for (i = 0; str1[i] != '\0';)
          	{
          		if (str1[i] >= '0' && str1[i] <= '9') { Num[++top1] = str1[i++] - '0'; }
          		else {//非操作数就比较运算符优先级
          			int cmp = Comp(str1[i], Symbol[top2]);
          			if (cmp == 1) { Symbol[++top2] = str1[i++]; }//将运算符入栈 并接着扫描下一个字符
          			else if (cmp == 0) { --top2; i++; }//优先级相等 弹栈 并接着扫描下一个字符
          			else {//优先级低 继续处理当前运算符
          				y = Num[top1--];//后面的数要先弹出来 才不会算反
          				x= Num[top1--];
          				op = Symbol[top2--];
          				switch (op)
          				{
          				case '+':
          					res = x + y;//将运算结果入栈
          					break;
          				case '-':
          					res = x - y;
          					break;
          				case '*':
          					res = x * y;
          					break;
          				case '/':
          					if (0 != y) { res = x / y; }
          					else { cout << "非法表达式"; return -1; }
          					break;
          				default:break;
          				}
          				Num[++top1] = res;
          			}
          		}
          	}
          	return Num[top1]; 
          }
          string format(string str) 
          {
          	int len = str.length();
          	for (int i = 0; i < len; i++)
          	{
          		if (str[i] == '-')
          		{
          			if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
          			else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
          		}
          	}
          	return str;
          }
          int main()
          {
          	string str;
          	int n = 3;
          	while (n--)
          	{
          		cout << "请输入一个表达式: " << endl;
          		cin >> str;
          		str = format(str);
          		Expression E(str);
          		int result = E.Compute();
          		cout << "表达式的值的是: " << result << endl;
          	}
          	return 0;
          }
          int Expression::Comp(char str1, char str2)//当前字符元素和栈顶运算符优先级比较
          {
          	//1代表 str1优先级大于str2 0 代表相等 -1代表小于
          	switch (str1)
          	{
          	case'+':case'-': 
          		if (str2 == '#'||str2==')'||str2=='(') { return 1; }//左括号入队列后优先级变为0
          		else { return -1; }
          		break;
          	case'*':case'/':
          		if (str2 == '*' || str2 == '/') { return -1; }
          		else  { return 1; }
          		break;
          	case'(':
          		return 1;
          		break;
          	case')':
          		if (str2 == '(') { return 0; }
          		else if(str2 == '#') { return 1; }
          		else { return -1; }
          		break;
          	case'#':
          		if (str2 == '#') { return 0; }
          		else { return -1; }
          		break;
          	default: break;
          	}
          }

          四.测试结果:

          总结

          本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!

          【文章来源:http://www.1234xp.com/mggfzq.html网络转载请说明出处】