鱼C论坛

 找回密码
 立即注册
查看: 4341|回复: 14

关于中缀转后缀与逆波兰合二为一的代码怎么写

[复制链接]
发表于 2020-3-2 14:38:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
【问题描述】表达式求值,栈的应用,给定一个以“#”作为结束符的算式,求出算式的结果

【输入形式】以“#”结尾的表达式,运算数为正数。每个表达式占一行。

【输出形式】输出表达式运算的结果,输出数据请保留2位小数。

【样例输入】

4+2.53*3-10/5#

3*(7.91-2)#

2.4*3.6/2#

【样例输出】

9.59

17.73

4.32
主要是怎么输入小数也能满足?求求大佬们,已经快被这题逼疯了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-2 15:02:03 | 显示全部楼层
“主要是怎么输入小数也能满足?”
是什么意思?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-2 19:23:39 | 显示全部楼层
人造人 发表于 2020-3-2 15:02
“主要是怎么输入小数也能满足?”
是什么意思?

就是我写的时候,输入的中缀表达式里面的数字只能是整数,比如说我可以输入1+2,但是我如果想输入1.2+3.3这样子的话就不会了,现在我想让我的输入里面既可以输入运算符像加减乘除,还可以是数字包括整数和小数,最终也能计算出答案
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-2 19:50:39 | 显示全部楼层
F0T1024 发表于 2020-3-2 19:23
就是我写的时候,输入的中缀表达式里面的数字只能是整数,比如说我可以输入1+2,但是我如果想输入1.2+3.3 ...

把你的代码贴出来
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-3 09:06:37 | 显示全部楼层
我是按照小甲鱼在数据结构与算法的视频里面讲的来写的两段代码
第一段是中缀转后缀的:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define MAXSIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 10//最大缓冲区

typedef char ElemType;
typedef struct
{
        ElemType* base;
        ElemType* top;
        int StackSize;
}sqStack;

void InitStack(sqStack* S)
{
        S->base = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
        //或S.base = (int*)malloc(MAXSIZE*sizeof(int));
        if (!S->base)
                exit(0);//存储分配失败

        S->top = S->base;//栈顶指针等于栈底指针
        S->StackSize = MAXSIZE;
}

void Push(sqStack* S, ElemType e)
{
        if ((S->top) - (S->base) >= (S->StackSize))//栈满或超出
        {
                S->base = (ElemType *)realloc(S->base, (S->StackSize + STACKINCREMENT) * sizeof(ElemType));//增加空间
                if (!S->base)
                        exit(0);

                S->top = (S->base) + (S->StackSize);
                S->StackSize = S->StackSize + STACKINCREMENT;
        }

        //*S->top++ = e;
        *(S->top) = e;
        S->top++;
}


void Pop(sqStack* S, ElemType* e)
{
        if (S->top == S->base)
                return;
        /*--S->top;
        *e = *(S->top);*/
        *e = *--(S->top);//将栈顶元素弹出并修改栈顶指针
}

int StackLen(sqStack s)
{
        return (s.top - s.base);
}

int main(void)
{
        sqStack s;
        char c, e;

        InitStack(&s);

        printf("请输入中缀表达式,以#作为结束标志:");
        scanf("%c", &c);

        while (c != '#')
        {
                while(c >= '0' && c <= '9')
                {
                        printf("%c", c);
                        scanf("%c",&c);
                        if(c<'0' || c>'9')
            {
                printf(" ");
            }
                }
                if (')' == c)
                {
                        Pop(&s,&e);
                        while ('(' != e)
                        {
                                printf("%c ", e);
                                Pop(&s, &e);
                        }
                }
                else if ('+' == c || '-' == c)
                {
                        if (!StackLen(s))//为空
                        {
                                Push(&s, c);
                        }
                        else
                        {
                                do
                                {
                                        Pop(&s, &e);
                                        if ('(' == e)
                                        {
                                                Push(&s, e);
                                        }
                                        else
                                        {
                                                printf("%c ", e);
                                        }
                                } while (StackLen(s) && '(' != e );
                                Push(&s, c);
                        }
                }
                else if ('*' == c || '/' == c || '(' == c)
                {
                        Push(&s, c);
                }
                else if('#' == c)
        {
            break;
        }
                else
                {
                        printf("\n出错:输入格式错误!\n");
                        return -1;
                }

                scanf("%c", &c);
        }

        while (StackLen(s))//不为空
        {
                Pop(&s, &e);
                printf("%c ", e);
        }
        //system("pause");
        return 0;
}

第二段是逆波兰:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>


#define MAXSIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 10//最大缓冲区

typedef double ElemType;
typedef struct
{
        ElemType* base;
        ElemType* top;
        int StackSize;
}sqStack;

void InitStack(sqStack* S)
{
        S->base = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
        //或S.base = (int*)malloc(MAXSIZE*sizeof(int));
        if (!S->base)
                exit(0);//存储分配失败

        S->top = S->base;//栈顶指针等于栈底指针
        S->StackSize = MAXSIZE;
}

void Push(sqStack* S, ElemType e)
{
        if (S->top - S->base >= S->StackSize)//栈满或超出
        {
                S->base = (ElemType*)realloc(S->base, (S->StackSize + STACKINCREMENT) * sizeof(ElemType));//增加空间
                if (!S->base)
                        exit(0);

                S->top = S->base + S->StackSize;
                S->StackSize = S->StackSize + STACKINCREMENT;
        }

        //*S->top++ = e;
        *(S->top) = e;
        S->top++;
}

void Pop(sqStack* S, ElemType* e)
{
        if (S->top == S->base)
                return;
        /*--S->top;
        *e = *(S->top);*/
        *e = *--(S->top);//将栈顶元素弹出并修改栈顶指针
}

int StackLen(sqStack S)
{
        return (S.top - S.base);
}

int main(void)
{
        sqStack s;
        char c;
        double d, e;
        char str[MAXBUFFER];
        int i = 0;

        InitStack(&s);

        printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志:\n");
        scanf("%c",&c);

        while (c != '#')
        {
                while(isdigit(c) || c == '.')//用于过滤数字,头文件为ctype.h
                {
                        str[i++] = c;
                        str[i] = '\0';
                        if (i >= 10)
                        {
                                printf("出错:输入的单个数据过大\n");
                                return -1;
                        }
                        scanf("%c",&c);
                        if (c == ' ')
                        {
                                d = atof(str);//将字符串转化为浮点数,返回值为double型,头文件为stdlib.h
                                Push(&s, d);
                                i = 0;
                                break;
                        }
                }
                switch (c)
                {
                case '+':
                        Pop(&s, &e);
                        Pop(&s, &d);
                        Push(&s, d + e);
                        break;
                case '-':
                        Pop(&s, &e);
                        Pop(&s, &d);
                        Push(&s, d - e);
                        break;
                case '*':
                        Pop(&s, &e);
                        Pop(&s, &d);
                        Push(&s, d * e);
                        break;
                case '/':
                        Pop(&s, &e);
                        Pop(&s, &d);
                        if (e != 0)
                        {
                                Push(&s, d / e);
                        }
                        else
                        {
                                printf("\n出错:除数为零! \n");
                                return -1;
                        }
                        break;

                }
                scanf("%c",&c);
        }

        Pop(&s, &d);
        printf("%f",d);

        system("pause");
        return 0;
}
现在我的问题有两个,一个是怎么把这两段代码合二为一,一个是改变我的输入形式,变成我之前的要求
感谢!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-3 16:35:41 | 显示全部楼层
F0T1024 发表于 2020-3-3 09:06
我是按照小甲鱼在数据结构与算法的视频里面讲的来写的两段代码
第一段是中缀转后缀的:
#include

你直接在你发的帖子下面回复,我根本就没有收到通知
这也是我点进来才看到
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-4 01:36:52 | 显示全部楼层
我仔细想了想,要把这两个程序合并成一个,并且实现你的需求
需要对这两个代码做大量的修改,我觉得这还不如重写一个
我估计修改这两个代码到完成你的需求后,这个代码就和重写了差不多了,所以我不想修改这个代码
我试试重写一个吧,可以吧?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-5 09:58:23 | 显示全部楼层
人造人 发表于 2020-3-4 01:36
我仔细想了想,要把这两个程序合并成一个,并且实现你的需求
需要对这两个代码做大量的修改,我觉得这还不 ...

非常感谢大佬
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-5 17:40:51 | 显示全部楼层
postfix_expression.tar.zip (25.21 KB, 下载次数: 29)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-6 15:52:56 | 显示全部楼层

大佬,我在测试数据时出现了异常,显示在stack.c文件中
stack_elem_t stack_top(stack_t s)
{
    return s->top->data;//这一行显示有未经处理的异常,读取位置发生冲突
}
不知道该怎么解决
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-6 17:36:22 | 显示全部楼层
F0T1024 发表于 2020-3-6 15:52
大佬,我在测试数据时出现了异常,显示在stack.c文件中
stack_elem_t stack_top(stack_t s)
{

qq: 1440332527
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-6 17:37:31 | 显示全部楼层
F0T1024 发表于 2020-3-6 15:52
大佬,我在测试数据时出现了异常,显示在stack.c文件中
stack_elem_t stack_top(stack_t s)
{

我猜可能是因为在栈空的时候访问了栈顶元素,^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-10 15:24:24 | 显示全部楼层
使用了类模板, C++
  1. #ifndef STACK_H
  2. #define STACK_H

  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <stack>
  6. #define MAXSIZE 20
  7. #define STACKINCREMENT 10

  8. // define element type

  9. //typedef double ElemType;
  10. template<class T>
  11. struct Node
  12. {
  13.     T *base;
  14.     T *top;
  15.     int stackSize;
  16. };


  17. template<class T>
  18. class Stack
  19. {

  20. public:
  21.     Stack(struct Node<T> *S)
  22.     {
  23.         this->S = S;
  24.         initStack();
  25.     }
  26.     Stack(){}

  27.     void initStack()
  28.     {
  29.         S->base = (T *)malloc(MAXSIZE *sizeof(T));
  30.         if(!S->base)
  31.         {
  32.             printf("alloc failure\n");
  33.             exit(-1);
  34.         }
  35.         S->top = S->base;
  36.         S->stackSize = MAXSIZE;
  37.     }
  38.     void initStack(struct Node<T>*S)
  39.     {
  40.         this->S = S;
  41.         initStack();
  42.     }

  43.     void push(T e)
  44.     {
  45.         // stack is full
  46.         if((S->top) - (S->base) >= (S->stackSize))
  47.         {
  48.             S->base = (T*)realloc(S->base, (S->stackSize + STACKINCREMENT)*sizeof(T));
  49.             if(!S->base)
  50.             {
  51.                 printf("realloc failure\n");
  52.                 exit(-1);
  53.             }
  54.             S->top = (S->base) +(S->stackSize);
  55.             S->stackSize = S->stackSize + STACKINCREMENT;
  56.         }
  57.         *(S->top) = e;
  58.         S->top++;
  59.     }
  60.     void pop(T *e)
  61.     {
  62.         if(S->top == S->base)
  63.         {
  64.             printf("stack is empty\n");
  65.             return;
  66.         }
  67.         // top always point is empty, so must S->top--;
  68.         *e = *--(S->top);
  69.     }
  70.     int stackLen(void)
  71.     {
  72.         return (S->top-S->base);
  73.     }

  74. private:
  75.     struct Node<T> *S;
  76. };

  77. #endif // STACK_H
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-10 15:24:59 | 显示全部楼层
逆波兰实现
  1. #ifndef POLANDOPERATOR_H
  2. #define POLANDOPERATOR_H
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include "stack.h"

  7. #define MAX_BUFF_VOLUMN 16

  8. template<class T>
  9. class PolandOperator
  10. {
  11. public:
  12.     PolandOperator(Stack<T> *S)
  13.     {
  14.         this->stack = S;
  15.     }

  16.     T getResult(char *buff)
  17.     {
  18.         char str[MAX_BUFF_VOLUMN] = {0};
  19.         char *p = buff;
  20.         int i = 0;
  21.         T d, e;
  22.         while(*p != '\0')
  23.         {
  24.             // filter digit
  25.             while(isdigit(*p) || *p == '.')
  26.             {
  27.                 str[i++] = *p;
  28.                 // use to end
  29.                 str[i] = '\0';
  30.                 if(i >=  MAX_BUFF_VOLUMN)
  31.                 {
  32.                     printf("error, this number is too big\n");
  33.                     return -1;
  34.                 }
  35.                 p++;
  36.                 //space
  37.                 if(*p == 32)
  38.                 {
  39.                     d = atof(str);
  40.                     stack->push(d);
  41.                     i = 0;
  42.                     break;
  43.                 }
  44.             }
  45.             switch (*p) {
  46.             case '+':
  47.                 stack->pop(&e);
  48.                 stack->pop(&d);
  49.                 stack->push(d+e);
  50.                 break;
  51.             case '-':
  52.                 stack->pop(&e);
  53.                 stack->pop(&d);
  54.                 stack->push(d-e);
  55.                 break;
  56.             case '*':
  57.                 stack->pop(&e);
  58.                 stack->pop(&d);
  59.                 stack->push(d*e);
  60.                 break;
  61.             case '/':
  62.                 stack->pop(&e);
  63.                 stack->pop(&d);
  64.                 if(e != 0)
  65.                 {
  66.                     stack->push(d/e);
  67.                 }
  68.                 else
  69.                 {
  70.                     printf("\n error, zero\n");
  71.                     return -1;
  72.                 }
  73.                 break;
  74.             }
  75.             p++;
  76.         }
  77.         stack->pop(&d);
  78.         return d;
  79.     }

  80.     void getPolandExpression(char *buff, char *ret)
  81.     {
  82.         char*p = buff;
  83.         char e;
  84.         while(*p != '\0')
  85.         {
  86.             while((*p >= '0' && *p <= '9') || *p == '.')
  87.             {
  88.                 *ret++ = *p++;
  89.             }
  90.             *ret = 32;
  91.             ret++;
  92.             if(')' == *p)
  93.             {
  94.                 stack->pop(&e);
  95.                 while('(' != e)
  96.                 {
  97.                     *ret++ = e;
  98.                     *ret++ = 32;
  99.                     stack->pop(&e);
  100.                 }
  101.             }
  102.             else if('+' == *p || '-' == *p)
  103.             {
  104.                 if(!stack->stackLen())
  105.                 {
  106.                     stack->push(*p);
  107.                 }
  108.                 else
  109.                 {
  110.                     do
  111.                     {
  112.                         stack->pop(&e);
  113.                         if('(' == e)
  114.                         {
  115.                             stack->push(e);
  116.                         }
  117.                         else
  118.                         {
  119.                             *ret++ = e;
  120.                             *ret++ = 32;
  121.                         }
  122.                     }while(stack->stackLen() && '(' != e);
  123.                     stack->push(*p);
  124.                 }
  125.             }
  126.             else if('*' == *p || '/' == *p || '(' == *p)
  127.             {
  128.                 stack->push(*p);
  129.             }
  130.             p++;
  131.         }
  132.         while (stack->stackLen()) {
  133.             stack->pop(&e);
  134.             *ret++ = e;
  135.             *ret++ = 32;
  136.         }
  137.         *ret = '\0';
  138.     }

  139. private:
  140.     Stack<T> *stack;
  141. };

  142. #endif // POLANDOPERATOR_H
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-10 15:25:51 | 显示全部楼层
本帖最后由 代号-K 于 2020-3-11 18:51 编辑

实现方法

  1. typedef double Element;
  2. typedef char ConvertEle;
  3. //convert polandExpression
  4.     char retArray[64] = {0};
  5.     char buff[32] = "2.4*3.6/2";
  6.     struct Node<ConvertEle> s1;
  7.     Stack<ConvertEle> stack1(&s1);
  8.     PolandOperator<ConvertEle> pld1(&stack1);
  9.     pld1.getPolandExpression(buff, retArray);
  10.     char *p = retArray;
  11.     while(*p != '\0')
  12.     {
  13.         printf("%c",*p);
  14.         p++;
  15.     }
  16.     printf("\n");

  17.     //computer polandExpression
  18.     struct Node<Element> s;
  19.     Stack<Element> stack(&s);
  20.     PolandOperator<Element> pld(&stack);
  21.     double ret = pld.getResult(retArray);
  22.     printf("%f\n", ret);
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 16:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表