华为招聘机试整理8:操作系统任务调度问题
题目:操作系统任务调度问题
操作系统任务分为系统任务和用户任务两种。当中,系统任务的优先级 < 50,用户任务的优先级 >= 50且 <= 255。优先级大于255的为非法任务,应予以剔除。现有一任务队列task[]。长度为n,task中的元素值表示任务的优先级,数值越小,优先级越高。函数scheduler实现例如以下功能。将task[] 中的任务依照系统任务、用户任务依次存放到 system_task[] 数组和 user_task[] 数组中(数组中元素的值是任务在task[] 数组中的下标),并且优先级高的任务排在前面。数组元素为-1表示结束。
比如:
task[] = {0, 30, 155, 1, 80, 300, 170, 40, 99}
system_task[] = {0, 3, 1, 7, -1}
user_task[] = {4, 8, 2, 6, -1}
函数接口 void scheduler(int task[], int n, int system_task[], int user_task[])
题目分析:
这道题非常有意思是先排序最后是要保存原来的下标,所以我们就想到好像sort不太试用了。
由于要储存下标,所以我们要想到用结构体或者map来做。
算法思路:
①首先定义一个结构体。这个结构体包括值和索引,定义结构体我们要申请动态内存。我们这里採用new和delete,定义的时候这里採用typedef
typedef struct TASKNODE
{
int index;
int value;
}Task_node;
②遍历保持好值和索引到结构体中
③先数值按优先级排列,事实上也就是降序排列,这个须要注意的一点是,里面用到中间变量temp,我们试想temp在我们这里应该也要是一个结构体
④循环将保持好的分别放入system_task和user_task中。最后另一个结尾-1
===============================================================================
參考代码:
//操作系统任务调度问题.cpp
//2014.7.10 hepanhui
#include <iostream>
const int maxn = 100;
using namespace std;
typedef struct TASKNODE
{
int index;
int value;
}Task_node;
void scheduler(int task[], int n, int system_task[], int user_task[])
{
Task_node *task_list = new Task_node[n * sizeof(Task_node)];
Task_node temp;
int i,j,k;
for(i=0; i < n; i++)
{
task_list[i].index = i;
task_list[i].value = task[i];
}
//按优先级排列
for(i = 0; i < n; i++)
{
for(j = i + 1; j < n; j++)
{
if(task_list[j].value < task_list[i].value)
{
temp = task_list[i];
task_list[i] = task_list[j];
task_list[j] = temp;
}
}
},
//将任务序列号存入数组中
j = k = 0;
for(i = 0; i < n; i++)
{
if(task_list[i].value >= 0 && task_list[i].value < 50)
{
system_task[j++] = task_list[i].index;
}
else if(task_list[i].value >= 50 && task_list[i].value <= 255)
{
user_task[k++] = task_list[i].index;
}
else
continue;
}
system_task[j] = -1;
user_task[k] = -1;
delete task_list;
//输出归类好的结果
for(int m = 0; m <= j-1; m++)
cout << system_task[m] << ",";
cout << system_task[j] << endl;
for(int m1 = 0; m1 <= k-1; m1++)
cout << user_task[m1] << ",";
cout << user_task[k] << endl;
}
int main()
{
int system_task[maxn];
int user_task[maxn];
/*int n;
cin >> n;
int task[maxn];
for(int i = 0 ; i < n; i++)
cin >> task[i];*/
//或者直接
int task[] = {0,30,155,1,80,300,170,40,99};
scheduler(task,9,system_task,user_task);
return 0;
}
调试过程中易犯的错误:
①最初算法思路是先判定值,保持好,之后再分别排序,保存好索引,这就麻烦了,事实上我们能够想下,我们全然能够先排序优先级别,之后再分配。
②对于整型数组时,我们两种不同的输入方式,这个要看题目需求
③我们定义int system_task[maxn];不妨定义一个maxn。切记千万不能用int system_task[n],这样是不正确的,由于n尽管已经输入了,可是不是常量
④使用三变量法的时候一定要看清楚,别笔误了
⑤学会使用new和delete来申请动态空间,这里要补充我们曾经用的malloc free差别所在
(1)new是c++中的操作符。malloc是c中的一个函数.
new是个操作符,和什么"+","-","="...有一样的地位,malloc是个分配内存的函数,供你调用的.正由于如此。new是保留字,不须要头文件支持,malloc须要头文件库函数支持.
(2)new不止是分配内存,并且会调用类的构造函数,同理delete会调用类的析构函数.而malloc则仅仅分配内存。不会进行初始化类成员的工作,相同free也不会调用析构函数.
(3)内存泄漏对于malloc或者new都能够检查出来的,差别在于new能够指明是那个文件的那一行,而malloc没有这些信息.
(4)new delete在实现上事实上调用了malloc,free函数.
(5)new能够看成两个动作:1.分配内存(相当于malloc) 2.引发构造函数
(6)new建立的是一个对象。malloc分配的是一块内存.new建立的对象你能够把它当成一个普通的对象,用成员函数訪问,不要直接訪问它的地址空间. malloc分配的是一块内存区域,就用指针訪问好了,并且还能够在里面移动指针.
(7)new出来的指针是直接带类型信息的,而malloc返回的都是void指针.
(8)malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存.
(9)对于非内部数据类型的对象而言。光用maloc/free无法满足动态对象的要求.对象在创建的同一时候要自己主动运行构造函数。对象在消亡之前要自己主动运行析构函数.由于malloc/free是库函数而不是运算符。不在编译器控制权限之内,不能够把运行构造函数和析构函数的任务强加于malloc/free.因此C++语言须要一个能完毕动态内存分配和初始化工作的运算符new,以及一个能完毕清理与释放内存工作的运算符delete.注意new/delete不是库函数.