[编程题]任务调度

本文介绍了一道关于任务调度的问题,通过使用最小堆作为优先级队列来解决。思路是根据任务的前序任务数量设定优先级,前序任务多的任务优先级低。在C++中,利用`priority_queue`实现此功能,而在Python中,代码更为简洁。博主通过对比C++和Python的实现,认识到Python在处理字符串方面的便捷性,并表示要提高专注力和编程技巧。
摘要由CSDN通过智能技术生成

关键词:最小堆,拓扑排序,字符串
试题链接:
任务调度
问题描述:
在这里插入图片描述
在这里插入图片描述
思路:
前序任务比较多的任务的优先度应该设定为较低值,可以把一个任务的前序任务数。
这道题的大体思路是:
先声明一个数据结构node,记录任务名称,任务的前序任务数。在优先队列里将前序任务数的任务优先级设定为较低值。对于输入的每一行,首先将当前行任务存入map中(如果是第一次出现),再将括号其后序任务存入map中(如果是第一次出现),并修改其前序任务数。

备注:
priority_queue 容器适配器定义了一个元素有序排列的队列。默认队列头部的元素优先级最高。因为它是一个队列,所以只能访问第一个元素,这也意味着优先级最高的元素总是第一个被处理。

感想:
个人感觉处理字符串还是python要方便一点。目前我做题的注意力还是不够集中,答题思路对了但总是会遗漏一些微不足道的地方,放进本地跑好久才找到问题…python虽慢但是稍微简练一点可能能避免很多问题…
在这里插入图片描述

解决方案:

#include<iostream>
#include<queue>
#include<map>
#include<string>
using namespace std;
struct node {
    string name;
    int num;

    friend bool operator < (node n1, node n2) {
        //前序任务多的优先级低
        if (n1.num != n2.num) {
            return n1.num > n2.num;
        }
        else {
            //前序任务相同,则按照字典序排列
            return n1.name > n2.name;
        }
    }
};

int main() {
    int n;
    cin >> n;
    priority_queue<node> pq; //优先队列
    map<string, node> mp;  //map方便访问

    for (int i = 0; i < n; i++) {
        string tmp;
        cin >> tmp;
        //遍历输入的字符串
        int j = 0;
        for (j = 0; j < tmp.size(); j++) {
            if (tmp[j] == '(') {
                break;
            }
        }
        string t = tmp.substr(0, j); //获取任务
        if (mp.count(t) == 0) //任务不在map中
        {
            node nd;
            nd.name = t;
            nd.num = 0;
            mp[t] = nd;
        }
        for (int k = j; k < tmp.size(); k++) {
            if (tmp[k] == ',' || tmp[k] == ')') {
                //后序任务数量增加,vector存储
                string latetask = tmp.substr(j + 1, k-j-1);
                if (latetask != "NULL") {
                    //后序任务没存入列表
                    if (mp.count(latetask) == 0) {
                        node nd;
                        nd.name = latetask;
                        nd.num = 1;
                        mp[latetask] = nd;
                    }
                    else {
                        //后序任务的前序任务数+1
                        mp[latetask].num++;
                    }
                    j = k;
                }
            }
        }
        pq.push(mp[t]); //令当前任务入队
    }
    for (int i = 0; i < n; i++) {
        cout << pq.top().name << " ";
        pq.pop();
    }
    return 0;
}

下面是大佬的用python写的解决方案,真就,太凝练了,tql,学习了:

# -*- coding: utf-8 -*-
res = []
for _ in range(int(input())):
    #-1去掉右括号,把NULL替换成u(比'Task'大就好),排序会靠后
    task = input()[:-1].replace('NULL', 'u').split('(')  
    #将后序任务也进行排序,后序任务排在前序任务的后面
    res.append([task[0], sorted(task[1].split(','))])   
#以后序任务为首要,再以前序任务为次要排序
res.sort(key=lambda x: (x[1], x[0]))           
print(" ".join(i[0] for i in res))

断点一点点调试了这个代码的每一步:
task = input()[:-1].replace(‘NULL’, ‘u’).split(’(’)
在这里插入图片描述
res.append([task[0], sorted(task[1].split(’,’))])
在这里插入图片描述
然后输入完毕后res:
在这里插入图片描述
一点点观察了一遍只觉得是我看了下次也写不出来的东西,之后加油吧。在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值