回 帖 发 新 帖 刷新版面

主题:[原创]中缀表达式的求值

前几天做的一个数据结构上机实验

/*===========================================================*/
/*                 ** 中缀表达式的求值 **                    */
/*函数个数:4  包含2个自定义头文件(seqstack.h  seqstack1.h)  */
/*作者:踏网无痕                                             */
/*修改时间:31/05/04                                         */
/*在VC++6.0下调试                                            */
/*===========================================================*/

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

typedef float DataType;        /*运算数的类型定义*/
#include "seqstack.h"

typedef struct                /*运算符的类型定义*/
{
    char op;
    int inputprecedence;    /*读入时的优先级*/
    int stackprecedence;    /*栈内的优先级*/
}DataType1;
#include "seqstack1.h"

DataType1 MathPotr(char);    /*给读入的运算符和左右括号配备优先级*/
void Evaluate(SeqStack *,DataType1);
                            /*执行从运算符栈弹出的运算符号所要求的运算*/
void Infix(char *);            /*将数、符分类压栈*/
int isoptr(char);            /*判断字符是否为运算符或左括号*/

/*
*主函数
*输入:空
*返回:空
*/
void main(void)
{
    char str[50];            /*声明接收表达式的字符串*/
    printf("Please input the expression(use \"=\" to end):");
    gets(str);                /*键盘读入用户的表达式*/
    Infix(str);                /*将表达式进行计算*/
}

/*
*功能:给读入的运算符和左右括号配备优先级
*输入:运算符和左右括号
*返回:运算符
*/
DataType1 MathOptr(char ch)
{
    DataType1 optr;
    optr.op=ch;

    switch(optr.op)
    {
        case '+':
        case '-':
            optr.inputprecedence=1;
            optr.stackprecedence=1;
            break;
        case '*':
        case '/':
            optr.inputprecedence=2;
            optr.stackprecedence=2;
            break;
        case '(':
            optr.inputprecedence=3;
            optr.stackprecedence=-1;
            break;
        case')':
            optr.inputprecedence=0;
            optr.stackprecedence=0;
            break;
    }
    return optr;
}

/*
*功能:执行从运算符栈弹出的运算符号optr所要求的运算
*输入:(运算数栈指针类型)运算数栈,(运算符栈元素类型)
*返回:空
*/
void Evaluate(SeqStack *OpndStack,DataType1 optr)
{
    DataType opnd1,opnd2;        /*声明两个运算数*/
    opnd1=popStack(OpndStack);    /*从数栈中弹出第一个数*/
    opnd2=popStack(OpndStack);    /*从数栈中弹出第二个数*/

    switch(optr.op)                /*由运算符决定运算数的计算规则*/
    {
        case'+':
            pushStack(OpndStack,opnd2+opnd1);
            break;
        case'-':
            pushStack(OpndStack,opnd2-opnd1);
            break;
        case'*':
            pushStack(OpndStack,opnd2*opnd1);
            break;
        case'/':
            pushStack(OpndStack,opnd2/opnd1);
            break;
    }
}

/*
*功能:将数、符分类压栈
*输入:(字符串指针)要分类处理的字符串
*返回:空
*/
void Infix(char *str)
{
    int i;                    /*数字字符串的计数变量*/
    int k;                    /*中缀表达式串的字符计数变量*/
    int n=strlen(str);        /*中缀表达式串的长度*/
    char ch;                /*用件处理的字符*/
    char numstr[10];        /*存储数字字符串*/

    DataType opnd;            /*临时存储一个数字*/
    DataType1 optr;            /*临时存储一个运算符*/

    SeqStack OpndStack;        /*运算数栈*/
    SeqStack1 OptrStack;    /*运算符栈*/

    setStack(&OpndStack,n);    /*初始化运算数栈*/
    setStack1(&OptrStack,n);/*初始化运算符栈*/

    k=0;                    /*标记表达式字符串的下标*/
    ch=str[k];                /*将字符串的第一个赋给ch*/
    while(ch!='=')

        /*如果是数字字符或小数点*/
        if(isdigit(ch)||ch=='.')    
        {
            for(i=0;isdigit(ch)||ch=='.';i++)
            {
                numstr[i]=ch;
                k++;
                ch=str[k];
            }
            numstr[i]='\0';
            opnd=(float)atof(numstr);
                            /*将字符串转化为实数*/
            pushStack(&OpndStack,opnd);
        }
        else
        {
            /*如果是运算符或左括号*/
            if(isoptr(ch))            
            {
                optr=MathOptr(ch);
                while(!isStackEmpty1(&OptrStack)&&getTopData1(&OptrStack).stackprecedence>=optr.inputprecedence)
                /*如果新进栈的算符优先级大的,则弹出数栈中的元素,计算后把结果压入数栈*/    
                    Evaluate(&OpndStack,popStack1(&OptrStack));
                pushStack1(&OptrStack,optr);/*算符入栈*/
                k++;
                ch=str[k];
            }

            /*如果是右括号*/
            else if(ch==')')        
            {
                optr=MathOptr(ch);
                while(!isStackEmpty1(&OptrStack)&&getTopData1(&OptrStack).stackprecedence>=optr.inputprecedence)
                    Evaluate(&OpndStack,popStack1(&OptrStack));
                popStack1(&OptrStack);    /*将栈中的左括号弹出*/
                k++;
                ch=str[k];
            }
        }

    /*如果运算符栈非空*/
    while(!isStackEmpty1(&OptrStack))
        Evaluate(&OpndStack,popStack1(&OptrStack));
    opnd=popStack(&OpndStack);
    printf("%-6.2f\n",opnd);    /*输出计算结果*/
    freeStack(&OpndStack);        /*释放数栈空间*/
    freeStack1(&OptrStack);        /*释放算符栈空间*/
}

/*
*功能:判断字符是否为运算符或左括号
*输入:字符
*返回:1(是),0(否)
*/
int isoptr(char ch)
{
    return(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='(');
}


/*
* @SeqStack11.h    1.0   04/05/21
*
* @Author 踏网无痕
*
* @实现对顺序栈的基本操作,要求用户用已有类型定义DataType11
*/

typedef struct
{
    DataType1 *data;
    int max;
    int top;
}SeqStack1;

/*
*构造函数 建立数组长度为n的空栈
*输入:(栈类型指针)要初始化的栈的地址,(整型)栈长度
*返回:空
*/
void setStack1(SeqStack1 *s,int n)
{
    s->data=(DataType1 *)malloc(n*sizeof(DataType1));
    if(s->data==NULL)
    {
        printf("Overflow!\n");
        exit(1);
    }
    s->max=n;
    s->top=-1;
}

/*
*析构函数 释放数组空间
*输入:(栈类型指针)要释放栈的地址
*返回:空
*/
void freeStack1(SeqStack1 *s)
{
    free(s->data);
}

/*
*获得栈中数据个数
*输入:(栈类型指针)要求数据个数的栈的地址
*返回:(整型)栈中数据的个数
*/
int getStackSize1(SeqStack1 *s)
{
    return(s->top+1);
}

/*
*判断栈是否为空
*输入:(栈类型指针)要判断的栈的地址
*返回:(整型1或整型0)1为空,0不空
*/
int isStackEmpty1(SeqStack1 *s)
{
    return(s->top==-1);
}

/*
*判断栈是否已满
*输入:(栈类型指针)要判断的栈的地址
*返回:(整型1或整型0)1为满,0不满
*/
int isStackFull1(SeqStack1 *s)
{
    return(s->top==s->max-1);
}

/*
*取栈顶元素
*输入:(栈类型指针)要操作的栈的地址
*返回:(用户定义类型)栈顶元素的值
*/
DataType1 getTopData1(SeqStack1 *s)
{
    if(isStackEmpty1(s))
    {
        printf("Stack is empty!\n");
        exit(1);
    }
    return(s->data[s->top]);
}

/*
*元素入栈
*输入:(栈类型指针)要操作的栈的地址,(用户定义类型)要入栈的元素值
*返回:空
*/
void pushStack1(SeqStack1 *s,DataType1 item)
{
    if(isStackFull1(s))
    {
        printf("Stack is full!\n");
        exit(1);
    }
    s->top++;
    s->data[s->top]=item;
}

/*
*元素出栈
*输入:(栈类型指针)要操作的栈的地址
*返回:(用户定义类型)出栈的元素值
*/
DataType1 popStack1(SeqStack1 *s)
{
    if(isStackEmpty1(s))
    {
        printf("Stack is empty!\n");
        exit(1);
    }
    s->top--;
    return(s->data[s->top+1]);
}

/*
*清空栈
*输入:(栈类型指针)要操作的栈的地址
*返回:空
*/
void clearStack1(SeqStack1 *s)
{
    s->top=-1;
}








/*
* @seqstack.h    1.0   04/05/16
*
* @Author 踏网无痕
*
* @实现对顺序栈的基本操作,要求用户用已有类型定义DataType
*/

typedef struct
{
    DataType *data;
    int max;
    int top;
}SeqStack;

/*
*构造函数 建立数组长度为n的空栈
*输入:(栈类型指针)要初始化的栈的地址,(整型)栈长度
*返回:空
*/
void setStack(SeqStack *s,int n)
{
    s->data=(DataType *)malloc(n*sizeof(DataType));
    if(s->data==NULL)
    {
        printf("Overflow!\n");
        exit(1);
    }
    s->max=n;
    s->top=-1;
}

/*
*析构函数 释放数组空间
*输入:(栈类型指针)要释放栈的地址
*返回:空
*/
void freeStack(SeqStack *s)
{
    free(s->data);
}

/*
*获得栈中数据个数
*输入:(栈类型指针)要求数据个数的栈的地址
*返回:(整型)栈中数据的个数
*/
int getStackSize(SeqStack *s)
{
    return(s->top+1);
}

/*
*判断栈是否为空
*输入:(栈类型指针)要判断的栈的地址
*返回:(整型1或整型0)1为空,0不空
*/
int isStackEmpty(SeqStack *s)
{
    return(s->top==-1);
}

/*
*判断栈是否已满
*输入:(栈类型指针)要判断的栈的地址
*返回:(整型1或整型0)1为满,0不满
*/
int isStackFull(SeqStack *s)
{
    return(s->top==s->max-1);
}

/*
*取栈顶元素
*输入:(栈类型指针)要操作的栈的地址
*返回:(用户定义类型)栈顶元素的值
*/
DataType getTopData(SeqStack *s)
{
    if(isStackEmpty(s))
    {
        printf("Stack is empty!\n");
        exit(1);
    }
    return(s->data[s->top]);
}

/*
*元素入栈
*输入:(栈类型指针)要操作的栈的地址,(用户定义类型)要入栈的元素值
*返回:空
*/
void pushStack(SeqStack *s,DataType item)
{
    if(isStackFull(s))
    {
        printf("Stack is full!\n");
        exit(1);
    }
    s->top++;
    s->data[s->top]=item;
}

/*
*元素出栈
*输入:(栈类型指针)要操作的栈的地址
*返回:(用户定义类型)出栈的元素值
*/
DataType popStack(SeqStack *s)
{
    if(isStackEmpty(s))
    {
        printf("Stack is empty!\n");
        exit(1);
    }
    s->top--;
    return(s->data[s->top+1]);
}

/*
*清空栈
*输入:(栈类型指针)要操作的栈的地址
*返回:空
*/
void clearStack(SeqStack *s)
{
    s->top=-1;
}

回复列表 (共3个回复)

沙发

为什么调试结果是错误的?
如果如何能否将源程序一字不差的打包发送给我?
E-mail:63978285@163.com
谢谢!

板凳

好久没来,程序已发,请查收

3 楼

能不能也把无错的程序发给我啊,wxc0077@126.com

我来回复

您尚未登录,请登录后再回复。点此登录或注册