| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 663 人关注过本帖
标题:表达式求值问题
只看楼主 加入收藏
jinzhubaobao
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-3-16
收藏
 问题点数:0 回复次数:0 
表达式求值问题
拜托各位帮忙给解释一下程序设计思想和流程.非常感谢
#include<iostream.h>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#define StackSize 100
typedef struct stack_num//有待改进
{
    int top;
    double a[StackSize];
}num_stack;
typedef struct stack_operation
{
    int top;
    char a[StackSize];
}opert;
bool empty(num_stack*p);//判断操作数栈是否为空
bool empty(opert*p);//判断操作数栈是否为空
char pop(opert*p);
double pop(num_stack*p);
void push(opert*p,char symb);
void push(num_stack*p,double num);
void PopAndTest(num_stack*p,double *x,bool*test);//.....
void PopAndTest(opert*p,char *x,bool*test);
void PushAndTest(num_stack*p,int x,bool*test);//....
void PushAndTest(opert*p,char x,bool*test);//以上为栈的实现
bool judge_of_inStr(char a[]);//判断输入的字符串是否为正确匹配形式
bool isoperand(char symb);//判断是否为操作数
bool prcd(char symb1,char symb2);//比较优先级
void postfix(char inStr[],char postStr[]);//将前缀表达式转化成后缀表达式
double counter(char postStr[]);//对后缀表达式运算
double oper(char symb,double op1,double op2);//对两个操作数进行symb运算
double get_number(char num_str[],int length,int);//将数字字符串转化成double型

int main()
{
    char inStr[50],postStr[50];
    double result;
    int choice;
    cout<<"请输入运算表达式(注意末尾不要输入'='号)"<<endl;
    do
    {
        gets(inStr);
        postfix( inStr, postStr);
        if(!judge_of_inStr(inStr))
        {
            cout<<"表达式错误,括号不匹配"<<endl;
            exit(1);
        }
        result=    counter(postStr);
        cout<<"计算结果为: "<<result<<endl;
        cout<<"继续计算请输入1,退出请输入0"<<endl;
        cin>>choice;
        cout<<"-------------------------------------------------------"<<endl;
    }while(choice==1);
    return 0;
}
bool empty(num_stack*p)//判断操作数栈是否为空
{
    return (p->top==-1);
}
bool empty(opert*p)//判断操作数栈是否为空
{
    return (p->top==-1);
}
void PopAndTest(num_stack*p,double  *x,bool*test)//....
{
    if(empty(p))
        *test=true;
    else
    {
        *test=false;
        *x=p->a[p->top];
        p->top--;
    }
}
void PopAndTest(opert*p,char *x,bool*test)//如果为空,返回ture
{
    if(empty(p))
        *test=true;
    else
    {
        *test=false;
        *x=p->a[p->top];
        p->top--;
    }
}
void PushAndTest(num_stack*p,double x,bool*test)//.....
{
    if(p->top==StackSize-1)
        *test=true;
    else
    {
        *test=false;
        p->top++;
        p->a[p->top]=x;
    }
}
void PushAndTest(opert*p,char x,bool*test)
{
    if(p->top==StackSize-1)
        *test=true;
    else
    {
        *test=false;
        p->top++;
        p->a[p->top]=x;
    }
}
char pop(opert*p)
{
    if(p->top==-1)
    {
        cout<<"表达式格式错误!"<<endl;
        exit(1);
        
    }
    else
        return    p->a[p->top--];
}  
double pop(num_stack*p)
{
    if(p->top==-1)
    {
        cout<<"表达式格式错误!"<<endl;
        exit(1);    
    }
    else
        return    p->a[p->top--];
}  
void push(opert*p,char symb)
{
    if(p->top==StackSize-1)
    {
        cout<<"表达式格式错误!"<<endl;
        exit(1);
    }
    p->a[++p->top]=symb;
}

void push(num_stack*p,double num)
{
    if(p->top==StackSize-1)
    {
        cout<<"表达式格式错误!"<<endl;
        exit(1);
    }
    p->a[++p->top]=num;
}
bool isoperand(char symb)  //判断是否是操作数
{
    return (symb>='0'&&symb<='9');
}
bool prcd(char symb1,char symb2)//比较两个操作符的优先级
{
    int former,later;
    char precedence[10][10]=
    {
        {'>','>','<','<','<','>','<','<'},
        {'>','>','<','<','<','>','<','<'},
        {'>','>','>','>','<','>','<','<'},
        {'>','>','>','>','<','>','<','<'},
        {'<','<','<','<','<','<','<','<'},
        {'0'},
        {'>','>','>','>','<','>','<','<'},
        {'>','>','>','>','<','>','>','0'}
    };
    switch(symb1)
    {
    case '+':former=0;break;
    case '-':former=1;break;
    case '*':former=2;break;
    case '/':former=3;break;
    case '(':former=4;break;
    case ')':former=5;break;
    case '^':former=6;break;
    case '~':former=7;break;
    default:
        cout<<"操作符错误!"<<endl;
        exit(1);
    }
    switch(symb2)
    {
    case '+':later=0;break;
    case '-':later=1;break;
    case '*':later=2;break;
    case '/':later=3;break;
    case '(':later=4;break;
    case ')':later=5;break;
    case '^':later=6;break;
    case '~':later=7;break;//......
    default:
        cout<<"操作符错误!"<<endl;
        exit(1);
    }
    return (precedence[former][later]=='>');
}
void postfix(char inStr[],char postStr[])//把前缀表达式转化成后缀表达式
{
    int i=0;
    int j=0;
    bool test;
    char topsymb='+';
    char symb;
    opert*p;
    p=new opert;
    p->top=-1;
    if(inStr[0]=='-')
        inStr[0]='~';
    
    while((symb=inStr[i])!='\0')
    {
        if(isoperand(symb))
        {
            while((isoperand(symb)&&symb!='\0')||symb=='.')
            {
                postStr[j++]=symb;
                symb=inStr[++i];
            }
            postStr[j++]='#';
        }
        else
        {
            if(symb=='-'&&inStr[i-1]=='(')
                symb='~';
            PopAndTest(p,&topsymb,&test);
            while(!test&&prcd(topsymb,symb))
            {
                postStr[j++]=topsymb;
                PopAndTest(p,&topsymb,&test);
            }
            if(!test)
                push(p,topsymb);
            if(test||symb!=')')
                push(p,symb);
            else               
                topsymb=pop(p);
            i++;
        }
    }
    while(!empty(p))
        postStr[j++]=pop(p);
    postStr[j]='\0';
    printf("后缀表达式:");
    printf("%s    ['#'代表空格]\n",postStr);                
}
double oper(char symb,double op1,double op2)
{
    switch(symb)
    {
    case '+': return (op1+op2);break;
    case '-':return (op1-op2);break;
    case '*':return (op1*op2);break;
    case '/':
        if(op2!=0)
        {
            return (op1/op2);
        }
        else
            printf("表达式不合法!\n");
            exit(1);
        break;
    case '^':
        if(op1==0 && op2==0)
        {
            printf("表达式不合法!\n");
            exit(1);
        }
        else
            return pow(op1,op2);
        break;
    default:
        {
            cout<<"无"<<symb<<"操作,错误在oper中"<<endl;
            exit(1);
        }
    }
}
double get_number(char num_str[],int length,int position_of_point)
{   
    double    sum=0;
    int i;
    for(i=0;i<length;i++)
    {
        if(num_str[i]=='.')
        {
            position_of_point++;
            continue;
        }
        sum+=(num_str[i]-'0')*pow(10,position_of_point-i-1);
    }
    return sum;
}
double counter(char postStr[])
{
    double op1,op2;
    double value;
    char symb;
    char num_str[20];//可能越界
    int iOFnum_str=0;
    bool exist_point;
    int k,position_of_point,i=0;
    num_stack*p;
    p=new num_stack;
    p->top=-1;
    symb=postStr[i];
    while(symb!='\0')
    {   
        iOFnum_str=0;
        k=0;
        exist_point=false;
        while(isoperand(symb)||symb=='.')
        {
            if(symb=='.')
            {
                position_of_point=k;
                exist_point=true;
            }
            k++;
            num_str[iOFnum_str]=symb;
            iOFnum_str++;
            symb=postStr[++i];
        }
        if(    exist_point==false)
        {
            position_of_point=k;
        }
        if(symb=='#')
            push(p,get_number(num_str,k,position_of_point));
        else if(symb=='~')
        {
            op1=pop(p);
            push(p,-op1);
        }
        else
        {
            op2=pop(p);
            op1=pop(p);
            value=oper(symb,op1,op2);
            push(p,value);
        }
        i++;
        symb=postStr[i];
    }
    return pop(p);
}

bool judge_of_inStr(char a[])//
{    
    char symb,topsymb;
    int i=0;
    opert*p;
    bool test;
    p=new opert;
    p->top=-1;
    symb=a[i];
    while(symb!='\0')
    //for(symb=a[i];symb!='\0';i++)
    {
        if(symb=='(')
            push(p,symb);
        if(symb==')')
        {
            PopAndTest(p,&topsymb,&test);
            if(test)
                return false;
        }
        i++;
        symb=a[i];
    }
    return empty(p);
}
搜索更多相关主题的帖子: 求值 表达 
2008-11-28 13:13
快速回复:表达式求值问题
数据加载中...
 
   



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

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