数据结构实验之栈二:一般算术表达式转换成后缀式(手写栈)

数据结构实验之栈二:一般算术表达式转换成后缀式

Time Limit: 1000MS Memory limit: 65536K

题目描述

对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之。

输入

输入一个算术表达式,以‘#’字符作为结束标志。

输出

输出该表达式转换所得到的后缀式。

示例输入

a*b+(c-d/e)*f#

示例输出

ab*cde/-f*+


解析: 其实对于栈的操作,大家更喜欢用stl,但是手写栈也是很重要的,可以让我们了解栈的内部操作;
对于这个题来说不用栈也行,用树的后序遍历更好。
讲一下核心内容:(1)、遇到字母一律输出;
(2)、遇到左括弧一律入栈;
(3)、遇到右括弧就把两个括弧之间的所有符号出栈输出,并且左括弧出栈;
(4)、遇到“+”或“-”,如果栈不空并且栈顶不是左括弧就出栈输出这一个栈顶,“+”或“-”入栈;
(5)、遇到“*”或“/”,如果栈不空并且栈顶不是左括弧并且栈顶是“*”或“/”,就把栈顶出栈输出,“*”或“/”入栈;
这是操作步骤,想问“+”、“-”、“*”、“/”为什么操作不一样,那就是符号优先级的问题了。
  ///***********代码
#include <stdio.h>  
#include <stdlib.h>  
#define maxstact 1000  
  
typedef char elemstack;  
typedef struct  
{  
    elemstack *top;  
    elemstack *base;  
    int sizestack;  
} Sq;  
int initstack(Sq &L)  
{  
    L.base=new elemstack[maxstact];  
    if(!L.base)  
        exit(0);  
    L.top=L.base;  
    L.sizestack=maxstact;  
}  
int push(Sq &L,char s)  
{  
    if(L.top-L.base>L.sizestack)  
        return -1;  
    *(L.top++)=s;  
    return 0;  
}  
int pop(Sq &L)  
{  
    if(L.top<=L.base)  
        return -1;  
    printf("%c",*(--L.top));  
}  
int main()  
{  
    Sq L;  
    char a[1000],*s;  
    int i;  
    gets(a);  
    initstack(L);  
    for(i=0; a[i]!='#'; i++)  
    {  
        switch(a[i])  
        {  
        case '(':  
            push(L,a[i]);  
            break;  
        case ')':  
        {  
            while(L.top>L.base&&*(L.top-1)!='(')  
                pop(L);  
            L.top--;  
            break;  
        }  
        case '+':  
        {  
            if(L.top>L.base&&*(L.top-1)!='(')  
                pop(L);  
            push(L,a[i]);  
            break;  
        }  
        case '-':  
        {  
            if(L.top>L.base&&*(L.top-1)!='(')  
                pop(L);  
            push(L,a[i]);  
            break;  
        }  
        case '*':  
        {  
            if(L.top>L.base&&*(L.top-1)!='('&&(*(L.top-1)=='*'||*(L.top-1)=='/'))  
                pop(L);  
            push(L,a[i]);  
            break;  
        }  
        case '/':  
        {  
            if(L.top>L.base&&*(L.top-1)!='('&&(*(L.top-1)=='*'||*(L.top-1)=='/'))  
                pop(L);  
            push(L,a[i]);  
            break;  
        }  
        default:  
        {  
            printf("%c",a[i]);  
            break;  
        }  
        }  
    }  
    while(L.top>L.base)  
    {  
        pop(L);  
    }  
    return 0;  
}  
  
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个实验的目的是将一般算术表达式转换成后缀后缀也叫逆波兰,是一种不含括号的表达式,运算符在操作数的后面,因此也叫后缀表达式。转换后的后缀可以方便地进行计算,而且不需要考虑运算符的优先级和括号的问题。 转换算法的基本思路是利用来存储运算符,遇到操作数直接输出,遇到运算符则将其与顶运算符比较优先级,如果顶运算符优先级高,则将顶运算符弹出并输出,直到顶运算符优先级低于当前运算符或者为空,然后将当前运算符入。最后将中剩余的运算符依次弹出并输出。 例如,将中缀表达式"3+4*5-6"转换成后缀表达式的过程如下: 1. 从左到右扫描中缀表达式,遇到操作数直接输出,即输出3; 2. 遇到运算符"+",将其入; 3. 遇到操作数4,直接输出,即输出4; 4. 遇到运算符"*",由于"*"的优先级高于"+",所以将其入; 5. 遇到操作数5,直接输出,即输出5; 6. 此时顶为"*",优先级高于"+",所以将"*"弹出并输出,即输出4 5 *; 7. 遇到运算符"-",由于"-"的优先级低于"*",所以将"-"入; 8. 遇到操作数6,直接输出,即输出6; 9. 此时顶为"-",优先级低于"*",所以将6入; 10. 扫描结束,将中剩余的运算符依次弹出并输出,即输出3 4 5 * + 6 -。 最终得到的后缀表达式为"3 4 5 * + 6 -"。 ### 回答2: 一般算术表达式是指包含加、减、乘、除等运算符及其优先级,以及括号的表达式。在计算机中,我们需要将这种表达式转换成后缀,以方便计算机的处理。后缀也叫逆波兰,是一种把运算符后置的表达式,例如将中缀表达式“9+5*3-8/4”转换为后缀表达式为“9 5 3 * + 8 4 / -”。 算法思想: 我们可以借助来实现中缀表达式后缀表达式,具体来说,我们需要先遍历一遍中缀表达式,然后按照优先级将操作符加入中,将数字直接输出。遍历完成之后,将中所有操作符按照顺序依次输出,这时候得到的序列就是后缀表达式。 具体实现: 1. 遍历中缀表达式,对于数字直接输出。 2. 对于遇到的操作符,如果是左括号,直接入;如果是右括号,则将中的操作符出,直到遇到左括号停止,并将左右括号丢弃;如果是其他操作符,则需要将中比当前操作符优先级更高的操作符全部出,放到后缀表达式中,然后将当前操作符入。 3. 遍历完成后,将中操作符全部出并添加到后缀表达式中。 4. 最后得到的序列就是后缀表达式。 代码实现: ```python def infixToPostfix(expression): operators = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0, ')': 0} # 操作符优先级 stack = [] postfix = [] for ch in expression: if ch.isdigit(): # 直接输出数字 postfix.append(ch) else: if ch == '(': stack.append(ch) elif ch == ')': while stack and stack[-1] != '(': postfix.append(stack.pop()) if stack and stack[-1] == '(': stack.pop() else: while stack and operators[ch] <= operators[stack[-1]]: postfix.append(stack.pop()) stack.append(ch) while stack: postfix.append(stack.pop()) return postfix ``` 总结: 通过的使用,我们可以很方便地将一般算术表达式转换成后缀,并且复杂度为O(n),非常高效。实际应用中,后缀表达式可以直接计算,比中缀表达式更便于计算。因此,这种算法也有很广泛的应用场景。 ### 回答3: 在编程领域中,算术表达式的转换是一项非常重要的任务。而在数据结构实验中,我们学习到了如何将一般算术表达式转换成后缀。下面,我将从以下几个方面进行阐述。 一、算法思路 将一般算术表达式转换成后缀的算法思路是将符号按照操作优先级依次入和出,这个过程需要遵守以下几个规则: 1、如果是操作数,直接输出 2、如果是左括号,入 3、如果是右括号,弹出中所有运算符,并将它们输出,直到遇到左括号为止,但是左括号不输出 4、如果是运算符,弹出所有优先级大于或等于该运算符的顶运算符,然后将该运算符入 5、最后,将中的所有运算符依次弹出并输出,不包括左括号 、具体实现 在具体实现上,我们需要创建两个,一个用于存储运算符,一个用于输出后缀,然后遍历算术表达式,根据上述算法思路将符号依次入和出即可。具体代码实现如下: void transform(char exp[], char postfix[]) { char ch, elem; int i = 0, k = 0; Stack<char> s; while ((ch = exp[i++]) != '\0') { if (ch == '(') s.push(ch); else if (isdigit(ch) || isalpha(ch)) { postfix[k++] = ch; } else if (ch == ')') { while ((elem = s.pop()) != '(') { postfix[k++] = elem; } } else { while (!s.isEmpty() && priority(s.peek()) >= priority(ch)) { postfix[k++] = s.pop(); } s.push(ch); } } while (!s.isEmpty()) { postfix[k++] = s.pop(); } postfix[k] = '\0'; } int priority(char ch) { if (ch == '(') return 0; if (ch == '+' || ch == '-') return 1; if (ch == '*' || ch == '/') return 2; return 3; } 三、算法的应用 将一般算术表达式转换成后缀在编程中有着广泛的应用,例如表达式求值、编译器中的语法分析等。 最后,要注意的是,在转换过程中,应当考虑数据类型及精度等问题,并严格按照算法思路进行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值