中缀输入逆波兰计算器程序part1

  在看K&R的时候,里面提到了逆波兰表示法,老实说看得我迷迷糊糊的,主要是这种反人类的后缀表示法做出的计算器,一般人根本就不知道怎么输入好吧。今天看书的时候,看到了将中缀表达式转为后缀表达式的方法才恍然大悟,原来是少了这一步。这下我就知道该如何做一个可用的逆波兰计算器了。

  先简单介绍一下如何完成这步转换吧。中缀表达式就是我们习惯的表达式,比如:1+2*3 考虑运算符优先级的话后缀表达式则应该写成123*+

  写成后缀表达式的形式后我们可以利用栈轻松地解决计算问题,思路是当见到一个数时就把它推入栈;在遇到一个运算符时就从栈中弹出相应的操作数,并把运算的结果推入栈中,最后栈顶的值就是表达式的值。

  虽然后缀表达式计算起来很方便,输入的时候却十分麻烦。要写出一个人性化的计算器程序,我们首先要完成中缀表达式到后缀表达式的转换。我们用两个数组存放中缀和后缀表达式的字符。从用户获取中缀表达式的输入到相应数组中。然后遍历中缀表达式。当读到一个操作数时我们立即把它写到后缀表达式的数组中去;当读到操作符或者左括号时我们把它推入栈中(从一个空栈开始)。如果读到右括号我们将栈元素弹出并写到数组直到遇到左括号为止,注意左括号只弹出而不写到数组中去;如果再次读到操作符(+-*/),我们从栈中弹出操作符直到遇到优先级更低的元素或遇到左括号为止(注意一定是要更低,相同也不行)然后把操作符推入栈中;如果我们读完了,我们就将栈元素弹出直到该栈变为空栈为止。

  有了算法,把它转变为代码就是比较简单的事了,我们把这个转换写成一个函数,tran()。

#include <stdio.h>
#include <ctype.h>

#define MAXSIZE 100    //可输入的最大字符数以及栈的容量

char infix[MAXSIZE];    //中缀表达式数组
char postfix[MAXSIZE];    //后缀表达式数组

char stack[MAXSIZE];    //创立栈
int top = -1;
int size = 0;  //数组大小

void push(char c)  //由于本程序入栈的元素不可能溢出,这里就没有做错误检测
{
    stack[++top] = c;
}

char pop(void)
{
    if (top >= 0)
        return stack[top--];
    else
        printf("stack empty!");
}

void tran(char a[], char b[])
{
    int i,j,tmp;
    for (i = 0, j = 0; i < size; i++) {
        if (isdigit(a[i]) || a[i] == ‘.‘)
            b[j++] = a[i];
        else if (a[i] == ‘(‘) {  //考虑是单纯的括号,还是负数(-x)
            tmp = i+1;
            if (a[tmp] == ‘-‘) {  //如果是负数-x,把(-x)复制到后缀数组去
                while (a[i] != ‘)‘)
                    b[j++] = a[i++];
                b[j++] = ‘)‘;
            }
            else
                push(a[i]);
        }
        else if (a[i] == ‘+‘ || a[i] == ‘-‘) {    //如果是+或-的话
            while (top >= 0 && stack[top] != ‘(‘)  //弹出直到遇上括号或者空栈
                b[j++] = pop();
            push(a[i]);
        }
        else if (a[i] == ‘*‘ || a[i] == ‘/‘) {  //如果是*或/的话,考虑要不要弹出
            while (stack[top] == ‘*‘ || stack[top] == ‘/‘)
                b[j++] = pop();
            push(a[i]);
        }
        else if (a[i] == ‘)‘) {
            while (stack[top] != ‘(‘)
                b[j++] = pop();
            pop();
        }
    }
    while (top >= 0)  //将栈中元素全部弹出
        b[j++] = pop();
}

如此我们就完成了将用户输入的中缀表达式转变为计算机易于计算的后缀表达式,接下来就是对后缀表达式的处理了。在这方面K&R上有详细的讲解。读者若有疑惑可以作为参照。当然如果手边没有K&R,也可以阅读我的下一篇博客。

时间: 2024-11-06 23:50:10

中缀输入逆波兰计算器程序part1的相关文章

09 - 逆波兰计算器

1. 前缀表达式 (波兰表达式) 前缀表达式的运算符位于操作数之前 [举例说明] (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈:重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果 [举例说明]针对上例的前缀表达式求值步骤如下(栈顶 ? 次顶): 从右至左扫描,将6.5.4.3压入堆栈 遇到

栈实现综合计算器(中缀表达式),前缀,中缀,后缀表达式,逆波兰计算器

思路: 代码:实现多位数的运算 public class Calculator { public static void main(String[] args) { //根据前面老师思路,完成表达式的运算 String expression = "7*2*2-5+1-5+3-4"; // 15//如何处理多位数的问题? //创建两个栈,数栈,一个符号栈 ArrayStack2 numStack = new ArrayStack2(10); ArrayStack2 operStack =

逆波兰计算器

#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #define IncreSize 10 #define InitSize 10 typedef int status; typedef int Elemtype; typedef struct sStack { Elemtype *base; Elemtype *top; int StackSize; }s

c# 逆波兰式实现计算器

语文不好,不太会组织语言,希望不要太在意. 如题,先简要介绍一下什么是逆波兰式  通常我们在写数学公式的时候  就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀表达式就为ab+ 而把中缀表达式转为逆波兰式也是很容易的,以下算法摘自百度百科 简要说一下栈,栈是一种先进后出的对象集合,可以把栈理解为一个桶,先进后出  Stack   Peek()是取出但是不剔除 做比较的时候用,Pop()是出栈,Push()入栈 首先需要分配2个栈,一个作为临时存储运算符的栈

后缀表达式(逆波兰表达式)计算器

package datastructure.stack; import java.util.*; /** * <h3>netty_lecture</h3> * <p>逆波兰计算器</p> * 1+((2+3)*4)-5 ==> 1 2 3 + 4 * + 5 1 * @author : myron * @date : 2020-03-18 23:48 **/ public class PolandNotation { private static fi

数据结构——逆波兰式

很久没有关注算法和数据结构,大部分知识都已经忘记了:是时间好好回炉一下了,说实话干读数据机构这本书还是挺枯燥而且这本书原理性比较多,有一定的难度.这不刚看到逆波兰式废了好大劲才搞懂,老了... 逆波兰式 逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后) 一个表达式E的后缀形式可以如下定义: (1)如果E是一个变量或常量,则E的后缀式是E本身. (2)如果E是E1 op E2形式的表达式,这里op是如何二元操作符,则E的后缀

算法题---带加减乘除和括号的单字母变量表达式转化成逆波兰式

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define STACK_INIT_SIZE 100 #define STACK_INCREAMENT 10 #pragma warning(disable:4996)//我用的vs2015,不加这句用scanf会报错(使用了unsafe的函数) typedef struct { //栈 char *base; char *top; int stack

简单计算机——逆波兰表达式

逆波兰数:逆波兰数由两部分组成(操作数,操作符)--是波兰表达式的一种,即操作符在操作数的后面. 形式:A+B*C-D = ABC*D-; (A+B)*C-D = AB+C*D-; 既然我们知道了,后缀表达式那我们表达式是唯一的吗?我们来看一组数据: 例如:(A+B)*C-D 和 C*(A+B)-D; 很显然第二个的表达式为:C*AB+D-;虽然对最后的结果无影响,但我们需要知道逆波兰的多样性. 注意事项: 1.如果出现1+23 = 123+,该如何判断它的数值呢? 可以利用分割符来进行很好的辅

逆波兰式(后缀表达式)的计算

输入 :后缀表达式(可带浮点数) 输出:double型的计算结果 代码: #include <stdio.h> #include <stdlib.h> #include <malloc.h> #define ElemType double #define Stack_Init_Size 100 #define Increase_Size 10 #define MaxBuffer 10 typedef struct sqStack { ElemType *top; Ele