在用逆波兰表示法进行四则运算时遇到的一些问题
  • 板块灌水区
  • 楼主KangarooGao
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/21 14:50
  • 上次更新2023/11/2 12:15:16
查看原帖
在用逆波兰表示法进行四则运算时遇到的一些问题
1159176
KangarooGao楼主2023/10/21 14:50
char Calculate(char c1,char op,char c2)
{
    int x1,x2,x;
    char ch[2],c[3];
    ch[0]=c1;
    x1=atoi(ch);
    ch[0]=c2;
    x2=atoi(ch);
    switch (op)
    {
    case '+':
        x=x1+x2;
        break;
    case '-':
        x=x1-x2;
        break;
    case '*':
        x=x1*x2;
        break;
    case '/':
        x=x1/x2;
        break;
    default:
        break;
    }
     itoa(x,c,10);
    return c[0];
}

这是其中一个函数,发现这样传不回多位数,但在四则运算中又不可避免,请问有什么办法修改吗? 以下是全部源代码

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

typedef struct StackList
{
    char ope; //储存操作符的链栈节点
    struct StackList* next;
}Stack;

typedef struct Linklist
{
    char ch;//储存操作符和操作数的链表节点
    struct Linklist* next;
}List;

Stack* InitStack()//初始化链栈
{
    return NULL;
}

Stack* PushStack(Stack** S,char c)//将操作符进栈
{
    Stack *p=(Stack*)malloc(sizeof(Stack));
    if(!p)
    {
        printf("申请空间失败");
        return NULL;
    }
    p->ope=c;
    if(!*S)
    {
        *S=p;
        (*S)->next=NULL;
    }
    else
    {
        p->next=*S;
        *S=p;
        //printf("进栈%c",S->ope);
    }
    //Stack *q=S;
    //printf("%c",q->ope);
    return *S;
}

char PopStack(Stack** S)//将栈顶操作符出栈
{
    char c;
    if(!*S)
    {
        printf("链栈为空");
        return 0;
    }
    Stack *p=*S;
    c=p->ope;
    //printf("原栈顶%c",c);
    (*S)=(*S)->next;
    //printf("新栈顶%c",(*S)->ope);
    free(p);
    return c;
}

char GetStackTop(Stack* S)//取栈顶操作符
{
    if(!S)
    {
        printf("链栈为空");
        return -1;
    }
    return S->ope;
}


int isOperator(char c)//判断是否为操作符
{
    const char *p="+-*/()";
    while(*p)
    {
        if(c==*p)
            return 1;
        p++;
    }
    return 0;
}

int isPrior(char c1,char c2)//判断操作符优先级
{
    const char *ch="#+-*/";
    int i=0,j=0;
    while (ch[i]&&ch[i]!=c1)
        i++;
    if(i==2)//加减同级
        i--;
    if(i==4)//乘除同级
        i--;
    while (ch[j]&&ch[j]!=c2)
        j++;
    if(j==2)//加减同级
        j--;
    if(j==4)//乘除同级
        j--;
    if(i>=j)
        return 1;
    else
        return 0;
}

List* InitList()//初始化链表
{
    return NULL;
}

List* PushList(List* link,char c)//将新字符插入链表末尾节点
{
    List* L=(List*)malloc(sizeof(List)),*rear=link;
    if(!L)
    {
        printf("申请空间失败");
        return link;
    }
    if(!link)
    {
        L->ch=c;
        link=L;
        link->next=NULL;
        return link;
    }
    L->ch=c;
    while (rear->next)
        rear=rear->next;
    rear->next=L;
    L->next=NULL;
    return link;
}

List* InversePoland(char* st)//将中缀表达式转为逆波兰(后缀)表达式
{
    int i=0,j=0;
    char e;
    Stack *Operate=InitStack();//Operate是在转化中储存操作符的链栈指针
    List *Convert=InitList(),*p=NULL;//Convert是储存转化后的逆波兰表达式的链栈指针
    Operate=PushStack(&Operate,st[i]);
    i++;
    while (st[i]!='#')
    {
        //printf("%c",st[i]);
        if(!isOperator(st[i]))
        {
            //printf("1");
            Convert=PushList(Convert,st[i]);
            i++;
        }
        else
        {
            if(st[i]=='(')
            {
                //printf("2");
                Operate=PushStack(&Operate,st[i]);
                i++;
            }
            else if(st[i]==')')
            {
                while(GetStackTop(Operate)!='(')
                {
                    //printf("3");
                    //char temp=GetStackTop(Operate);
                    //printf("栈顶%c",temp);
                    //char c=PopStack(&Operate);
                    //printf("弹出%c",c);
                    //Stack *O=Operate;
                    //printf("新栈顶%c",O->ope);
                    if(GetStackTop(Operate)!='#')
                    {
                        Convert=PushList(Convert,PopStack(&Operate));
                        //i++;
                    }
                    else
                    {
                        printf("括号不匹配\n");
                        break;
                    }
                }
                char ch=PopStack(&Operate);
                i++;
                //printf("%c",ch);
            }
            else
            {
                if(GetStackTop(Operate)!='('&&GetStackTop(Operate)!='#'&&isPrior(GetStackTop(Operate),st[i]))
                    Convert=PushList(Convert,PopStack(&Operate));
                else 
                {
                    Operate=PushStack(&Operate,st[i]);
                    i++;
                }
            }  
        }
    }
    while (Operate->ope!='#')
        PushList(Convert,PopStack(&Operate));
    p=Convert;
    while (p)
    {
        printf("%c",p->ch);
        p=p->next;
    }
    printf("\n");
    return Convert;
}

char Calculate(char c1,char op,char c2)
{
    int x1,x2,x;
    char ch[2],c[3];
    ch[0]=c1;
    x1=atoi(ch);
    ch[0]=c2;
    x2=atoi(ch);
    switch (op)
    {
    case '+':
        x=x1+x2;
        break;
    case '-':
        x=x1-x2;
        break;
    case '*':
        x=x1*x2;
        break;
    case '/':
        x=x1/x2;
        break;
    default:
        break;
    }
     itoa(x,c,10);
    return c[0];
}
char Calculate_InversePoland(List* Convert)
{
    Stack* Opnd=InitStack();
    int i;
    char c,e1,e2,res;
    List* L=Convert;
    while (L)
    {
        if(!isOperator(L->ch))
            PushStack(&Opnd,L->ch);
        else
        {
            e1=PopStack(&Opnd);
            e2=PopStack(&Opnd);
            res=Calculate(e1,L->ch,e2);
            PushStack(&Opnd,res);
        }
        L=L->next;
    }
    return res;
}

void Arithmetic(char* st)//采用逆波兰表示法表示运算操作(避免使用括号)实现多项式四则运算
{
    List *Convert=InversePoland(st);
    char ch[2];
    ch[0]=Calculate_InversePoland(Convert);
    int res=atoi(ch);
    printf("%d",res);

}


    
int main()
{
    char st[20];
    printf("请输入进行四则运算的多项式序号及运算方式,且首尾需加上#(如#(1+2)*3#表示1式与2式的和与3式相乘,注意要使用半角括号):");
    scanf("%s",st);
    Arithmetic(st);
}

谢谢指导!

2023/10/21 14:50
加载中...