标题:谁能帮忙做一个运算器
只看楼主
moridiansha
Rank: 6Rank: 6
来 自:承德
等 级:侠之大者
威 望:4
帖 子:254
专家分:417
注 册:2009-10-21
结帖率:75%
已结贴  问题点数:20 回复次数:5 
谁能帮忙做一个运算器
要求用栈做
能进行+-* /%()的运算
搜索更多相关主题的帖子: 运算器 
2010-03-30 18:10
xichong
Rank: 7Rank: 7Rank: 7
来 自:四川南充
等 级:黑侠
威 望:2
帖 子:146
专家分:582
注 册:2009-6-10
得分:20 
#define STACK_INIT_SIZE 100
#define STACKINCREMENT  10
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
    char *base;
    char *top;
    int stacksize;
}OPTR,*StackOPTR;//运算符栈
typedef struct
{
    char *base;
    char *top;
    int stacksize;
}OPND,*StackOPND;//操作数栈
void initialOPTR(StackOPTR s)
{
    s->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
    if(!s->base) exit(0);
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
}
void initialOPND(StackOPND s)
{
    s->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
    if(!s->base) exit(0);
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
}
void PushOPTR(StackOPTR s,char e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(char *)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(char));
        if(!s->base) exit(0);
        s->top=s->base+s->stacksize;
        s->stacksize+=STACKINCREMENT;
    }
    *(s->top)++=e;
}
void PushOPND(StackOPND s,char e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(char *)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(char));
        if(!s->base) exit(0);
        s->top=s->base+s->stacksize;
        s->stacksize+=STACKINCREMENT;
    }
    *(s->top)++=e;
}
void PopOPTR(StackOPTR s,char *e)
{
    if(s->top==s->base) exit(0);
    *e=*--(s->top);
}
void PopOPND(StackOPND s,char *e)
{
    if(s->top==s->base) exit(0);
    *e=*--(s->top);
}
char GetTopOPTR(StackOPTR s)
{
    char e;
    if(s->top==s->base) exit(0);
    e=*(s->top-1);
    return e;
}
char GetTopOPND(StackOPND s)
{
    char e;
    if(s->top==s->base) exit(0);
    e=*(s->top-1);
    return e;
}
int In(char c)//判断输入的字符是否为运算符
{
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')
        return(1);
    else return(0);
}
//----------------------------------------------------------
char Precede(char op,char c)
{
    char ch;              
    if(op=='+'||op=='-')
        switch(c)
           {
              case '+':
              case '-':
              case ')':
              case '#':ch ='>';break;
              case '*':
              case '/':
              case '(':ch ='<';break;
           }
      else if(op=='*'||op=='/')
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':     
             case ')':
             case '#':ch ='>';break;
             case '(':ch ='<';break;
           }
      else if(op=='(')
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case '(':ch='<';break;
             case ')':ch='=';break;
             case '#':printf("Error!\n");exit(0);//---------------------------------------------
           }
      else if(op==')')
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case ')':
             case '#':ch='>';break;
             case '(':printf("Error!\n");exit(0);
           }
      else if(op=='#')
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case '(':ch ='<';break;
             case '#':ch='=';break;
             case ')':printf("Error!\n");exit(0);
           }
      return ch;                              
}
char operate(char c1,char theta,char c2)//仅操作0-9内的数之间的运算与ASCIII转换
{
    char answer;
    int m,n,result;
    m=c1-48;
    n=c2-48;
    switch(theta)
    {
    case '+':result=m+n;break;
    case '-':result=m-n;break;
    case '*':result=m*n;break;
    case '/':result=m/n;break;
    }
    answer=result+48;
    return answer;
}
int EvaluateExpression()
{
    OPTR optr;
    OPND opnd;
    char c,theta,a,b;
    initialOPTR(&optr);
    initialOPND(&opnd);
    PushOPTR(&optr,'#');
    printf("请输入你要计算的算术表达式,并以#表示结束:\n");
    c=getchar();
    while(c!='#'||GetTopOPTR(&optr)!='#')
    {
        if(!In(c))
        {
            PushOPND(&opnd,c);
            c=getchar();
        }
        else
            switch(Precede(GetTopOPTR(&optr),c))
        {
            case '<':
                PushOPTR(&optr,c);c=getchar();
                break;
            case '=':
                PopOPTR(&optr,&c);//弹出左括号
                c=getchar();
                break;
            case '>':
                PopOPTR(&optr,&theta);PopOPND(&opnd,&b);PopOPND(&opnd,&a);PushOPND(&opnd,operate(a,theta,b));
                break;
        }
    }
    return(GetTopOPND(&opnd));
}
void main()
{
    char result;
    result=EvaluateExpression();
    printf("该算术表达式的结果为%c\n",result);
}
2010-03-30 18:13
xichong
Rank: 7Rank: 7Rank: 7
来 自:四川南充
等 级:黑侠
威 望:2
帖 子:146
专家分:582
注 册:2009-6-10
得分:0 
改程序只能计算0-9范围内的整数,且每一部计算结果也在0-9的范围内,如果要扩大范围的话,改改char operate(char c1,char theta,char c2)这个函数就可以了
2010-03-30 18:17
longlong89
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:小飞侠
威 望:6
帖 子:1043
专家分:2754
注 册:2009-8-18
得分:0 
数据结构开篇—栈。

想象力征服世界
2010-03-30 18:56
moridiansha
Rank: 6Rank: 6
来 自:承德
等 级:侠之大者
威 望:4
帖 子:254
专家分:417
注 册:2009-10-21
得分:0 
回复 2楼 xichong
谢谢,非常感谢

www.qysy.tk
2010-03-31 13:19
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
得分:0 
#include <stdio.h>
#include <stdlib.h>

#define LENc sizeof(char)
#define LENi sizeof(int)
#define INIT_SIZE 100
#define INCREMENT  10

int i = 0;

typedef struct
{
    char *base;
    char *top;
    int stacksize;
}CharStack;

typedef struct
{
    int *base;
    int *top;
    int stacksize;
}IntStack;

void Init_CharStack( CharStack &s )
{
    s.base = (char *) malloc (INIT_SIZE*LENc);
    if( !s.base )
        exit(0);
    s.top = s.base;
    s.stacksize = INIT_SIZE;
}

void Push_CharStack( CharStack &s, char e )
{
    if( s.top-s.base >= s.stacksize )
    {
        s.base = (char*) realloc ( s.base, (s.stacksize + INCREMENT)*LENc );
        s.top = s.base + s.stacksize;
        s.stacksize += INCREMENT;
    }
    *s.top++ = e;
}

void Pop_CharStack( CharStack &s, char &e )
{
    if( s.top == s.base )
        exit(0);
    e = *--s.top;
}

char Getop_CharStack( CharStack &s )
{
    if( s.top == s.base )
        return '1';
    else
        return *(s.top-1);
}

void Init_IntStack( IntStack &s )
{
    s.base = (int *) malloc (INIT_SIZE*LENi);
    if( !s.base )
        exit(0);
    s.top = s.base;
    s.stacksize = INIT_SIZE;
}

void Push_IntStack( IntStack &s, int e )
{
    if( s.top-s.base >= s.stacksize )
    {
        s.base = (int*) realloc ( s.base, (s.stacksize + INCREMENT)*LENi );
        s.top = s.base + s.stacksize;
        s.stacksize += INCREMENT;
    }
    *s.top++ = e;
}

void Pop_IntStack( IntStack &s, int &e )
{
    if( s.top == s.base )
        exit(0);
    e = *--s.top;
}

int Getop_IntStack( IntStack &s )
{
    if( s.top == s.base )
        return 1;
    else
        return *(s.top-1);
}

void Total(CharStack &OPND, IntStack &sum )
{
    int sum1, sum2;

    if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
        i = i*10 + Getop_CharStack( OPND ) - 48;
    else if( Getop_CharStack( OPND )==' ' )
    {
        Push_IntStack( sum, i);
        i = 0;
    }
    else
        switch( Getop_CharStack( OPND ) )
    {
        case '+':
            Pop_IntStack( sum, sum1 );
            Pop_IntStack( sum, sum2 );
            sum1 += sum2;
            Push_IntStack( sum, sum1 );
            break;
        case '-':
            Pop_IntStack( sum, sum1 );
            Pop_IntStack( sum, sum2 );
            sum1 -= sum2;
            Push_IntStack( sum, sum1 );
            break;
        case '*':
            Pop_IntStack( sum, sum1 );
            Pop_IntStack( sum, sum2 );
            sum1 *= sum2;
            Push_IntStack( sum, sum1 );
            break;
        case '/':
            Pop_IntStack( sum, sum1 );
            Pop_IntStack( sum, sum2 );
            sum1 = sum2/sum1;
            Push_IntStack( sum, sum1 );
            break;
    }
}

void Work()
{
    CharStack OPND, OPTR;
    char e, c;
    IntStack sum;

    Init_CharStack( OPND );
    Init_CharStack( OPTR );
    Init_IntStack( sum );

    Push_CharStack( OPTR, '#' );
    printf("请输入正确地格式,中间不能有空格,并以‘#’号作为\n结束符号!\n");
    printf("前缀表达式:   ");
    while( 1 )
    {
        c = getchar();
        if( c>='0' && c<='9' )
        {
            Push_CharStack( OPND, c );
            Total( OPND, sum );
        }
        else if( c=='(' || c==')' )
        {
            if( c==')' )
            {
                while( Getop_CharStack( OPTR ) != '(' )
                {
                //    Total( OPND, sum );
                    Pop_CharStack( OPTR, e );
                    if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
                    {
                        Push_CharStack( OPND, ' ' );
                        Total( OPND, sum );
                    }
                    Push_CharStack( OPND, e );
                    Total( OPND, sum );
                }
                Pop_CharStack( OPTR, e );
            }
            else
                Push_CharStack( OPTR, c );
        }
        else
        {
            //Push_CharStack( OPND, ' ');
            if( c=='+' || c=='-' )
loop:switch( Getop_CharStack( OPTR ) )
            {
                case '/':
                case '*':
                    //Total( OPND, sum );
                    Pop_CharStack( OPTR, e );
                    if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
                    {
                        Push_CharStack( OPND, ' ' );
                        Total( OPND, sum );
                    }
                    Push_CharStack( OPND, e );
                    Total( OPND, sum );
                    goto loop;
                    break;
                default:
                //    Total( OPND, sum );
                    if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
                    {
                        Push_CharStack( OPND, ' ' );
                        Total( OPND, sum );
                    }
                    Push_CharStack( OPTR, c );
                    break;
            }
            if( c=='*' || c=='/' )
            {
                if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
                {
                    Push_CharStack( OPND, ' ' );
                    Total( OPND, sum );
                }
                Push_CharStack( OPTR, c);
            }
            if( c=='#')
            {
                while( Getop_CharStack( OPTR ) != '#' )
                {
                    //Total( OPND, sum );
                    Pop_CharStack( OPTR, e );
                    if( Getop_CharStack( OPND )>='0' && Getop_CharStack( OPND )<='9' )
                    {
                        Push_CharStack( OPND, ' ' );
                        Total( OPND, sum );
                    }
                    Push_CharStack( OPND, e );
                    Total( OPND, sum );
                }
                Pop_CharStack( OPTR, e );
            }
        }
        //Total( OPND, sum );
        if( c=='#' )
            goto lop;
    }
lop:while( OPND.base != OPND.top )
    {
        Pop_CharStack( OPND, e );
        Push_CharStack( OPTR, e );
    }
    printf("输出后缀表达式:   ");
    while( OPTR.base != OPTR.top )
    {
        Pop_CharStack( OPTR, e );
        printf("%c",e);
    }
    printf("\n");
    printf("输出计算结果:   ");
    printf("%d\n", Getop_IntStack( sum ) );
}

void main()
{
    Work();
}


2010-04-01 12:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-301051-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.682877 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved