首页 > 其他分享 >简单计算器

简单计算器

时间:2022-11-12 22:02:36浏览次数:34  
标签:%. return 计算器 Next 简单 2lf else Data

思路 将中缀表达式转化为后缀表达式处理 

数据结构 栈

注 目前只适用 10以内的带括号的 +-*/^ 运算

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

#define ElementType char
#define ERROR -1

// 定义栈的结构
typedef struct SNode *PtrToSNode;
struct SNode{
    ElementType Data;
    PtrToSNode Next;
};
typedef PtrToSNode Stack;

// 定义链表的结构
typedef struct LNode *PtrToLNode;
struct LNode{
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;
typedef PtrToLNode Position;
// 定义一个头节点 Next指的头节点下一个节点 Last指的链表最后一个节点
typedef struct LHeadNode *LHead;
struct LHeadNode{
    ElementType Data;
    PtrToLNode Next;
    Position Last;
};

// 定义一个数据为double的栈 用于计算
typedef struct SDoubleNode *PtrToSDoubleNode;
struct SDoubleNode{
    double Data;
    PtrToSDoubleNode Next;
};
typedef PtrToSDoubleNode DoubleStack;

Stack CreateStack(void){ // 带头节点的栈
    Stack S;
    S = (Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}

bool IsEmpty(Stack S){
    return (S->Next == NULL);
}

bool Push(Stack S, ElementType X){
    PtrToSNode q;
    q = (PtrToSNode)malloc(sizeof(struct SNode));
    q->Data = X;
    q->Next = S->Next;
    S->Next = q;
    return true;
}

ElementType Pop(Stack S){
    PtrToSNode FirstCell;
    ElementType TopElem;
    
    if(IsEmpty(S)){
        printf("Stack is Empty\n");
        return ERROR;
    }else{
        FirstCell = S->Next;
        TopElem = FirstCell->Data;
        S->Next = FirstCell->Next;
        free(FirstCell);
        return TopElem;
    }
}

LHead CreateList(void){   // 创造带头节点的链表
    LHead L = (LHead)malloc(sizeof(struct LHeadNode));
    L->Next = NULL;
    L->Last = NULL;
    return L;
}

int ListIsEmpty(LHead L){ // 判断链表是否为空 是 返回1 否则返回0
    if(L->Last == NULL)
        return 1;
    return 0;
}

void TailInsert(LHead L,ElementType X){ //链表尾部插入
    PtrToLNode p = (PtrToLNode)malloc(sizeof(struct LNode));
    p->Data = X;
    p->Next = NULL;
    if(ListIsEmpty(L)){
        L->Next = p;
        L->Last = p;
    }else{
        L->Last->Next = p;
        L->Last = p;
    }
}

void TavelList(LHead L){
    Position p = L->Next;
    while (p) {
        printf("%c ",p->Data);
        p = p->Next;
    }
    printf("\n");
}

DoubleStack CreateDoubleStack(void){ // 带头节点的栈
    DoubleStack S;
    S = (DoubleStack)malloc(sizeof(struct SDoubleNode));
    S->Next = NULL;
    return S;
}

bool DoubleStackIsEmpty(DoubleStack S){
    return (S->Next == NULL);
}

bool DoubleStackPush(DoubleStack S, double X){
    DoubleStack q;
    q = (DoubleStack)malloc(sizeof(struct SDoubleNode));
    q->Data = X;
    q->Next = S->Next;
    S->Next = q;
    return true;
}

double DoubleStackPop(DoubleStack S){
    DoubleStack FirstCell;
    double TopElem;
    
    if(DoubleStackIsEmpty(S)){
        printf("Stack is Empty\n");
        return ERROR;
    }else{
        FirstCell = S->Next;
        TopElem = FirstCell->Data;
        S->Next = FirstCell->Next;
        free(FirstCell);
        return TopElem;
    }
}
/*给出运算符给出优先级 优先级越大 则返回值越大
 +- --> 1
 / * --> 2
 ^ --> 3
 ( 在入栈前为4 在栈中为0 用tag记是否在栈中 1代表是 0代表不是
 */
int CaculatePriority(char c,int tag){
    if(c == '+' || c == '-'){
        return 1;
    }else if(c == '/' || c == '*'){
        return 2;
    }else if (c == '^'){
        return 3;
    }else{
        if(tag == 0){
            return 4;
        }else{
            return 0;
        }
    }
}

LHead ChangeExpression(void){  //将中缀表达式转化为后缀表达式
    char c,t;  // c 输入元素 t 栈中符号
    int c1,t1; // c1 输入符号优先级 s 栈中符号优先级
    Stack s = CreateStack(); // 存符号的临时栈
    LHead l = CreateList(); // 存后缀表达式的链表
    scanf("%c",&c);
    while (c!='\n') {
        if(c <= '9' && c >= '0'){
            TailInsert(l, c);
        }else{
            if(IsEmpty(s)){
                Push(s, c);
            }else if(c == ')'){
                t = Pop(s);
                while (t != '(') {
                    TailInsert(l, t);
                    t = Pop(s);
                }
            }else{
                c1 = CaculatePriority(c, 0);
                t = s->Next->Data;
                t1 = CaculatePriority(t, 1);
                if(c1 > t1){
                    Push(s, c);
                }else{
                    do{
                        t = Pop(s);
                        TailInsert(l, t);
                        if(IsEmpty(s)){
                            break;
                        }
                        t = s->Next->Data;
                        t1 = CaculatePriority(t, 1);
                    }while(c1 <= t1);
                    Push(s, c);
                }
            }
        }
        scanf("%c",&c);
    }
    t = Pop(s);
    TailInsert(l, t);
    return l;
}

double CaculateExpresion(LHead L){ // 计算后缀表达式
    Position p = L->Next;
    DoubleStack s = CreateDoubleStack();
    double a,b,t;
    while (p!=NULL) {
        if(p->Data <= '9' && p->Data >= '0'){
            t = p->Data - '0';
            DoubleStackPush(s, t);
        }else if (p->Data == '+'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b + a;
            DoubleStackPush(s, t);
//            printf("%.2lf + %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '-'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b - a;
            DoubleStackPush(s, t);
 //           printf("%.2lf - %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '*'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b * a;
            DoubleStackPush(s, t);
//            printf("%.2lf * %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '/'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b / a;
            DoubleStackPush(s, t);
 //           printf("%.2lf / %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '^'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = pow(b, a);
            DoubleStackPush(s, t);
 //           printf("%.2lf ^ %.2lf = %.2lf\n",b,a,t);
        }
        p = p->Next;
    }
    t = DoubleStackPop(s);
    return t;
}

int main(){
    LHead l = ChangeExpression();
    TavelList(l);
    double s;
    s = CaculateExpresion(l);
    printf("%.2lf",s);
    return 0;
}

 

标签:%.,return,计算器,Next,简单,2lf,else,Data
From: https://www.cnblogs.com/xinrenbool/p/16884784.html

相关文章

  • 云原生安全:Trivy + Harbor实现镜像漏洞的简单、高效扫描
    作者|李大白本文已参与「开源摘星计划」,欢迎正在阅读的你加入。活动链接:​ ​https://github.com/weopenprojects/WeOpen-Star[文章来源]:《Harbor进阶实战》公众号......
  • C# 判断网络是连接到互联网(简单有效)
    [System.Runtime.InteropServices.DllImport("wininet")]privateexternstaticboolInternetGetConnectedState(outintconnectionDescription,intreservedValue);......
  • 使用JFinal实现简单的学生管理系统
    JFinal简介Controller是JFinal核按心类美之一,该类作为MVC模式中的控制器。基于JFinal的Web应用的控制器需要继承该类。Controller是定义Action方法的地点,是组织Action的一......
  • 一个动态规划的简单例题
    动态规划(DynamicProgramming)它是计算机中解决最优化问题的一种方法,效率高,速度快。一般思路:1、穷举法/暴力搜索2、记忆化搜索/剪枝3、改写成迭代形式思想1.动......
  • 简单几步,轻松导出喜马拉雅音频到本地端
    平时有听喜马拉雅跑步的习惯,但是总用手机听不够专注,所以想了一个办法直接将喜欢的音频下载到播放器里。 之前有人说手机端导出的音频如果放到播放器里,要进行格式的转换,......
  • C++一元多项式计算器的设计与实现
    C++一元多项式计算器的设计与实现七、一元多项式计算器的设计与实现1.基于动态数组或者链表实现--元多项式的计算,可以使用STL的vector或者list。2.在系统中需要提供必......
  • FileChannel 文件流的简单使用
    FileChannel注意:FileChannel只能工作在阻塞模式下复制代码新建FileChannel是一个抽象类,所以不能直接创建对象创建一个FileChannel有以下三种方式:创建一个FileInpu......
  • 一个简单的查询学生信息的接口测试
    Test作业提交学习笔记编写一个业务接口(登录,查找学生等)打包成jar包在本机上面执行相应的命令,通过浏览器访问接口获得数据。(可选)将该jar包放在服务器上面运行,通......
  • C++时间计算器
    C++时间计算器六、时间计算器的设计与实现1.采用面向对象的方法实现时间DateTime的模拟和计算,主要属性包括year,month,day,hour,minute,second,wday(该星期中的第几天)......
  • linux sed 简单使用
    操作系统最大的一个好处是它带有各种各样的实用工具。存在如此之多不同的实用工具,几乎不可能知道并了解所有这些工具。可以简化关键情况下操作的一个实用 工具是 sed。它......