用栈实现计算器的举例阐述

注意:代码中的注释有些错误,此文仅供参考;代码是从QT上截取的部分,不能直接运行,需用QT Create。
需要结合代码看:

举例:(2+1*3)

第一次:符号栈(
第二次:数字栈2
第三次:符号栈+;因为栈顶为(,自己不为)
第四次:数字栈1
第五次:符号栈*;因为自己比栈顶+的权值大
第六次:数字栈3
第七次:符号栈):因为自己比栈顶*的权值大

出栈
第一次:出栈)
第二次:因为*,执行13,弹出,弹出1、3,压入3
第二次:因为+,执行2+3,弹出+,弹出2、3,压入5
第三次:弹出(
执行完毕,返回5

(2*1+3)

第一次:符号栈(
第二次:数字栈2
第三次:符号栈*;因为栈顶为(,自己不为)
第四次:数字栈1
第五次:前面条件均不符合:+的权重比小,且栈顶不为(,符号栈不空
执行出栈 因为栈顶此时的符号位为
,所以执行操作,执行21,压入2;
再次返回while判断符号+,因为栈顶为(,自己不为),
所以符号栈+
第六次:数字栈3
第七次:)导致前面不满足条件,执行出栈操作,因为符号),出栈)
第八次:因为+,执行2+3,弹出2、3,压入5,弹出+
第九次:因为(,出栈(
执行完毕,返回5

代码:

void Widget::on_equalButton_clicked()
{

    int signFlag=0;
    if((*express.begin())=='-')                           //在运算之前,把最前面的符号位给去掉,并进行记录保存
    {
        signFlag=1;
        express.remove(0,1);
    }
    else if((*express.begin())=='+')
    {
        signFlag=0;
        express.remove(0,1);
    }
   // ui->inputLineEdit->setText(express);


    //以(1+2)为例
    if(express.size()!=0 && (*express.begin()!=')') && checkError(express))    //核实所给的计算式
    {
       QByteArray ba;
       ba.append(express);      //把QString转换成QByteArray
       char *str = ba.data();   //把QByteArray转换成char *
       QStack<int> s_num, s_opt;                                                //定义一个先进后出的数据类型    即为栈
       int i = 0, tmp = 0, num1, num2;                                          //i计数

       while (str[i] != '\0' || s_opt.empty() != true)                          //判断是否为空
       {
           if (str[i] >= '0' && str[i] <= '9')    //运算数
           {
               tmp = tmp * 10 + str[i] - '0';                                   //数字位放在一起
               i++;
               if (str[i] > '9' || str[i] < '0')   //运算符
               {
                   s_num.push(tmp);                                             //将之前的合出来的数字压入栈中
                   tmp = 0;
               }
           }
           else                                  //运算符
           {
               //运算符进栈
               if (s_opt.empty() == true || Priority(str[i]) > Priority(s_opt.top()) ||
                   (s_opt.top() == '(' && str[i] != ')'))
               {
                   s_opt.push(str[i]);                                           //将符号位压入栈中
                   i++;                                                          //移到下一位
                   continue;                                                     //直到符号栈中为空,优先级没有栈顶的符号位高,且栈顶不为(现在的符号为不为);
                   //接着跳过此if操作
               }

               //出栈不计算
               if (s_opt.top() == '(' && str[i] == ')')                         //如果符号位栈顶为(,且现在的符号位为),则进行符号位出栈操作,即出现()现象
               {
                   s_opt.pop();
                   i++;                                                         //移到下一位
                   continue;                                                    //继续while循环
               }                                                                                   //执行第一次while,符号栈压入一个(
                                                                                                   //第二次数字栈压入一个1
                                                                                                    //第三次,符号栈压入一个+,因为没有(的权值大
                                                                                                    //第四次,数字栈压入一个2
                                                                                                    //第五次,符号栈压入一个),
                                                                                                    //开始进行出栈操作
                                                                                                    //目前,数字栈有 1 2;符号栈有( +);

               //出栈计算
               if ((str[i] == ')' && s_opt.top() != '(') || Priority(str[i]) <= Priority(s_opt.top()) ||
               (str[i] == '\0' && s_opt.empty() != true))
               {
                   char opt = s_opt.top();                                   //符号位位栈顶的符号位
                   s_opt.pop();                                              //弹出栈顶的符号位
                   switch(opt)
                   {
                       case '+':
                           num1 = s_num.top();
                           s_num.pop();
                           num2 = s_num.top();
                           s_num.pop();
                           s_num.push(num1 + num2);
                           break;
                       case '-':
                           num1 = s_num.top();
                           s_num.pop();
                           num2 = s_num.top();
                           s_num.pop();
                           s_num.push(num2 - num1);
                           break;
                       case '*':
                           num1 = s_num.top();
                           s_num.pop();
                           num2 = s_num.top();
                           s_num.pop();
                           s_num.push(num1 * num2);
                           break;
                       case '/':
                           num1 = s_num.top();
                           s_num.pop();
                           num2 = s_num.top();
                           s_num.pop();
                           s_num.push(num2 / num1);
                           break;                              //第一次,将)弹出
                   }
                   continue;                                 //第二次case,因为之前弹出来的是+,那么将弹出两个数字位1和2,并压入3;对它们进行相加运算并弹出。第二次符号位
                                                             //(,将其弹出,此时只有数字位不为空,为3
               }

           }

       }

       if(signFlag == 1)
       {
           express = "-" + QString::number(s_num.top());
           ui->inputLineEdit->setText(express);
       }
       else
       {
           ui->inputLineEdit->setText(QString::number(s_num.top()));
       }
      //ui->inputLineEdit->setText(num);

    }
    else
    {
        QString tmpexpress="error input!";
        ui->inputLineEdit->setText(tmpexpress);
    }
}
在C语言中,使用栈(Stack)实现计算器的主要目的是演示递归调用和表达式求值的基本算法,特别是后缀表达式(也称为逆波兰表示法,RPN)。这种方法不需要复杂的符号表或优先级规则,非常适合教学和理解递归。 以下是一个简单的栈实现后缀表达式计算器的例子: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义数据结构 typedef struct { double num; } Number; typedef struct { char operator; Number left, right; } Expression; // 函数声明 void push(Number stack[], int &top); double pop(Number stack[], int &top); char pop_operator(Number stack[], int &top); // 后缀表达式处理函数 double evaluate_postfix(char* exp); int main() { char expression[100]; printf("Enter an expression in postfix notation: "); fgets(expression, sizeof(expression), stdin); expression[strcspn(expression, "\n")] = '\0'; // 去除末尾的换行符 double result = evaluate_postfix(expression); printf("Result: %.2lf\n", result); return 0; } // 栈操作 void push(Number stack[], int &top) { Number n = {atof(stack[top].num)}; top++; stack[top] = n; } double pop(Number stack[], int &top) { top--; return stack[top].num; } char pop_operator(Number stack[], int &top) { top--; return stack[top].operator; } // 表达式求值 double evaluate_postfix(char* exp) { int top = 0; Number stack[100]; // 栈大小可调整 stack = {'0'}; // 初始化栈顶为0 for (int i = 0; exp[i] != '\0'; i++) { if (isdigit(exp[i])) { push(stack, top); // 如果是数字,压入栈 } else { double right = pop(stack, top); double left = pop(stack, top); switch (exp[i]) { case '+': stack[top++] = {left + right}; break; case '- right}; break; case '*': stack[top++] = {left * right}; break; case '/': stack[top++] = {left / right}; break; // 添加其他运算符处理 } } } return pop(stack, top); // 返回结果 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值