前缀变后缀

原创 2013年12月04日 12:33:39


 

一、实验目的

1. 掌握栈的数据结构与基本操作(链表和数组实现栈)

2. 了解什么是中缀表达式和后缀表达(逆波兰表达式)

3. 掌握中缀表达式转为后缀表达式的方法

4. 掌握使用栈结构计算后缀表达式

5. 提高利用计算机分析和解决复杂实际问题的能力

6. 锻炼自己的编程能力和查阅资料的能力

二、实验要求及实验环境

实验要求:

1.从键盘输入任意一个语法正确的(中缀)表达式,显示并保存该表达式。

 

2.利用栈结构,把上述(中缀)表达式转换成后缀表达式,并显示栈的状态变化过程和所得到的后缀表达式。

 

3.利用栈结构,对上述后缀表达式进行求值,并显示栈的状态变化过程和最终结果。

实验环境:

1.Windows 7操作系统

 

2.GC++ 编译器

 

 

三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系)

struct node{            //定义栈--链表实现

    float num; //存放操作数

    char data; //存放操作符

    struct node *next;

};

函数列表:

 

Stack CreateStack( void )          //创建一个带表头的空栈

int IsEmpty( Stack s )             //判断是否为空栈

void MakeEmpty( Stack s )        //将栈变空

Stack Transform( Stack s )         //输入和转换

void Pop(Stack s)   //弹出栈顶

void Calculate(Stack s)            //计算并输出结果

//定义全局变量

char string1[100];         //存储中缀表达式

char string2[100];         //存储后缀表达式

char flag[100];             

五、系统不足与经验体会

1.(1)不能计算(-(12+23))*2这样的算式。

(2)使用栈时比较浪费存储空间,最好使用联合体union来写能够节省一半的空间。

(3)将字符串转化为实数时调用了atof函数,没有自己编写函数。

2.(1)在编写代码时,要思路清晰,设计要严谨,考虑问题要全面。

(2)要学会查阅资料,上网查询时它不一定正确,要学会            判断正误。

(3)多与别人讨论问题并且交换思路,不能自己空想,很浪费时间和精力。

 

六、附录:源代码(带注释)

 

/********************************************/

/* 中缀表达式变为后缀表达式并计算输入结果   */

/* 1120310510 高天峰 计科五班               */

/*日期: 2013 .10. 25                       */

/*修改: 10 .29                             */

/********************************************/

 

#include<stdio.h>

#include<malloc.h>

#include<string.h>

#include<stdlib.h>

//定义全局变量

char string1[100];      //存储中缀表达式

char string2[100];      //存储后缀表达式

char flag[100];         //设置标志符号

int j=0;

 

 

struct node{            //定义栈--链表实现

    float num;

    char data;

    struct node *next;

};

typedef struct node * Stack;

 

Stack CreateStack( void )           //创建一个带表头的空栈

{

    Stack s;

    s = malloc( sizeof ( struct node ) );

    if ( s == NULL )

    {

        printf("申请内存失败!!程序已退出!!\n");

        exit(1);

    }

    s->num = 0;

    s->data = '@';                  //  设置数组标识符

    s->next = NULL;

    return s;

}

 

int IsEmpty( Stack s )              //判断是否为空栈

{

    return s -> next == NULL;

}

void Pop(Stack s)

{

   Stack stk;

   if(s->next){

    stk=s->next;

    s->next=stk->next;

    free(stk);

   }

}

 

void MakeEmpty( Stack s )            //将栈变空

{

    if ( s == NULL )

    {

        printf("请先使用CreateStack函数!!\n");

    }

    else

        while( !IsEmpty ( s ) )

            Pop ( s );

}

 

Stack Transform( Stack s )                 //输入中缀表达式并输出后缀表达式

{

    Stack p,top;

int i;

int m;

char a;

top=s;

gets(string1);

m=strlen(string1);                  //数组长度

for(i=0;i<m;i++)

    {

         if(string1[i] == '(' && string1[i+1]=='-')

           {

               string2[j] = string1[i+1];

                flag[j] = 1; //设置负数标志位

                j++;

                i=i+2;

                while ( string1[i] != ')' )

                {

 

                    string2[j]=string1[i];

                    flag[j]=0;

                    j++;

                    i++;

                }

 

           }

           else{

                    if ( ('0' <= string1[i] && string1[i] <= '9' )|| string1[i] == '.')

                    {

                        string2[j]=string1[i];

                        flag[j]=0;

                        j++;

                    }

                    else {

                        a=string1[i];

                        switch(a)

                        {

                            case '(':{

                                     p=malloc(sizeof(struct node));

                                     p->data=a;

                                     p->next=top;

                                     top=p;

                                     printf("将‘(’入栈。\n");

                                     break;

                                     }

                            case '*':

                            case '/':

                                {

                                   string2[j]=' ';flag[j]=0;

                                   j++;

                                    if((top->data=='*')||(top->data=='/'))

                                    {

                                        printf("将‘%c’出栈。\n",top->data);

                                        string2[j]=top->data;//比其高,现将栈顶运算符出栈,再进栈。

                                        flag[j]=0;

                                        j++;

                                        top->data=a;

                                        printf("将‘%c’入栈。\n",top->data);

                                        break;

                                    }

                                    else

                                    {

                                        p=malloc(sizeof(struct node));//否,直接进栈

                                        p->data=a;

                                        p->next=top;

                                        top=p;

                                        printf("将‘%c’入栈。\n",a);

                                        break;

                                    }

 

                                }

                            case '+':

                            case '-':

                                {

                                    string2[j]=' ';flag[j]=0;

                                    j++;

                                    if(top->data=='+'||top->data=='-'||top->data=='*'||top->data=='/')

                                    {

                                        printf("将‘%c’出栈。\n",top->data);

                                        string2[j]=top->data;

                                        flag[j]=0;

                                        j++;

                                        if(top->next->data=='+'||top->next->data=='-')

                                        {

                                            top=top->next;

                                            string2[j]=top->data;

                                            flag[j]=0;

                                            printf("将‘%c’出栈。\n",top->data);

                                        }

                                        top->data=a;

                                        printf("将‘%c’入栈。\n",top->data);

                                        j++;

                                    }

                                    else{

                                        p=malloc(sizeof(struct node));//否,直接进栈

                                        p->data=a;

                                        p->next=top;

                                        top=p;

                                        printf("将‘%c’入栈。\n",top->data);

                                    }

                                    break;

                                }

                            case ')':

                                {

                                    while(top->data != '(')

                                            {

                                                string2[j]=top->data;

                                                printf("将‘%c’出栈。\n",top->data);

                                                flag[j]=0;

                                                j++;

                                                p=top;

                                                top = top->next;

                                                free(p);

                                            }

                                    p=top;

                                    printf("将‘%c’出栈,并删除。\n",top->data);

                                    top = top->next;

                                    free(p);

                                }

                        }

                    }

    }}

    while(top->data!='@')  //判断标志位

    {

        string2[j]=top->data;

        printf("将‘%c’出栈。\n",top->data);

        flag[j]=0;

        j++;

        p=top;

        top=top->next;

        free(p);

    }

    string2[j]='#'; //设置最后标志位

    printf("转化后的后缀表达式为:%s\n",string2);

return top;

}

 

void Calculate(Stack s)             //利用后最表达式来计算并输出结果

{

    int i,n;

    float q,x,y,z;

    char a;

    Stack top,p;

    top = s;

    for( i=0;i <= j; i++)

    {

        if(flag[i]==1) //判断是否为负数

        {

                q = atof( &string2[i] ); //将字符串转化为浮点数

                for(n=i+1;(string2[n]>='0'&&string2[n]<='9')||string2[n]=='.';n++){}

                p=malloc(sizeof(struct node));

                p->num = q;

                p->next = top;

                top=p;

                printf("将‘%f’入栈。\n",top->num);

                i=n-1;

        }

        else{ //不是负数时

                if(string2[i] >= '0'&& string2[i] <= '9')

                {

                    q = atof( &string2[i]);         //将字符串转化为浮点数

                    for(n=i;(string2[n]>='0'&&string2[n]<='9')||string2[n]=='.';n++){}

                    p=malloc(sizeof(struct node));

                    p->num = q;

                    p->next = top;

                    top=p;

                    printf("将‘%f’入栈。\n",top->num);

                    i=n-1;

                }

                else

                {

                        if(string2[i] == '#')

                        printf("后缀表达式计算结果是:%f\n",top->num);

                    else

                    {

                        if(string2[i]==' '){}

                        else{

                        y=top->num;printf("将‘%f’出栈。\n",top->num);p=top;top=top->next;free(p);

                        x=top->num;printf("将‘%f’出栈。\n",top->num);p=top;top=top->next;free(p);

                        a = string2[i];

                        switch(a)

                        {

                            case '+':{

                                    z=x+y;

                                   break;}

                            case '-':{

                                    z=x-y;

                                  break;}

                            case '*':{

                                z=x*y;

                                  break;}

                            case '/':{

                                    z=(float)x/y;

                                    if(y == 0)

                                        {

                                            printf("除数为0程序中断,请检查后再重新输入!!\n");

                                            exit(1);

                                        }

                                    else

                                    break;}

                            }

                        p=(struct node *)malloc(sizeof(struct node ));

                        p->num=z;

                        p->next=top;

                        top=p;

                        printf("将‘%f’入栈。\n",top->num);

                    }

                }

                }

    }

    }

}

 

//主程序

int main()

 

{

 

    Stack top,head;

top=CreateStack(); //建立一个链栈,并返回栈顶指针

printf("程序说明:\n");

    printf("一、功能:输出后缀表达式并输出结果.\n");

    printf("二、注意:\n");

    printf("        1.注意在输入时请切到英文输入法输入.\n");

    printf("        2.输入负数时请加(),如(-12).\n");

    printf("        3.可以计算小数,可判断除数是否为0.\n");

    printf("请输入前缀表达式:\n");

head=Transform(top); //中缀转化为后缀表达式

Calculate(head); //后缀表达式的计算

return 0;

 

}

 


前缀中缀后缀表达式及其互相转换

计算机中前缀中缀后缀表达式是数据结构栈的重要应用,他们都是对表达式的记法,只是相对位置不一样,顾名思义,前缀表达式指的是符号都在操作数之前,中缀表达式指的是运算符都在操作数之后,而后缀表达式是之后。如...
  • yanerhao
  • yanerhao
  • 2015年05月24日 19:59
  • 6691

C++中的前缀、中缀、后缀表达式转换

35,15,+,80,70,-,*,20,/               //后缀表达方式 (((35+15)*(80-70))/20)=25           //中缀表达方式   /...
  • eastlhu
  • eastlhu
  • 2014年03月01日 22:49
  • 1577

前缀---中缀--后缀 表达式的相互转换

前缀---中缀--后缀 表达式的相互转换
  • linsheng9731
  • linsheng9731
  • 2014年04月07日 20:19
  • 2566

数据结构-前缀、中缀、后缀表达式

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。 举例: (3 +...
  • viease
  • viease
  • 2014年08月14日 09:14
  • 2052

python数据结构与算法 9 中缀后前缀、后缀的转换思路

中缀到前缀和后缀的转换 So far, we have used adhoc methods to convert between infix expressions and the equival...
  • ppabcde
  • ppabcde
  • 2014年03月16日 09:21
  • 2021

前缀 中缀 后缀 表达式求值问题

原文链接:http://www.cnblogs.com/dolphin0520/p/3708602.html                            中缀表达式求值问题   中缀表达...
  • yuyanggo
  • yuyanggo
  • 2015年08月29日 13:03
  • 1433

英语单词最常用的328个前缀后缀(超全面)

1 a- 加在单词或词根前面, 表示 不,无,非   2 a- 加在单词前, 表示 在..., ...的   3 ab-, abs- 加在词根前,表示 相反,变坏,离去 等   4 ...
  • csshuke
  • csshuke
  • 2016年06月29日 11:22
  • 703

IT笔试题中经常出现的前缀、中缀、后缀表达式转换问题-----阿冬专栏

转载自:http://blog.csdn.net/antineutrino/article/details/6763722 做笔试题学习遇到,收集的最好的解释,通俗易懂。 它们都是对表达式的记法,...
  • zhangdong305
  • zhangdong305
  • 2016年09月18日 16:37
  • 829

为什么前缀++/--比后缀++/--的效率高?

首先切记一句话:前缀++比后缀++的效率高,返回引用的效率比返回对象的效率高,所以前缀++返回引用,后缀++返回对象。 对于内置类型和当代的编译器而言,这看似不是什么问题。然而,C++允许您针对...
  • sjpz0124
  • sjpz0124
  • 2015年04月22日 16:28
  • 911

前缀、中缀、后缀表达式学习

前言 最近做面试题的时候碰到了前缀、中缀、后缀表达式的问题,题目如下: 表达式“X=A+B*(C-D)/E”的后缀表达式? 看到这里有点蒙,于是赶紧google,记录一下学习新得吧 概述 ...
  • zinss26914
  • zinss26914
  • 2013年09月06日 13:29
  • 6377
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:前缀变后缀
举报原因:
原因补充:

(最多只允许输入30个字)