中缀表达式转后缀表达式与括号匹配

来源:互联网 发布:ios编程 第四版 微盘 编辑:程序博客网 时间:2024/06/01 23:40

1、算法思想

1.1中缀转后缀表达式:

从左到右依次扫描每个元素
(1)如果是左括号,直接入栈;
(2)如果是右括号,则将栈中左括号以及之上的元素依次出栈,如果出栈的元素不是左括号,则加入后缀表达式中(这里用队列来存储,也可以直接输出);
(3)如果是其他运算符,如果该操作符优先级比栈顶元素高则直接入栈;否则,依次出栈,加入后缀表达式中,直到如果该操作符优先级比栈顶元素高或者栈空为止;将该元素入栈,(设左括号优先级小于任何操作符);
(4)如果是操作数直接加入后缀表达式(这里用队列来存储,也可以直接输出)

1.2括号匹配:

从左到右依次扫描每个元素
(1)如果是左括号,直接入栈;
(2)如果是右括号,则出栈,若出栈的是左括号;则该右括号匹配成功;否则括号匹配失败;
(3)扫描完成后若栈空,匹配成功;否则匹配失败;

#include<iostream>using namespace std;#define ok 1#define no 0#define error 0#define yes 1#define maxsize 50struct sqstack//定义一个顺序栈{    char data[maxsize];    int top, bottom;};struct sqqueue//定义一个顺序队列{    char data[maxsize];    int front, rear;};int initstack(sqstack &s)//初试化栈{    s.bottom = s.top = -1;    return ok;}int initqueue(sqqueue &q)//初始化队列{    q.front = q.rear = 0;    return ok;}int stack_isempty(sqstack s)//判栈空{    if (s.bottom == s.top)        return yes;    else        return no;}int queue_isempty(sqqueue q)//判队空{    if (q.front == q.rear)        return yes;    else        return no;}int stack_isfull(sqstack s)//判栈满{    if (s.top-s.bottom>=maxsize)        return yes;    else        return no;}int queue_isfull(sqqueue q)//判队满{    if ((q.rear+1)%maxsize==q.front)        return yes;    else        return no;}int push(sqstack &s, char x)//入栈{    if (stack_isfull(s))        return error;    else    {        s.data[++s.top] = x;        return ok;    }}int pop(sqstack &s, char &x)//出栈{    if (stack_isempty(s))        return error;    else    {        x = s.data[s.top--];        return ok;    }}int gettop(sqstack s, char &x)//取栈顶元素{    if (stack_isempty(s))        return error;    else    {        x = s.data[s.top];        return ok;    }}int enqueue(sqqueue &q, char x)//进队{    if (queue_isfull(q))        return error;    else    {        q.data[q.rear] = x;        q.rear = (q.rear + 1) % maxsize;            return ok;    }}int dequeue(sqqueue &q, char &x)//出队{    if (queue_isempty(q))        return error;    else    {        x=q.data[q.front];        q.front = (q.front + 1) % maxsize;        return ok;    }}int priority(char x)//判断优先级{    int n=0;    switch (x)    {    case '+':n = 3; break;    case '-':n = 3; break;    case '*':n = 5; break;    case '/':n = 5; break;    case '(':n = 1; break;    case ')':n = 6; break;    default: break;    }    return n;}/*括号匹配思想从左到右依次扫描每个元素(1)如果是左括号,直接入栈;(2)如果是右括号,则出栈,若出栈的是左括号;则该右括号匹配成功;否则括号匹配失败;(3)扫描完成后若栈空,匹配成功;否则匹配失败;*/int match(char str[], int n){    int i; char x;    sqstack s; initstack(s);    for (i = 0; i < n; i++)    {        switch (str[i])        {        case '(':push(s, str[i]); break;        case ')':pop(s, x); if (x = '(') break; else return error;        default:break;        }    }    if (stack_isempty(s))        return ok;    else        return error;}/*中缀转后缀表达式: 从左到右依次扫描每个元素(1)如果是左括号,直接入栈;(2)如果是右括号,则将栈中左括号以及之上的元素依次出栈,如果出栈的元素不是左括号,则加入后缀表达式中(这里用队列来存储,也可以直接输出);(3)如果是其他运算符,如果该操作符优先级比栈顶元素高则直接入栈;否则,依次出栈,加入后缀表达式中,直到如果该操作符优先级比栈顶元素高或者栈空为止;将该元素入栈,(设左括号优先级小于任何操作符);(4)如果是操作数直接加入后缀表达式(这里用队列来存储,也可以直接输出)*/int chang(char str[],int n){    int i; char x;     sqstack s; initstack(s);    sqqueue q; initqueue(q);    for (i = 0; i < n; i++)//从左到右依次扫描    {        if (str[i] == '(')//如果是左括号直接入栈,然后扫描下一个元素            if (push(s, str[i]))                continue;            else                return error;        else if (str[i] == ')')//如果是右括号,则将左括号之上的元素出栈,依次入队,然后将括号出栈        {            while (!stack_isempty(s))            {                pop(s, x);                if (x != '(')                    enqueue(q, x);                else                    break;            }            continue;        }        else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')//如果是四则运算的符号        {            if (gettop(s, x))//如果栈不为空,取出栈顶元素                if (priority(str[i]) > priority(x))//如果当然元素优先级别大于栈顶元素的优先级别,则入栈                {                    if (push(s, str[i]))                        continue;                }                else                {                    while (!stack_isempty(s) && priority(str[i]) <= priority(s.data[s.top]))//否则将优先级高于或等于当前运算符的栈顶元素依次出栈并入队,直到栈顶元素优先级比自己低或者遇到左括号为止                    {                        pop(s, x);                        enqueue(q, x);                    }                                               push(s, str[i]);                        continue;                }            else//如果栈空,则直接入栈            {                push(s, str[i]);                continue;            }        }        else//如果是操作数则直接进队        {            enqueue(q, str[i]);                continue;        }    }    while (!stack_isempty(s))//扫描完成后将栈中剩余的操作符依次入队    {        pop(s, x);        enqueue(q, x);    }    while (!queue_isempty(q))//输出后缀表达式    {        dequeue(q, x);        cout << x;    }     return ok;}void main(){    char str[] = "a+b-a*((c+d)/e-f)+g";    if (match(str,sizeof(str)-1))        chang(str,sizeof(str)-1);    else        cout << "表达式括号不匹配,请重新输入";}

这里写图片描述

0 0
原创粉丝点击