首页 > 其他分享 >2024/11/19日 日志 数据结构实验(2)---栈实现表达式求值、队列应用(蓝桥杯)

2024/11/19日 日志 数据结构实验(2)---栈实现表达式求值、队列应用(蓝桥杯)

时间:2024-11-19 20:39:52浏览次数:1  
标签:11 char return int top 蓝桥 postfix 求值 表达式

栈实现表达式求值
问题:https://pintia.cn/problem-sets/1858366427985383424/exam/problems/type/7?problemSetProblemId=1858366732315615232
解答:

点击查看代码
#include<bits/stdc++.h>

using namespace std;
//运算符优先级
int precedence(char op) {
    switch (op) {
    case '+':
    case '-':
        return 1;
    case '*':
    case '/':
        return 2;
    default:
        return 0;
    }
}
//转换为后缀表达式
int infixToPostfix(const string& infix, string& postfix) {
    stack<char>s;
    bool prevWasOp = true; //前一个字符是否是运算符
    int openPar = 0; //开括号数量

    for (char c : infix) {
        if (isspace(c)) {
            continue;//跳过空格
        }
        if (isdigit(c)) {
            if (!prevWasOp) {
                return -2;//表达式缺操作数
            }
            postfix += c;//直接将数字加入后缀表达式
            prevWasOp = false;//当前为操作数
        }
        else if (c == '(') {
            s.push(c);
            openPar++;
            prevWasOp = true;
        }
        else if (c == ')') {
            while (!s.empty() && s.top() != '(') {
                postfix += s.top();
                s.pop();
            }
            if (s.empty()) {
                return -1;//缺少右括号
            }
            s.pop();//弹出'('
            openPar--;
            prevWasOp = false; //')'后面可以是运算符
        }else {
            if (precedence(c) == 0) {
                //无效字符
            }
            if (prevWasOp) {
                return -2;//表达式缺少操作数
            }
            while (!s.empty() && precedence(s.top()) >= precedence(c)) {
                postfix += s.top();
                s.pop();
            }
            s.push(c);
            prevWasOp = true;//当前是运算符
        }
    }
    while (!s.empty()) {
        char top = s.top();
        if (top == '(') {
            return -1;//缺少右括号
        }
        postfix += top;
        s.pop();
    }
    return openPar > 0 ? -1: 0;
}
//计算后缀表达式的值
int evaluatePost(const string& postfix) {
    stack<int>s;
    for (char c : postfix) {
        if (isdigit(c)) {
            s.push(c - '0');//将字符数字转换为整数
        }
        else {
            int b = s.top();
            s.pop();
            int a = s.top();
            s.pop();
            switch (c) {
            case '+':s.push(a + b); break;
            case '-':s.push(a - b); break;
            case '*':s.push(a * b); break;
            case '/':s.push(a / b); break;
            }
        }
    }
    return s.top();
}

int main() {
    string in;
    string post;
    getline(cin,in);
    
    int result = infixToPostfix(in, post);
    if (result == -1) {
        cout << "ERROR:缺少括号"<<endl;
    }
    else if (result == -2) {
        cout << "ERROR:表达式缺操作数" << endl;
    }
    else {
        cout << post << endl;
        int value = evaluatePost(post);
        cout << value ;
    }

    return 0;
}
思路:对于式子转换,先确定符号的优先级,再使用一个栈stacks来存储运算符和处理括号。遍历中缀表达式的每个字符,根据字符类型进行不同的处理:如果是空格,跳过。如果是数字,直接添加到后缀表达式。如果是左括号(,压入栈中并增加开括号计数。如果是右括号),弹出栈顶元素直到遇到左括号,然后弹出左括号。如果是运算符,比较优先级并根据需要弹出栈顶元素,然后将当前运算符压入栈中。函数返回值用于指示转换过程中是否出现错误,如缺少括号或表达式缺操作数。 计算后缀表达式的值,使用一个栈stacks来存储操作数。遍历后缀表达式的每个字符,如果是数字则压入栈中,如果是运算符则从栈中弹出两个操作数进行计算,并将结果压回栈中。最终,栈顶的元素即为后缀表达式的计算结果。 补充:C语言示例代码,较C++写法上会复杂
点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXSIZE 100

typedef struct {
    char data[MAXSIZE];
    int top;
} Stack;

// 栈操作
void initStack(Stack *s) {
    s->top = -1;
}

int isEmpty(Stack *s) {
    return s->top == -1;
}

int isFull(Stack *s) {
    return s->top == MAXSIZE - 1;
}

void push(Stack *s, char c) {
    if (!isFull(s)) {
        s->data[++(s->top)] = c;
    }
}

char pop(Stack *s) {
    if (!isEmpty(s)) {
        return s->data[(s->top)--];
    }
    return '\0'; // 空栈时返回空字符
}

char peek(Stack *s) {
    if (!isEmpty(s)) {
        return s->data[s->top];
    }
    return '\0'; // 空栈时返回空字符
}

// 运算符优先级
int precedence(char op) {
    switch (op) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

// 转换为后缀表达式
int infixToPostfix(const char *infix, char *postfix) {
    Stack s;
    initStack(&s);
    int j = 0;
    int prevWasOperator = 1; // 表示前一个字符是否是运算符
    int openParentheses = 0; // 记录开括号数量

    for (int i = 0; infix[i] != '\0'; i++) {
        char c = infix[i];

        if (isspace(c)) {
            continue; // 跳过空格
        }

        if (isdigit(c)) {
            if (!prevWasOperator) {
                return -2; // 表达式缺操作数
            }
            postfix[j++] = c; // 直接将数字加入后缀表达式
            prevWasOperator = 0; // 当前是操作数
        } else if (c == '(') {
            push(&s, c);
            openParentheses++;
            prevWasOperator = 1; // '('后面可以是操作数
        } else if (c == ')') {
            while (!isEmpty(&s) && peek(&s) != '(') {
                postfix[j++] = pop(&s);
            }
            if (isEmpty(&s)) {
                return -1; // 缺少右括号
            }
            pop(&s); // 弹出 '('
            openParentheses--;
            prevWasOperator = 0; // ')'后面可以是运算符
        } else {
            if (precedence(c) == 0) {
                return -3; // 无效字符
            }
            if (prevWasOperator) {
                return -2; // 表达式缺操作数
            }
            while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(c)) {
                postfix[j++] = pop(&s);
            }
            push(&s, c);
            prevWasOperator = 1; // 当前是运算符
        }
    }

    while (!isEmpty(&s)) {
        char top = pop(&s);
        if (top == '(') {
            return -1; // 缺少右括号
        }
        postfix[j++] = top;
    }

    postfix[j] = '\0'; // 结束后缀表达式
    return openParentheses > 0 ? -1 : 0; // 确保所有括号匹配
}

// 计算后缀表达式的值
int evaluatePostfix(const char *postfix) {
    Stack s;
    initStack(&s);
    for (int i = 0; postfix[i] != '\0'; i++) {
        char c = postfix[i];
        if (isdigit(c)) {
            push(&s, c - '0'); // 将字符数字转换为整数
        } else {
            int b = pop(&s);
            int a = pop(&s);
            switch (c) {
                case '+': push(&s, a + b); break;
                case '-': push(&s, a - b); break;
                case '*': push(&s, a * b); break;
                case '/': push(&s, a / b); break;
            }
        }
    }
    return pop(&s); // 返回最终结果
}

int main() {
    char infix[MAXSIZE];
    char postfix[MAXSIZE];

    printf("请输入数学表达式: ");
    fgets(infix, MAXSIZE, stdin);
    
    int result = infixToPostfix(infix, postfix);
    if (result == -1) {
        printf("ERROR:缺少括号\n");
    } else if (result == -2) {
        printf("ERROR:表达式缺操作数\n");
    } else if (result == -3) {
        printf("ERROR:无效字符\n");
    } else {
        printf("后缀表达式: %s\n", postfix);
        int value = evaluatePostfix(postfix);
        printf("结果: %d\n", value);
    }

    return 0;
}

队列应用(蓝桥杯)
题目:https://pintia.cn/problem-sets/1858366427985383424/exam/problems/type/7?problemSetProblemId=1858366732315615233
解答:

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int MAXM = 1005;
int M;
string inflx[MAXM];
vector<string>post;
queue<string> vip;
queue<string> nor;

void queueup(const string *inflx) {
    for (int i = 1; i <= M; i++) {
        string in = inflx[i];
        if (in.substr(0, 3) == "IN ") {
            string name = in.substr(3);
            char type = name.back();
            name.pop_back(); //删除末尾类型
            name.pop_back();//删除空格
            if (type == 'V') {
                vip.push(name);
            }
            else if (type == 'N') {
                nor.push(name);
            }
        }else if (in.substr(0, 4) == "OUT ") {
            char type = in[4];
            if (type == 'V' && !vip.empty()) {
                vip.pop();
            }
            else if (type == 'N' &&!nor.empty()) {
                nor.pop();
            }
        }
    }
}


int main() {
    cin >> M;
    cin.ignore();
    for (int i = 1; i <= M; i++) {
        getline(cin, inflx[i]);
    }
    queueup(inflx);
    while (!vip.empty()) {
        post.emplace_back(vip.front());
        vip.pop();
    }
    while (!nor.empty()) {
        post.emplace_back(nor.front());
        nor.pop();
    }
    for (int i = 0; i < post.size(); i++) {
        cout << post[i];
        if (i != post.size() - 1) {
            cout << endl;
        }
    }
    return 0;
}
思路:遍历所有的指令。对于每个指令,检查是否是“IN”指令(对象进入)或“OUT”指令(对象退出)。如果是“IN”指令,解析出对象的名称和类型,根据类型将对象名称加入到对应的队列中。如果是“OUT”指令,检查对应的队列是否非空,如果是,则弹出队列中的对象。利用容器储存结果,按要求输出。

补充:https://blog.csdn.net/qq_47332831/article/details/123400882

标签:11,char,return,int,top,蓝桥,postfix,求值,表达式
From: https://www.cnblogs.com/MoonbeamsC/p/18555560

相关文章

  • 2024/11/18日 日志 数据结构实验(1)---链表逆置、线性表A,B顺序存储合并、双向循环链表应
    链表逆置题目:https://pintia.cn/problem-sets/1855808612225744896/exam/problems/type/6?problemSetProblemId=1855808768018968576解答:点击查看代码structListNode*reverse(structListNode*head){structListNode*prev=NULL;structListNode*current=head;......
  • 1119鲜花——咸鱼
    我没有任何天分我却有梦的天真也许,现在的我,就是茫茫人海里的一条鱼压力人生中最难熬的几天,停了几个月的课感觉文化课的无力感与OI的压迫感逼的我喘不过来气化学不会,物理没有信心,OI得不到像样的反馈也许一年前的我,还会这样浑浑噩噩即便NOIP近在眼前但是如今不同11月的7,8,9......
  • 2024年11月一区SCI-逃离优化算法Escape Algorithm-附Matlab免费代码
    引言本期介绍了一种受人群疏散行为的启发的元启发式优化算法,称为逃离优化算法EscapeAlgorithm,ESC。该算法于2024年11月最新发表在JCR1区,中科院2区TopSCI期刊 ArtificialIntelligenceReview。ESC的灵感来自于人们在紧急疏散期间的行为。本节解释人群疏散系统的背景,以及......
  • SS241119C. 甜果(sugar)
    SS241119C.甜果(sugar)题意有\(n\)个人,每个人初始有\(a_i\)颗糖果,有\(n\)个事件,事件\(i\)是如果\(a_i>a_{b_i}\),那么\(a_i':=a_i+w_i\)。问所有事件以随机的排列的顺序依次发生后,每个人的期望糖果数量。思路即求每个事发生的概率\(p_i\),那么\(ans_i=a_i......
  • [考试记录] 2024.11.19 noip模拟赛17
    T1选取字符串warning❗:本题解前缀含量过高。挺典的kmp。考虑到题目中的串都是一个串的前缀,那么所选出来的串,他们的前缀一定是最短的那个串。不妨直接枚举每一个前缀,也就是枚举每一个串,看他们是否可以作为前缀出现,hash即可,复杂度\(\mathcal{O}(N^2)\)。换个思路,考虑有多......
  • 2024/11/19
    队列应用(蓝桥杯)分数10作者liudan单位石家庄铁道大学CLZ银行只有两个接待窗口,VIP窗口和普通窗口,VIP用户进入VIP窗口排队,剩下的进入普通窗口排队。现有M次操作,操作有四种类型,如下:INnameV:表示一名叫name的用户到VIP窗口排队OUTV:表示VIP窗口队头的用户离开......
  • 倒计时 4 天! 11 月 23 日成都站 Meetup 分享议题抢先看
    在云原生浪潮持续席卷的当下,技术的迭代与创新推动着企业加速迈向高效智能化。KubeSphere社区始终致力于为开发者、架构师和企业提供一流的云原生技术交流平台,而此次在成都举办的Meetup沙龙便是一次技术分享与思想碰撞的绝佳机会。11月23日,KubeSphere社区联合Higress社区将......
  • 11.16
    @所有人网络安全C10-2024.11.17作业:水平越权&垂直越权漏洞实验水平越权垂直越权密码修改逻辑漏洞实验3、验证码安全(1)验证码绕过(onclient)+验证码绕过(onserver)在client于server中由于验证码在使用后没有即使的在服务器段刷新或者作废,所以可以重复使用验证码绕过(onserver)实验中,......
  • 24.11.19
    今日写大作业实验三:JFinal极速开发框架实验 (2024.11.29日前完成)    根据参考资料,学习JFinal极速开发框架的使用并如下任务:    任务一:了解Maven及其使用方法,总结其功能作用(占20%)    任务二:学习JFinal框架,基于Maven建立JFinal工程,并对JFinal框架功能进行总结介绍(占3......
  • 微软Office 2021 24年11月授权版
    概述MicrosoftOfficeLTSC2021专业增强版是微软公司推出的一款专为企业客户设计的办公软件套件。该版本于2024年11月进行了批量许可版更新推送,旨在为企业用户提供更加稳定、高效的办公体验。主要特点LOGO设计趋势强化:新版Office将棱角改为圆角风格,提高了企业的辨识度。......