中缀表达式转后缀表达式并输出混合运算结果(C,C++)

        在大一下学期的学习中,离散数学学习了后缀表达式,数据结构也学习了栈的使用,在书本中看到了关于混合运算的大致介绍,所以有了想写混合运算的代码,口头运算简单但是转成代码形式时就发现困难很大了。在代码实现过程中也借鉴了不少其他大佬的方法和思路。大部分代码用的是C语言,部分代码用的是C++(编译时要创建C++文件,使用C++的原因是因为C++中提供了很多好用的函数,大大简化了代码过程),不要害怕没学过c++,代码部分使用了C++的地方我都标注了并进行了注释说明。

代码思路(算法):

首先:读入的中缀表达式是正确的。
1.当读到操作数时,立即输出。
2.遇到操作符时不立即输出,而是放入栈中。

3.‘(’的优先级最高,其余符号同四则运算的法则。

4.读入一个操作符时,弹出栈顶元素直至发现优先级更低的元素为止。除非是在处理一个‘)’,否则绝不从栈中弹出‘(’。

5.遇到‘)’,将栈顶元素弹出并输出直到遇到相应的‘(’,但该‘(’只弹出,不输出。
读入输入的末尾时,若栈非空,依此弹出并输出所有栈元素

6.将后缀表达式中的数字部分转换成十进制存储在字符串中

7.计算后缀表达式字符串,并输出结果

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
#define MAX 1000
char *change(char data[]);
bool compare(char a, char b);
int priority(char a);
// (40  括号在算术上优先级最高,但是在 栈的优先级是最低的,为了其他符号正常入栈 优先级最低
//  /* 优先级最高 , +- 优先级最低

// true 的情况 只有a 是*/ b是+-的情况
int priority(char a)
{
    if (a == '(')
    {
        return 0;
    }
    else if (a == '+' || a == '-')
    {
        return 1;
    }
    else
    {
        return 2;
    }
}
// 比较优先级 ,a 的优先级比b 高,就返回true
bool compare(char a, char b)
{
    return priority(a) > priority(b);
}

void show(char data[],int length)
{
    printf("输出状态\t");
    for (int i=0; i<length; i++)
    {
        printf("%c",data[i]);
    }
}

// 中缀表达式--> 后缀表达式(逆波兰表达式)
// 返回字符串数组
char *change(char data[])
{
    int length = strlen(data);
    char *hou = (char *)malloc(length * sizeof(char));
    stack<char> s;
    int index = 0; // 后缀表达式的长度

    // 1. 判断类型
    for (int i = 0; i < length; i++)
    {
        // 如果是运算数,直接输出,
        if (data[i] >= '0' && data[i] <= '9')
        {
            hou[index] = data[i];
            index++;
        }
        else if (data[i] == ')')
        {
            // 不断的弹出栈元素并输出直到遇到左括号结束
            while (!s.empty() && s.top() != '(')
            {
                hou[index] = s.top();//栈s中的栈顶元素
                index++;
                s.pop();//c++中输出栈s的栈顶函数
            }
            s.pop(); //退出左括号
        }
        else if(data[i]=='(')
        {
            s.push(data[i]);
        }
        else
        {
            // 表示 运算符优先级小于等于 栈顶元素,就退出栈顶元素,并输出
            // 包含情况data[i]='(',compare 返回false

            while (!s.empty() && !compare(data[i], s.top()))//s.empty()用于判断栈s是否为空
            {
                printf("进行比较%c %c %d\n",data[i],s.top(),compare(data[i], s.top()));
                hou[index] = s.top();
                index++;
                s.pop();
            }
            s.push(data[i]);
        }
        show(hou,index);
        printf("\t 参加运算的符号 is %c  \t  栈的元素个数 is %d \n", data[i], s.size());
    }

    // 输出栈内所有元素
    while (!s.empty())
    {
        hou[index] = s.top();
        index++;
        s.pop();
    }
    // 打印最后的结果
    show(hou,index);
    return hou;
}
char Switch(char a[])//将字符串中数字部分转换为十进制存储
{
    int lenth=strlen(a);
    int i;
    for(i=0; i<lenth; i++)
        if(a[i]>=48&&a[i]<=57)//数字在字符串中存储的数值不同
            a[i]=a[i]-48;
}
char Count(char a[])//利用后缀表达式计算混合运算
{
    int lenth=strlen(a);
    int num;
    int i,j,k;
    for(i=0; i<lenth; i++)//遍历后缀表达式的字符串
    {
        if(a[i]=='/')
        {
            a[i-2]=a[i-2]/a[i-1];
            for(j=i-1,k=i+1; j<lenth; j++,k++)//进行计算后要将字符串前移
                a[j]=a[k];
            i=-1;//让循环从头进行
            lenth--;//计算后长度缩减
            continue;
        }
        else if(a[i]=='*')
        {
            a[i-2]=(a[i-2])*(a[i-1]);
            for(j=i-1,k=i+1; j<lenth; j++,k++)
                a[j]=a[k];
            i=-1;
            lenth--;
            continue;
        }
        else if(a[i]=='+')
        {
            a[i-2]=(a[i-2])+(a[i-1]);
            for(j=i-1,k=i+1; j<lenth; j++,k++)
                a[j]=a[k];
            i=-1;
            lenth--;
            continue;
        }
        else if(a[i]=='-')
        {
            a[i-2]=(a[i-2])-(a[i-1]);
            for(j=i-1,k=i+1; j<lenth; j++,k++)
            {
                a[j]=a[k];
            }
            i=-1;
            lenth--;
            continue;
        }
        else//遇到数字部分跳过
            continue;
    }
    return a[0];
}

// 后缀表达式的计算
int main(int argc, char const *argv[])
{
    // 样例 2*(9+6/3-5)+4
    // 结果 2963/+5-*4+
    ///char s[MAX] = "2*(9+6/3-5)+4";
    char s[MAX];
    printf("请输入正确的表达式(英文状态):");
    scanf("%s",s);
    char *result;
    result = change(s);
    Switch(result);
    printf("\n%s=",s);
    printf("%d\n",Count(result));
    return 0;
}

 这是运行截图,该代码还是有许多缺陷,如输入的数值只能是0-9,计算的结果也只能是整数,若要输出小数部分还需对结果输出部分进行微调。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值