计算器带码3

阅读: 评论:0

计算器带码3

计算器带码3

#include<stdio.h>
#include <stdlib.h>
#include<malloc.h>
#define N 100        //定义接收字符串大小
typedef struct StackNode
{
    int num_ch;     //数字和符号都用int存储
    struct StackNode *next;
} StackNode;
//创建一个链栈 注意我的栈最后一个元素无意义但必须存在 因为方便在表达式末尾进行操作
StackNode *CreatStackNode()
{
    StackNode *q=(StackNode *)malloc(sizeof(StackNode));
    if(q==NULL)return NULL;
    q->num_ch =0;
    q->next=NULL;
    return q;
}
 //直接给最后一个元素赋值 并新建一个无意义的结点作为最后元素
int push(StackNode *p,int num)
{
    while(p->next!=NULL)
    {
        p=p->next;
    }
    p->num_ch=num;
    StackNode *q=(StackNode *)malloc(sizeof(StackNode));
    q->num_ch =0;
    q->next=NULL;
    p->next=q;
    return 0;
}
 // 最后一个无意义的直接free // 倒数第二个next置空,返回倒数第二的值
int Pop(StackNode *p)
{
    int tmp;
    if(p->next==NULL) return -1;//只有头,无值时无法Pop
    while(p->next->next!=NULL)
    {
        p=p->next;
    }
    tmp=p->num_ch;
    free(p->next);
    p->num_ch = 0;
    p->next = NULL;
    return tmp;
}//获取栈顶元素
int GetTop(StackNode *p)
{
    while(p->next->next!=NULL)
    {
        p=p->next;
    }
    return p->num_ch;
}
//判栈空 如果只剩一个结点(这是个无意义的) 那么就为空
int Empty(StackNode *p)
{
    if(p->next==NULL) return 1;
    return 0;
}
//显示栈的所有元素
void DispStack(StackNode *p)
{
    if(p->next==NULL) return;//只有头,无值时无法Pop
    while(p->next!=NULL)
    {
        printf("%d,",p->num_ch);
        p=p->next;
    }
    putchar(10);
}
//计算int变量的长度 例如1234长度为4
int sum_int(int in)
{
    int len=0;
    while(in!=0)
    {
        len++;
        in/=10;
    }
    return len;
}
//  符号优先级判断 返回: 1(opt1>opt2)   -1(opt1<opt2)   0(opt1=opt2) 注意符号的ASSIC码:43(+) 45(-) 42(*) 47(/)
int opt_max(int opt1,int opt2)
{
    if(42==opt1||47==opt1)
    {
        if(43==opt2||45==opt2)
        {
            return 1;
        }
        return 0;
    }
    else
    {
        if(42==opt2||47==opt2)
        {
            return -1;
        }
        return 0;
    }
}
//计算a和b在mode符号的运算结果
int cal(int a,int b,int mode)
{
    int re=-1;
    switch(mode)
    {
    case 43:
        re=a+b;
        break;
    case 45:
        re=a-b;
        break;
    case 42:
        re=a*b;
        break;
    case 47:
        re=a/b;
        break;
    default:
        break;
    }
    return re;
}
//计算表达式的值
int cal(char *str)
{
    int num1,num2,opt1,opt2;
    StackNode *num,*opt;
    num=CreatStackNode();  //创建数字栈
    opt=CreatStackNode();  //创建符号栈
    while(1)
    {
        if(''==*str)  // 读到字符串末尾
        {
             //如果最后一个符号是*或/则会剩下三个数字和两个符号
             //如果最后一个符号时+或-则会剩下两个数字和一个符号
             //结果只是算两次和算一次的问题
            opt1=GetTop(opt);
            if((42==opt1)||(47==opt1))
            {
                num2=Pop(num);
                num1=Pop(num);
                opt2=Pop(opt);
                push(num,cal(num1, num2, opt2));
            }
            num2=Pop(num);
            num1=Pop(num);
            opt2=Pop(opt);
            num1=cal(num1, num2, opt2);
            break;
        }
        else if('('==*str)    // 读到(,注意进栈的时(的ASSIC码40
        {
            push(opt,(int)'(');
            str++;
        }
        else if(')'==*str)    // 只是判断)不进入栈
        {
            while(1)  // 本循环会计算与)匹配的最近的(地方为之
            {
                if(40==GetTop(opt))  // 如果当前栈顶是(则弾栈退出
                {
                    Pop(opt);
                    break;
                }
                else    // 否则弾两个数字,一个符号进行运算
                {
                    // 结果入操作数栈
                    num2=Pop(num);
                    num1=Pop(num);
                    opt2=Pop(opt);
                    push(num,cal(num1, num2, opt2));
                }
            }
            str++;
        }
        else if(('9'>=*str)&&('0'<=*str))    // 如果取到数字则将数字进入栈
        {
            sscanf(str,"%d",&num1);
            push(num,num1);
            //将指针移动到当前数字到后面
            str=str+sum_int(num1);
        }
        else    // 取到一个符号
        {
            opt1=(int)*str++;
            while(1)
            {
                if( (1==Empty(opt))||(40 == GetTop(opt)) )  // 如果栈不空则遇到(则进入取到的符号
                {
                    // 为空时也要进栈
                    push(opt,opt1);
                    break;
                }
                else
                {
                    //取出符号栈顶元素
                    opt2=GetTop(opt);
                    if(0<opt_max(opt1,opt2))  // 当前获取的符号优先级大于栈顶符号
                    {
                        // 则进栈
                        push(opt,opt1);
                        break;
                    }
                    else    // 栈顶优先级高或者平级则
                    {
                        // 取两个数和栈顶符号进行运算
                        num2=Pop(num);
                        num1=Pop(num);
                        opt2=Pop(opt);
                        push(num,cal(num1,num2,opt2));
                    }
                }
            }
        }
    }
    free(num);
    free(opt);
    return num1;
}
int main()
{
    int flag=1;
    char buf[N]={0};
    printf("tt********************************$n");
    printf("tt*      欢迎您使用本计算器       *n");
    printf("tt********************************$n");
    printf("                                         作者:张治政n");
    printf("请输入一个运算式(eg:8+6*(9-3)+8/4注意括号为英文式的!):n");
    printf("当你想结束的时候输入一个纯数字就结束了!n");
    while(flag==1)
    {
        scanf("%s",buf);
        if(getchar()=="0000")
        {
            flag=0;
        }
        printf("%s=%dn",buf,cal(buf));
    }
    return 0;
}

本文发布于:2024-02-04 23:50:30,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170719212160889.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:计算器
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23