使用栈实现表达式求值,运用栈计算

使用栈实现表达式求值

题目要求

	读取一个多项式,使用栈进行多项式求值,并输出结果。

##思路

	1.使用两个栈,nums用于存储操作数,ops用于存储操作符
	2.从左往右扫描,遇到操作数入栈nums
	3.遇到操作符时,如果优先级低于或等于栈顶操作符优先级,则从nums弹出两个元素进行计算,并压入nums,
	  继续与栈顶操作符的比较优先级
	4.如果遇到操作符高于栈顶操作符优先级,则直接入栈ops
	5.遇到左括号,直接入栈ops,遇到右括号,则直接出栈并计算,直到遇到左括号
#include<bits/stdc++.h>//万能头文件,没有的话需要手动下载
typedef int datatype;
#define maxsize 64
//定义顺序栈结构
struct seqstack
{
	datatype data[maxsize];
	int top;
};
//定义基本函数
seqstack* CREATES()
{
	seqstack* p;
	p = (seqstack*)malloc(sizeof(seqstack));
	p->top = -1;
	return p;
}

seqstack* SETNULL(seqstack* S)
{
	S->top = -1;
}

int EMPTY(seqstack* S)
{
	if (S->top >= 0)
		return false;
	else
		return true;
}

seqstack* PUSH(seqstack* s, datatype x)
{
	if (s->top == maxsize - 1)
	{
		printf("overflow");
		return NULL;
	}
	else
	{
		s->top++;
		s->data[s->top] = x;
	}
	return s;
}

datatype POP(seqstack* s)
{
	if (EMPTY(s))
	{
		printf("underflow");
		return NULL;
	}
	else
	{
		s ->top--;
		return s->data[s->top + 1];
	}
}

datatype TOP(seqstack* s)
{
	if (EMPTY(s))
	{
		printf("underflow");
		return NULL;
	}
	else
	{
		return s->data[s->top];
	}
}
//记录运算符号优先级
static char pre[128] = { 0 };


//定义优先级
void setpre()
{
    pre['+'] = 4;
    pre['-'] = 4;
    pre['*'] = 3;
    pre['/'] = 3;
    pre['('] = 1;
    pre[')'] = 1;
}

//创建字符串接收字符串型数据
string gets()
{
	string s;
	cin >> s ;
	return s;
}

//比较两个符号的优先级,如果op2高于op1则返回fu值,相等为0,低于为z值
int precompare(char op1, char op2)
{
    return pre[op2] -pre[ op1];
}

//计算操作,只负责计算,将所得数据压入num中;
int active(seqstack* num, seqstack* ops)
{
    int a, b, r=0,op;
        op=POP(ops);
        if (op == '(')
            op = POP(ops);
        b = POP(num);
        a = POP(num);
        printf("get b from stack %d\n", b);
        printf("get a from stack %d\n", a);
        printf("get op from stack %c\n", op);
        switch (op)
        {
        case '+':
        {
            printf("push %d into stack\n", a + b);
            r=a+b;
            PUSH(num, r);
            break;
        }
        case '-':
        {
            printf("push %d into stack\n", a - b);
            r=a-b;
            PUSH(num, r);
            break;
        }
        case '*':
        {
            printf("push %d into stack\n", a * b);
             r = a * b;
             PUSH(num, r);
            break;
        }
        case '/':
        {
            printf("push %d into stack\n", a / b);
            r=a/b;
            PUSH(num, r);
            break;
        }
        }
       
        return r;
}

//整体操作,进行运算,得出结果
int addition(string str)
{
    cout << str << endl;
    int i=0, j, k, flag, temp;
    //创建两个栈,nums装填数字,ops装填操作符
    seqstack* nums, * ops;
    nums = CREATES();
    ops = CREATES();
    while (str[i] != '#')//遍历多项式
    {
        cout << str[i]<<"   ";
        if (str[i] >= '0' && str[i] <= '9')//判断是否为数字
        {
            if (flag == 1)//判断前一个字符是否为数字,如果是,弹出乘10加下一位
            {
                temp = POP(nums);
            }
            else
                temp = 0;
            temp = temp * 10 + str[i] - '0';
            flag = 1;
            PUSH(nums, temp);
        }
        //判断是否为操作符,如果是则进行判断和计算
        else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
        {
            flag = 0;
            if (ops->top<0)//判断操作数栈是否为空栈,是则直接插入,不是则判断是否需要运算
            {
                PUSH(ops, str[i]);
            }
            else
            {
                if (precompare(TOP(ops),str[i])>=0)//如果新输入的符号优先级低于之前的,进行计算
                {
                    if (TOP(ops) == '(')
                        PUSH(ops, str[i]);
                    else
                    {
                       active(nums, ops);
                        PUSH(ops, str[i]);
                    }
                }
                else
                {
                     
                    PUSH(ops, str[i]);
                    
                }
            }
        }
        else if (str[i] == '(')//左括号直接压入
        {
            flag = 0;
            PUSH(ops, str[i]);
        }
        else if (str[i] == ')')//右括号对左侧进行弹出计算
        {
            flag = 0;
            while (TOP(ops) !='(')//遍历到左括号结束
            {
                if (TOP(ops) == '(')
                {
                    POP(ops);
                    break;
                }
                active(nums, ops);
                printf("%c\n", TOP(ops));
            }
        }
        i++;
    }
    while (!EMPTY(nums) && !EMPTY(ops))//判断是否计算完全,即操作数栈为空
    {
        active(nums, ops);
    }
    temp = POP(nums);
    printf("%d\n", temp);
    return 0;
}

int main()
{
    string s;
    setpre();
    //freopen("D:\\学习X\\数据结构\\基础操作实现\\text.in", "r", stdin);
    s = gets();
    addition(s);
    return 0;
}
  • 4
    点赞
  • 0
    评论
  • 25
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:鲸 设计师:meimeiellie 返回首页

打赏作者

cpp小白

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值