zh080223 2022-11-12 14:57 采纳率: 83.3%
浏览 39
已结题

c语言关于计算器的栈

c语言关于计算器的栈

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

#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
#define S 100

typedef struct{
    void* pBase;
    void* pTop;
    int sizeOfElement;
    int sizeOfStack;
}Stack;

typedef enum{
    ERROR=0,
    OK=1
}Status;

Status Stack_Init(Stack *pStack,int sizeOfElement);
Bool Stack_IsEmpty(Stack *pStack);
Bool Stack_IsFull(Stack *pStack);
int Stack_Length(Stack *pStack);
Status Stack_GetTop(Stack *pStack,void *pElem);
void Stack_Free(Stack *pStack);
void Stack_Clear(Stack *pStack);
Status Stack_Push(Stack *pStack,void *pData);
Status Stack_Pop(Stack *pStack,void *pElem);
Status Stack_Traverse(Stack *pStack,Status(*visit)());
float ConvertToFloat(char s[S]);
Status VisitInteger(void *pElem);
Status VisitChar(void *pElem);
Status VisitFloat(void *pElem);

Status Stack_Init(Stack *pStack,int sizeOfElement){
    pStack->pBase=(void*)malloc(sizeOfElement*STACK_INIT_SIZE);
    if(pStack->pBase==NULL){
        return ERROR;
    }
    pStack->pTop=pStack->pBase;
    pStack->sizeOfStack=STACK_INIT_SIZE;
    pStack->sizeOfElement=sizeOfElement;
}

Bool Stack_IsEmpty(Stack *pStack){
    if(pStack->pTop==pStack->pBase){
        return true;
    }
    else{
        return false;
    }
}

Bool Stack_IsFull(Stack *pStack){
    if(pStack->pTop-pStack->pBase==pStack->sizeOfStack){
        return true;
    }
    else{
        return false;
    }
}

int Stack_Length(Stack *pStack){
    return (pStack->pTop-pStack->pBase)/pStack->sizeOfElement;
}

Status Stack_GetTop(Stack *pStack,void *pElem){
    if(Stack_IsEmpty(pStack)){
        return ERROR;
    }
    memcpy(pElem,pStack->pTop-pStack->sizeOfElement,pStack->sizeOfElement);
    return OK;
}

void Stack_Free(Stack *pStack){
    free(pStack->pBase);
    pStack->pBase=NULL;
    pStack->pTop=NULL;
    pStack->sizeOfStack=0;
    return;
}

void Stack_Clear(Stack *pStack){
    pStack->pTop=pStack->pBase;
    return;
}

Status Stack_Push(Stack *pStack,void *pData){
    if(Stack_Length(pStack)>=pStack->sizeOfStack){
        int newSize=pStack->sizeOfStack+STACK_INCREMENT*pStack->sizeOfElement;
        void *Temp=realloc(pStack->pBase,newSize);
        if(pTemp==NULL){
            return ERROR;
        }
        pStack->pBase=pTemp;
        pStack->pTop=pStack->pBase+pStack->sizeOfStack*pStack->sizeOfElement;
        pStack->sizeOfStack=pStack->sizeOfStack+STACK_INCREMENT;
    }
    memcpy(pStack->pTop,pData,pStack->sizeOfElement);
    pStack->pTop=pStack->pTop+pStack->sizeOfElement;
    return OK;
}

Status Stack_Pop(Stack *pStack,void *pElem){
    if(Stack_IsEmpty(pStack)){
        return ERROR;
    }
    else{
        pStack->pTop=pStack->pTop-pStack->sizeOfElement;
        memcpy(pElem,pStack->pTop,pStack->sizeOfElement);
        return OK;
    }
}

Status Stack_Traverse(Stack *pStack,Status(*visit)()){
    int i,j;
    j=Stack_Length(pStack);
    for(i=0;i<n;++i){
        if(visit(pStack->pBase+i*pStack->sizeOfElement)==ERROR){
            return ERROR;
        }
    }
    return OK;
}

float ConvertToFloat(char s[S]){
    int i=0;
    float value=0;
    while(s[i]!='\0'&&s[i]!='.'){
        value=value*10+(s[i]-'0');
        i=i+1;
    }
    if(s[i]=='\0'){
        return value;
    }
    i=i+1;
    float weight=0.1;
    while(s[i]!='\0'){
        value=value+(s[i]-'0')*weight;
        weight=weight/10;
        i=1+1;
    }
    return value;
}

Status VisitInteger(void *pElem){
    printf("%d\t",*(int*)pElem);
    return OK;
}

Status VisitChar(void *pElem){
    printf("%c\t",*(char*)pElem);
    return OK;
}

Status VisitFloat(void *pElem){
    printf("%.12f\t",*(double*)pElem);
    return OK;
}

int main(){
    int i,j;
    j=100;
    Stack stack;
    
    int iData;
    Stack_Init(&stack,sizeof(int));
    for(i=0;i<j;++i){
        iData=rand()%100+1;
        printf("%d\t",iData);
        Stack_Push(&stack,&iData);
    }
    printf("\n");
    Stack_Traverse(&stack,VisitInteger);
    printf("\n");
    while(!Stack_IsEmpty(&stack)){
        Stack_Pop(&stack,&iData);
        printf("%d\t",iData);
    }
    Stack_Free(&stack);
    printf("\n\n");
    
    char ch;
    Stack_Init(&stack,sizeof(char));
    for(i=0;i<j;++i){
        ch=rand()%26+'A';
        printf("%c\t",ch);
        Stack_Push(&stack,&ch);
    }
    printf("\n");
    Stack_Traverse(&stack,VisitChar);
    printf("\n");
    while(!Stack_IsEmpty(&stack)){
        Stack_Pop(&stack,&ch);
        printf("%c\t",ch);
    }
    Stack_Free(&stack);
    printf("\n\n");    
}

求纠错

  • 写回答

4条回答 默认 最新

  • 关注

    代码:

    #define _CRT_SECURE_NO_WARNINGS 1
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h> 
    #define STACK_SIZE 100 
    #define STACK_INIT_SIZE 100
    /*定义栈初始容量*/
    #define STACK_INCREMENT 10
    /*定义栈增加容量*/
    #define M 100
    /*定义字符串的长度*/
    #define DEBUG 1
    typedef struct {
        int data[STACK_SIZE];
        int top;
        //int base;
        //int sizeOfElement;
        //int sizeOfStack;
    }StackData;
    /*构建数字栈*/
    typedef struct {
        char symbol[STACK_SIZE];
        int top;
        //int base;
        //int sizeOfElement;
        //int sizeOfStack;
    }StackSymbol;
    /*构建符号栈*/
    typedef enum {
        ERROR = 0,
        OK = 1
    }Status;
    Status StackData_Init(StackData* pStackData);
    /*参数:pStackData是指向数字栈的指针
     *返回:成功返回OK,失败返回ERROR
     */
    Status StackSymbol_Init(StackSymbol* pStackSymbol);
    /*参数:pStackSymbol是指向符号栈的指针
     *返回:成功返回OK,失败返回ERROR
     */
    int StackData_IsEmpty(StackData* pStackData);
    /*参数:pStackData是指向数字栈的指针
     *返回:如果为空,返回1;否则返回0
     */
    int StackSymbol_IsEmpty(StackSymbol* pStackSymbol);
    /*参数:pStackSymbol是指向符号栈的指针
     *返回:如果为空,返回1;否则返回0
     */
    int StackData_IsFull(StackData* pStackData);
    /*参数:pStackData是指向数字栈的指针
     *返回:如果为满,返回1;否则返回0
     */
    int StackSymbol_IsFull(StackSymbol* pStackSymbol);
    /*参数:pStackSymbol是指向符号栈的指针
     *返回:如果为满,返回1;否则返回0
     */
    Status StackData_Push(StackData* pStackData, int num);
    /*功能:将num的数值压入pStackData指向的栈
     *参数:pStackData是指向数字栈的指针
     *      num是要入栈的元素
     *返回:成功返回OK;否则返回ERROR
     */
    Status StackSymbol_Push(StackSymbol* pStackSymbol, char fuhao);
    /*参数:pStackSymbol是指向符号栈的指针
            fuhao是要入栈的元素
     *返回:成功返回OK;否则返回ERROR;
     */
    int StackData_GetTop(StackData* pStackData);
    /*参数:pStackData是指向数字栈的指针
     *返回:返回该栈顶元素
     */
    char StackSymbol_GetTop(StackSymbol* pStackSymbol);
    /*参数:pStackSymbol是指向符号栈的指针
     *返回:返回该栈顶元素
     */
    int StackData_Pop(StackData* pStackData);
    /*参数:pStackData是指向数字栈的指针
     *返回:返回该栈顶元素
     */
    char StackSymbol_Pop(StackSymbol* pStackSymbol);
    /*参数:pStackSymbol是指向符号栈的元素
     *返回:返回该栈顶元素
     */
    void StackData_Free(StackData* pStackData);
    /*功能:释放pStackData指向的栈的元素的内存
     *参数:pStackData是指向数字栈的指针
     *返回:无
     */
    void StackSymbol_Free(StackSymbol* pStackSymbol);
    /*功能:释放pStackSymbol指向的栈的元素的内存
     *参数:pStackSymbol是指向符号栈的指针
     *返回:无
     */
    void StackData_Clear(StackData* pStackData);
    /*功能:将pStackData指向的栈的元素清空
     *参数:pStackData是指向数字栈的指针
     *返回:无
     */
    void StackSymbol_Clear(StackSymbol* pStackSymbol);
    /*功能:将pStackSymbol指向的栈的元素清空
     *参数:pStackSymbol是指向符号栈的指针
     *返回:无
     */
    Status StackData_Traverse(StackData* pStackData, Status(*visit)());
    /*功能:遍历pStackData指向的栈,对栈中的每个元素执行visit操作
     *参数:pStackData是指向数字栈的指针
     *返回:如果成功,返回OK;否则返回ERROR
     */
    Status StackSymbol_Traverse(StackSymbol* pStackSymbol, Status(*visit)());
    /*功能:遍历pStackSymbol指向的栈,对栈中每个的元素执行visit操作
     *参数:pStackSymbol是指向符号栈的指针
     *返回:如果成功,返回OK;否则返回ERROR
     */
    float ConvertToFloat(char m[M], float r);
    /*功能:将数字串转为浮点数
     *参数:m[M]是原字符串
     *返回:返回结果浮点数
     */
    int Judge(char x);
    /*
     *功能:判断运算符的类型并分级
     *参数:运算符的字符
     *返回:字符代表的级数
     */
    int Culculate(int x1, int x2, char s);
    /*
     *功能:对数字进行计算
     *参数:x1是第一个数字
            x2是第二个数字
            s是运算符
     *返回:运算结果
     */
    Status StackData_Init(StackData* pStackData) {
        pStackData->top = -1;
        //pStackData->base = -1;
        return OK;
    }
    Status StackSymbol_Init(StackSymbol* pStackSymbol) {
        pStackSymbol->top = -1;
        //pStackSymbol->base = -1;
        return OK;
    }
    int StackData_IsEmpty(StackData* pStackData) {
        if (pStackData->top == -1) {
            return 1;
        }
        else {
            return 0;
        }
    }
    int StackSymbol_IsEmpty(StackSymbol* pStackSymbol) {
        if (pStackSymbol->top == -1) {
            return 1;
        }
        else {
            return 0;
        }
    }
    int StackData_IsFull(StackData* pStackData) {
        if (pStackData->top == STACK_SIZE - 1) {
            return 1;
        }
        else {
            return 0;
        }
    }
    int StackSymbol_IsFull(StackSymbol* pStacksymbol) {
        if (pStacksymbol->top == STACK_SIZE - 1) {
            return 1;
        }
        else {
            return 0;
        }
    }
    Status StackData_Push(StackData* pStackData, int num) {
        if (StackData_IsFull(pStackData))
            return ERROR;
    
        pStackData->top++;
        pStackData->data[pStackData->top] = num;
        return OK;
    }
    Status StackSymbol_Push(StackSymbol* pStackSymbol, char fuhao) {
        if (StackSymbol_IsFull(pStackSymbol))
            return ERROR;
        pStackSymbol->top++;
        pStackSymbol->symbol[pStackSymbol->top] = fuhao;
        return OK;
    }
    int StackData_GetTop(StackData* pStackData) {
        return pStackData->data[pStackData->top];
    }
    char StackSymbol_GetTop(StackSymbol* pStackSymbol) {
        return pStackSymbol->symbol[pStackSymbol->top];
    }
    int StackData_Pop(StackData* pStackData) {
        int i;
        i = pStackData->data[pStackData->top];
        pStackData->top--;
        return i;
    }
    char StackSymbol_Pop(StackSymbol* pStackSymbol) {
        char a;
        a = pStackSymbol->symbol[pStackSymbol->top];
        pStackSymbol->top--;
        return a;
    }
    float ConvertToFloat(char m[M], float r) {
        int i = 0;
        float value = 0;
        while (m[i] != '\0' && m[i] != '.') {
            value = value * 10 + (m[i] - '0');
            i = i + 1;
        }
        if (m[i] == '\0') {
            return value;
        }
        i = i + 1;
        float weight = 0.1;
        while (m[i] != '\0') {
            value = value + (m[i] - '0') * weight;
            weight = weight / 10;
            i = i + 1;
        }
        return value;
    }
    int Judge(char x) {
        if (x == '(') {
            return 4;
        }
        else if (x == '+' || x == '-') {
            return 1;
        }
        else if (x == '*' || x == '/') {
            return 2;
        }
        else if (x == '^') {
            return 3;
        }
        else if (x == ')') {
            return 0;
        }
    }
    int Culculate(int x1, int x2, char s) {
        int result = 0; //这里初始化一下
        switch (s) {
        case '+': {
            result = x1 + x2;
            break;
        }
        case '-': {
            result = x1 - x2;
            break;
        }
        case '*': {
            result = x1 * x2;
            break;
        }
        case '/': {
            result = x1 / x2;
            break;
        }
        case '^': {
            result = pow(x1, x2);
            break;
        }
        }
        return result;
    }
    
    
    Status check(char left, char right) {
        if (left == '(' && right == ')')
            return OK;
        else if (left == '[' && right == ']')
            return OK;
        else
            return ERROR;
    }//判断括号
    
    
    Status isSymbol(char c) {
        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '[' || c == ']' || c == '^')
            return OK;
        else
            return ERROR;
    }
    Status isNum(char e) {
        if (e >= '0' && e <= '9')
            return OK;
        else
            return ERROR;
    }
    
    //执行一条公式的计算
    int DosingleCaculate(char s[]) {
        StackData data;      // = (StackData*)malloc(sizeof(StackData));  //因为结构体有明确的内存,没必要再重新malloc了
        StackSymbol symbol;  // = (StackSymbol*)malloc(sizeof(StackSymbol));
        StackSymbol eff; //判断括号是否匹配
        StackData_Init(&data);
        StackSymbol_Init(&symbol);
        StackSymbol_Init(&eff);
           
        int len, n;
        len = strlen(s);
        s[len] = '#';
        len++;
        int i;
        int a, b, c = 0;
        for (i = 0; i < len; i++) {
            if (s[i] == '(' || s[i] == '[') {
                StackSymbol_Push(&eff, s[i]);
            }
            else if (s[i] == ')' || s[i] == ']') {
                if (check(StackSymbol_GetTop(&eff), s[i]) == 1) {
                    StackSymbol_Pop(&eff);
                }
                else
                {
                    //printf("ERROR_02"); //括号不匹配
                    return 0;
                }
            }
        }//判断括号是否匹配
        /*for (i = 0; i < len - 1; i++) {
            if (isSymbol(s[i]) == 0 && isNum(s[i]) == 0 && s[i] != '.') {
                //printf("ERROR_02"); //输入非法
                return 0;
            }//判断是否是数字和运算符号
        }*/
        i = 0;
        if (s[0] == '+' || s[0] == '-' || s[0] == '*' || s[0] == '/' || s[0] == '^') { //先不考虑浮点型
            //printf("ERROR_02");
            return 0;
        }
        while (s[i] != '#') {
            int x = 0;
            if (isNum(s[i]) == OK) {
                while (s[i] >= '0' && s[i] <= '9') {
                    x *= 10;
                    x += s[i++] - '0';
                }
                StackData_Push(&data, x);
                continue;
            }
            else {
                char theta = s[i];
                while (StackSymbol_IsEmpty(&symbol) == 0 && StackSymbol_GetTop(&symbol) != '(' && Judge(StackSymbol_GetTop(&symbol)) >= Judge(s[i])) { //运算符栈不为空,并且栈顶运算符的优先级比当前运算符高,则出栈两个数进行计算
                    a = StackData_GetTop(&data);
                    StackData_Pop(&data);
                
                    b = StackData_GetTop(&data);
                    StackData_Pop(&data);
                    if (a == 0 && StackSymbol_GetTop(&symbol) == '/')
                    {
                        printf("除数为0\n");
                        return 0;
                    }
                    c = Culculate(b, a,StackSymbol_GetTop(&symbol));
                    StackData_Push(&data, c);
                    StackSymbol_Pop(&symbol);
                }
                if (Judge(theta) == 0 && Judge(StackSymbol_GetTop(&symbol)) == 4) { //当前为右括号,并且运算符栈顶为左括号,那么左括号直接出栈
                    StackSymbol_Pop(&symbol);
                }
                if (Judge(theta) != 0) {
                    StackSymbol_Push(&symbol, theta);
                }
                i++;
            }
        }
        while (StackSymbol_IsEmpty(&symbol) == 0) {
            a = StackData_GetTop(&data);
            StackData_Pop(&data);;
            b = StackData_GetTop(&data);
            StackData_Pop(&data);;
            if (a == 0 && StackSymbol_GetTop(&symbol) == '/')
            {
                printf("除数为0\n");
                return 0;
            }
            c = Culculate(b, a,StackSymbol_GetTop(&symbol));
            StackData_Push(&data, c);
            StackSymbol_Pop(&symbol);
        }
        printf("%d\n", StackData_GetTop(&data));
        return StackData_GetTop(&data);
    }
    
    
    int main()
    {
        char all[100] = { 0 }; //保存所有的公式 ,长度根据需要调整
        int res = 0;
        FILE* fp = fopen("1.txt", "r");
        if (fp == 0)
        {
            printf("1.txt open error\n");
            return 0;
        }
        FILE* fp2 = fopen("2.txt", "w");
    
        while (!feof(fp))
        {
            fgets(all, 100, fp); //逐行读取
            int len = strlen(all);
            if (len == 0)
                continue; //避免读入空行
            if (all[len - 1] == '\n')
                all[len - 1] = '\0';
            printf("%s\n", all);
            res = DosingleCaculate(all);
            fprintf(fp2, "%d\n", res);
        }
        fclose(fp);
        fclose(fp2);
    
        return 0;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 12月4日
  • 已采纳回答 11月26日
  • 创建了问题 11月12日

悬赏问题

  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真