中缀表达式计算器

假如给定一个中缀表达式:1+(2-3)*4+10/5利用栈就可以导出后缀表达式123-4*+105/+

导出时注意:操作符入栈,操作数不入栈,在符号“+-*/()”入栈时如果栈中的出现了括号匹配时,需要匹配括号中的符号弹出。如果操作符入栈栈中有级别高或者相等的,就需要将栈中这样级别高或者想到的先出栈,格式肯定是操作数在前,操作符在后的。具体看这个视频:http://v.youku.com/v_show/id_XNTg3MDc0ODQw.html

当得到一个后缀表达式时就很容易的求出表达式的值了,也是用栈计算的,对于123-4*+105/+,从前往后,如果遇到操作数的时候直接入栈,遇到操作符,就从栈中弹出两个操作,那下面的跟上面的那个预算,就可以得到123-4*+105/+的值为-1了,张铭的数据结构堆栈中讲的有。

下面是个中缀表达式的例子:

Stack.h

#include <stdio.h>   
#include <malloc.h>   
//栈节点数据结构   
class DoubleNode  
{  
	friend class DoubleStack;  
private:  
	double value;  
	DoubleNode *next;  
	//构造函数   
	DoubleNode(double value, DoubleNode *p):value(value),next(p){}  
};  
//栈,用来保存采用后缀表达式进行四则运算时的操作数   
class DoubleStack  
{  
private:  
	DoubleNode *top;  
public:  
	DoubleStack():top(NULL){}  
	~DoubleStack();  
	void push(double value);  
	double pop();  
	bool isEmpty(){return top == NULL;}  
	double getTop();  
};  

//栈节点数据结构   
class CharNode  
{  
	friend class CharStack;  
private:  
	char value;  
	CharNode *next;  
	//构造函数   
	CharNode(char value, CharNode *p):value(value),next(p){}  
};  
//栈,用来保存中缀表达式转换成后缀表达式时的运算符   
class CharStack  
{  
private:  
	CharNode *top;  
public:  
	CharStack():top(NULL){}  
	~CharStack();  
	void push(char value);  
	char pop();  
	bool isEmpty(){return top == NULL;}  
	char getTop();  
	void makeEmpty();  
};  
Stack.cpp

#include "Stack.h"
DoubleStack::~DoubleStack()
{
	DoubleNode *p;
	while (NULL != top)
	{
		p = top;
		top = top->next;
		delete p;
	}
}
void DoubleStack::push(double value)
{
	top = new DoubleNode(value,top);
}
double DoubleStack::pop()
{
	if (!isEmpty())
	{
		DoubleNode *p;
		p = top;
		top = top->next;
		double nodeValue = p->value;
		delete p;
		return nodeValue;
	}
}
double DoubleStack::getTop()
{
	return top->value;
}

CharStack::~CharStack()
{
	CharNode *p;
	while (NULL != top)
	{
		p = top;
		top = top->next;
		delete p;
	}
}
void CharStack::push(char value)
{
	top = new CharNode(value,top);
}
char CharStack::pop()
{
	if (!isEmpty())
	{
		CharNode *p;
		p = top;
		top = top->next;
		char nodeValue = p->value;
		delete p;
		return nodeValue;
	}
}
void CharStack::makeEmpty()
{
	CharNode *p;
	while (NULL != top)
	{
		p = top;
		top = top->next;
		delete p;
	}
}
char CharStack::getTop()
{
	return top->value;
}
arithmetic.h

#include <stdio.h>   
#include <malloc.h>   
#include <string.h>   
#include <stdlib.h>   
#include "Stack.h"   
class Data  
{  
public:  
	double num;  
	char op;  
};  
class Arithmetic  
{  
private:  
	DoubleStack dStack;  //保存四则运算时,后缀表达式中的操作数   
	CharStack cStack;   //保存中缀表达式转换成后缀表达式过程中的操作符   
	int isp(char op);   //栈内优先级   
	int icp(char op);   //栈外优先级   
public:  
	Data post[100];    //保存后缀表达式   
	int curLen;        //后缀表达式数组的实际长度   
	void midTopost(char *c);  //把中缀表达式转换成后缀表达式   
	double calculate();  //进行四则运算   
}; 
arithmetic.cpp

#include "arithmetic.h"   
void Arithmetic::midTopost(char *c)  
{  
	int i = 0;  
	int k;  
	int j;  
	char tmp;  
	char a[100];  
	char num[10];  

	//下面开始把字符串中的操作符(+-*/)放入后缀表达式   
	cStack.makeEmpty();  
	cStack.push('#');  
	//字符串最后都加一个#   
	strcat(c, "#");  
	k = 0;  
	while (c[k] != '\0')  
	{  
		if (c[k] == '+' || c[k] == '-' || c[k] == '*' || c[k] == '/' || c[k] == '(')  
		{  
			//如果优先级低,一直退栈,否则入栈   
			while (isp(cStack.getTop()) > icp(c[k]))  
			{  
				post[i++].op = cStack.pop();  
			}  
			cStack.push(c[k]);  
		}  
		else if (c[k] == ')')  
		{  
			//一直退栈到'('   
			while (isp(cStack.getTop()) >= icp(')'))  
			{  
				tmp = cStack.pop();  
				if (tmp != '(')  
				{  
					post[i++].op = tmp;  
				}  
			}  

		}  
		else if (c[k] == '#')  
		{  
			while (isp(cStack.getTop()) > icp('#'))  
			{  
				tmp = cStack.pop();  
				post[i++].op = tmp;  
			}  
		}  
		else if (c[k] >= '0' && c[k] <= '9')  
		{  
			//数字,继续往后获取字符,如果是数字,全部拼装到num中,然后转换成double类型   
			j = 0;  
			memset(num, 0, 10);  
			num[j] = c[k];  
			k = k + 1;  
			while (c[k] >= '0' && c[k] <= '9')  
			{  
				num[++j] = c[k];  
				k++;  
			}  
			post[i].num = atof(num);  
			post[i].op = '#';  
			i++;  
			k--;  
		}  
		else  
		{  
			//其他非法字符,不处理   
		}  
		k++;  
	}  
	curLen = i;  
}  
//栈内优先级,栈内优先级大于栈外优先级   
//'('的栈内优先级应该比所有的操作符都小(除了#)   
//')'的栈内优先级应该最大   
//+-的优先级一致,*/的优先级一致   
int Arithmetic::isp(char op)  
{  
	int pri;  
	switch (op)  
	{  
	case '#' : pri = 0;  
		break;  
	case '(' : pri = 1;  
		break;  
	case '+' : pri = 3;  
		break;  
	case '-' : pri = 3;  
		break;  
	case '*' : pri = 5;  
		break;  
	case '/' : pri = 5;  
		break;  
	case ')' : pri = 10;  
		break;  
	}  
	return pri;  
}  
//栈外优先级   
int Arithmetic::icp(char op)  
{  
	int pri;  
	switch (op)  
	{  
	case '#' : pri = 0;  
		break;  
	case '(' : pri = 10;  
		break;  
	case '+' : pri = 2;  
		break;  
	case '-' : pri = 2;  
		break;  
	case '*' : pri = 4;  
		break;  
	case '/' : pri = 4;  
		break;  
	case ')' : pri = 1;  
		break;  
	}  
	return pri;  
}  
//根据后缀表达式进行四则运算   
double Arithmetic::calculate()  
{  
	int i;  
	double result = 0;  
	double left, right;  
	for (i = 0; i < curLen; i++)  
	{  
		//如果是数字就入栈   
		if (post[i].op == '#')  
		{  
			dStack.push(post[i].num);  
		}  
		else //如果是操作符,就取出两个数字进行运算   
		{  
			right = dStack.pop();  
			left = dStack.pop();  
			switch (post[i].op)  
			{  
			case '+' : dStack.push(left + right);  
				break;  
			case '-' : dStack.push(left - right);  
				break;  
			case '*' : dStack.push(left * right);  
				break;  
			case '/' : dStack.push(left / right);  
				break;  
			}  
		}  
	}  
	return dStack.pop();  
}  
main.cpp

#include "arithmetic.h"
int main()
{
	char tmp[100];
	printf("please input a arithmetic express:\n");
	scanf("%s", tmp);
	Arithmetic ari = Arithmetic();
	ari.midTopost(tmp);

	printf("the result = [%f]/n", ari.calculate());

	system("pause") ;
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式计算器可以使用栈来实现。具体方法如下: 1. 定义两个栈,一个存放运算符,一个存放操作数。 2. 从左到右遍历中缀表达式,遇到操作数直接入操作数栈。 3. 遇到运算符时,先将其与运算符栈的栈顶元素比较优先级。 4. 如果当前运算符优先级大于栈顶运算符优先级,则直接入栈。 5. 如果当前运算符优先级小于或等于栈顶运算符优先级,则弹出栈顶运算符和两个操作数进行计算,并将结果入操作数栈,直到当前运算符可以入栈。 6. 遍历完表达式后,如果运算符栈不为空,则依次弹出运算符和两个操作数进行计算,直到运算符栈为空。 下面是一个示例代码,只包括加法和乘法: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int top; int data[100]; } Stack; void push(Stack *s, int x) { s->data[++s->top] = x; } int pop(Stack *s) { return s->data[s->top--]; } int peek(Stack *s) { return s->data[s->top]; } int is_empty(Stack *s) { return s->top == -1; } int is_operator(char c) { return c == '+' || c == '*'; } int precedence(char c) { return (c == '*') ? 2 : 1; } int evaluate(char *expr) { Stack op_stack, num_stack; op_stack.top = num_stack.top = -1; for (int i = 0; expr[i] != '\0'; i++) { char c = expr[i]; if (is_operator(c)) { while (!is_empty(&op_stack) && peek(&op_stack) != '(' && precedence(c) <= precedence(peek(&op_stack))) { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int res = (op == '+') ? a + b : a * b; push(&num_stack, res); } push(&op_stack, c); } else if (c == '(') { push(&op_stack, c); } else if (c == ')') { while (!is_empty(&op_stack) && peek(&op_stack) != '(') { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int res = (op == '+') ? a + b : a * b; push(&num_stack, res); } pop(&op_stack); } else { int num = c - '0'; push(&num_stack, num); } } while (!is_empty(&op_stack)) { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int res = (op == '+') ? a + b : a * b; push(&num_stack, res); } return pop(&num_stack); } int main() { char expr[100]; printf("Enter an infix expression (only + and * operators): "); scanf("%s", expr); int res = evaluate(expr); printf("Result: %d\n", res); return 0; } ``` 输入示例:(1+2)*3+4*5 输出示例:Result: 23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值