表达式求值(C实现) z


对于这个转得简单的C多项表达式求值,这只是一个非常简单的演示,建议大家看更新的一篇 数据结构-表达式求值-栈 http://blog.youkuaiyun.com/katadoc360/article/details/6802334

话我不多说了,c利用堆栈求表达式值.直接上代码了.

zj@zj:~/C_parm/data_s$ cat expr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 4000;
typedef struct
{
    char data[10];
    int top;//头地址

    int base;//基地址

    int length;//长度

}Stack;

void init(Stack *st)//初始化栈

{
    st->base=0;
    st->top=0;
    st->length=0;
}

int isEmpty(Stack *st)
{
    int n=0,top,base;
    top =st->top;
    base =st->base;
    if(top==base)
    {
        return 1;
    }
    return n;
}

int isFull(Stack *st)
{
    int n=0,top,base;
    top =st->top;
    if(top>=4000)
    {
        return 1;
    }
    return n;
}

char getTop(Stack *st)// 返回top值,不改变栈的结构

{
    char n;
    if(isEmpty(st))
    {
        printf("栈为空/n");
        return 0;
    }
    int positon= st->top-1;
    n= st->data[positon];//取出数据;

    return n;
}

char pop(Stack *st)// 出栈,返回

{
    char n;
    if(isEmpty(st))
    {
        printf("栈为空/n");
        return 0;
    }
    int positon= st->top-1;
    n= st->data[positon];//取出数据;


    st->top--;
    st->length--;
    st->data[positon]='/0';//消除数据

    return n;
}

void push(char n,Stack *st)//入栈

{
    int positon ;
    if(isFull(st))
    {
        printf("栈满/n");
        
    }
    else
    {
        positon= st->top;//获取位置


        st->data[positon]=n;//存入数据


        st->top++;//改变位置

    }

}

void show(Stack *m1)//输出栈中的数据

{
    int top,base;
    top=m1->top;
    base=m1->base;
    while(top>base)
    {
        printf("%c,",m1->data[--top]);
    }
    printf("/n");
}

int isOperate(char temp)//是否是操作符

{
    if(temp=='+'||temp=='-'||temp=='*'||temp=='/'||temp=='('||temp==')'||temp=='#')
    {
        return 1;
    }
    return 0;
}

int isValue(char temp)//是否是数值

{
    if(temp>='0'&&temp<='9')//

    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int isAvail(char temp)//是否有效字符

{
    if(isOperate(temp)||isValue(temp))//如果temp既不是操作符和数值的话,则它是非法的

    {
        return 1;
    }
    return 0;
}

int detect(char temp)//搜索矩阵位置

{
    int i=0;
    char oper[7]={'+','-','*','/','(',')','#'};
    for(i=0;i<7;i++)
    {
        if(temp==oper[i])
        {
            return i;
        }
    }
}

char Priority(char temp,char optr)//判断优先级

{
    /**//*
            + - * / ( ) #
            1 2 3 4 5 6 7
        + 1 < < < < > > >
        - 2 < < < < > > >
        * 3 > > < < > > >
        / 4 > > < < > > >
        ( 5 > > > > > = 0
        ) 6 < < < < = 0 >
        # 7 < < < < > 0 =
    */

    int row ,col;
    char priority[7][7]={/**//* + - * / ( ) # */
                             {'<','<','<','<','>','>','>'},

                            {'<','<','<','<','>','>','>'},

                            {'>','>','<','<','>','>','>'},

                            {'>','>','<','<','>','>','>'},

                            {'>','>','>','>','>','=','>'},

                            {'<','<','<','<','=','0','>'},

                            {'<','<','<','<','>','<','='},
                        };


    row = detect(temp);//找出对应的矩阵下标;

    col = detect(optr);
// printf("%d,%d",row,col);

      
    //优先级存储在一个7x7的矩阵中,对应关系上图;

    
    return priority[row][col];

}
char evaluate(int a,int b,char oper)
{
    switch(oper)
    {
        case '+': return a+b+'0';
        case '-': return a-b+'0';
        case '*': return a*b+'0';
        case '/': return a/b+'0';
        default : return 0+'0';
    }
}
int calculateExpress(char *express)//计算表达式

{
    int result=0;
    int a,b;
   // char oper,result;


    Stack OPTR,OPND;//OPTR存储操作符,OPND操作数值

    init(&OPTR);
    init(&OPND);
    push('#',&OPTR);//默认第一个位'#'


    ////////////////////-算法-////////////////////////////

    while(*express!='/0')
    {
        char temp;
        temp= *(express);
        printf("---------------------------------/n");
        printf("当前的符号为%c/n",temp);
        if(isAvail(temp))//是否是有效字符

        {
                if(isOperate(temp) )//输入的是操作符

                {
             char oper,result;
                    char optr = getTop(&OPTR);//栈中top位的操作符

                    printf("栈顶操作符位:%c/n",optr);
                    char prior = Priority(temp,optr);//判断优先级

                    switch(prior)
                    {
                        case '>':
                                    push(temp,&OPTR);
                                    printf("将符号位%c入栈/n",temp);
                                    express++;
                                    break;
                        case '<':
                                    //int a,b;


                                    //char oper,result;


                                    a=pop(&OPND)-'0';//存在栈中的都是char字符

                                    b=pop(&OPND)-'0';
                                    oper=pop(&OPTR);
                                    
                                    result=evaluate(b,a,oper);//出栈一个操作符,计算结果

                                    //printf("%d",result-'0');

                                    push(result,&OPND);//结果入OPND

                                    printf("%d%c%d结果为:%d/n",b,oper,a,result-'0');
                                    break;
                    
                        case '=':
                                    //消除括号

                                    pop(&OPTR);
                                    printf("消除括号/n");
                                    express++;
                                    break;
                        
                    }

                }
                if(isValue(temp))//输入的是数值

                {
                    push(temp,&OPND);//将数值位入栈;

                    express++;
                    printf("将数值%c压入栈/n",temp);
                    //show(&OPND);

                }
        }
        else //表达式中有非法字符

        {
            printf("表达式中有非法字符/n");
            exit(-1);//退出程序

        }
        
    
    }
// show(&OPND);

// show(&OPTR);

    return getTop(&OPND)-'0';
}

void inputExpress(char *express)//输入表达式

{
    int length=0;
    printf("请输入一个表达式:");
    scanf("%s",express);
    int len =strlen(express);
    express[len]='#';//表达式最后一位默认为'#';

    express[len+1]='/0';

}

void output(char *express,int result)//输出表达式

{
    int i=0;
    printf("----------------------------------------/n表达式:");
    while(express[i]!='#')
    {
        printf("%c",express[i]);
        i++;
    }
    printf("=%d/n",result);



}

int main()
{
    
    char express[100];//表达式

    int result =0;
    
    inputExpress(express);//输入表达式

    
    result = calculateExpress(express);//计算表达式;

    
    output(express,result); //输出表达式

    
    //、、、、、、、、、、、、、测试优先级。

    /**//*
    char m='7' ;
    m=Priority('+','*');
    printf("优先级为%c",m);
    
    int m=evaluate(5,6,'m');
    printf("%d",m);
    */

   return 0;
}
zj@zj:~/C_parm/data_s$ ./expr
请输入一个表达式:2*3+(4+8)/3-2
---------------------------------
当前的符号为2
将数值2压入栈
---------------------------------
当前的符号为*
栈顶操作符位:#
将符号位*入栈
---------------------------------
当前的符号为3
将数值3压入栈
---------------------------------
当前的符号为+
栈顶操作符位:*
2*3结果为:6
---------------------------------
当前的符号为+
栈顶操作符位:#
将符号位+入栈
---------------------------------
当前的符号为(
栈顶操作符位:+
将符号位(入栈
---------------------------------
当前的符号为4
将数值4压入栈
---------------------------------
当前的符号为+
栈顶操作符位:(
将符号位+入栈
---------------------------------
当前的符号为8
将数值8压入栈
---------------------------------
当前的符号为)
栈顶操作符位:+
4+8结果为:12
---------------------------------
当前的符号为)
栈顶操作符位:(
消除括号
---------------------------------
当前的符号为/
栈顶操作符位:+
将符号位/入栈
---------------------------------
当前的符号为3
将数值3压入栈
---------------------------------
当前的符号为-
栈顶操作符位:/
12/3结果为:4
---------------------------------
当前的符号为-
栈顶操作符位:+
6+4结果为:10
---------------------------------
当前的符号为-
栈顶操作符位:#
将符号位-入栈
---------------------------------
当前的符号为2
将数值2压入栈
---------------------------------
当前的符号为#
栈顶操作符位:-
10-2结果为:8
---------------------------------
当前的符号为#
栈顶操作符位:#
消除括号
----------------------------------------
表达式:2*3+(4+8)/3-2=8


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值