C++表达式求值

"sharing happiness is happy"

                                                                                                                             2021-10-8

一.细节处理:

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  5."#"为-1

二.知识要点:

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

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

    

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

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

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

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

     1. 此时若str1优先级大于str2 则将str1入运算符栈并继续扫描下一个字符

     2.否则弹出运算符栈的栈顶元素和弹出操作数栈的两个元素进行运算,并继续执行当前字符

    3其中'#'和运算符栈中的'#'相遇 则弹出栈中的'#'     ”)“右括号遇到运算符栈中的左括号”(” 弹出栈中的"("

   三.最后 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;
	}
}

四.测试结果:

五. 热爱编程 热爱计算机~

附:java版实现

import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Scanner;
class Expression
{
	private String str;
	public Expression(String s)
	{
		this.str=s+"#";
	}
	private int Comp(char str1,char str2)
	{
	  switch(str1)
	  {
	  case'+':
	  case'-':
		  if(str2=='#'||str2=='('||str2==')') {return 1;}
		  else {return -1;}
	  case'*':
      case'/':
		  if(str2=='*'||str2=='/') {return -1; }
		  else {return 1;}
      case'(':
    	  return 1;
      case')':
    	  if(str2=='(') {return 0;}
    	  else if(str2=='#') {return 1;}
    	  else {return -1;}
      case '#':
    	  if(str2=='#') {return 0;}
    	  else {return -1;}
      default:
    	  return 0;
	  }
	}
	public int Compute() throws IOException
	{
		int Num[]=new int[100];
		char Symbol[]=new char[100];
		int top1=-1,top2=0;
		Symbol[0]='#';
		int j=0;
		char op;
		while(j<this.str.length())
		{
			if(str.charAt(j)>='0'&&str.charAt(j)<='9') {Num[++top1]=str.charAt(j++)-'0';;}
			else {
				//运算符
				int result=0;
				int cmp=Comp(str.charAt(j),Symbol[top2]);
				if(cmp==1){Symbol[++top2]=str.charAt(j++);}
				else if(cmp==0) {j++;--top2;}//运算符出栈 继续处理下一个字符
				else if(cmp==-1) {
					int y=Num[top1--];
					int x=Num[top1--];
					op=Symbol[top2--];
					switch(op)
					{
					case'+':
						result=x+y;
						break;
					case'-':
						result=x-y;
						break;
					case'*':
					    result=x*y;
					    break;
					case'/':
						if(0!=y) {result=x/y;}
						else {throw new IOException("除数为0!");}
						break;
				    default:break;		
					}
					Num[++top1]=result;
				}	
			}
		}
		return Num[top1];
	}
}
public class Tencent
{
	static void Format(StringBuilder s)
	{
		int len=s.length();
		for(int i=0;i<len;i++)
		{
			if(s.charAt(i)=='-')
			{
				if(i==0) {s.insert(0, '0');}
				else if(s.charAt(i-1)=='(') {s.insert(i,'0' );}
			}
		}
	}
	static public void main(String []args) throws IOException
	{
	   StringBuilder s=new StringBuilder("(2+3)*2+1");
	   Format(s);
       Expression str=new Expression(s.toString());
       System.out.println(str.Compute());
	}
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值