一道华为笔试题--内存块排序
题目描述(没有记录原题目,回忆的大概):
给定几个内存块,限定内存块只有M,G,T三个单位,三个之间的进制转换为:1T=1024G,1G=1024M,根据大小排序并输出
输入描述:
先输入一个数n,用来表示接下来会输入几个数据。
再输入n个字符串,形式为mv,m表示数字大小,v表示单位。
数据规模:n<=1000,2<=字符串长度<=10
解题思路(错误!):因为只有三个类型的数据,我没有用到进制转换,而是利用了map的键会自动排序的原理,(这样写的扩展性不好,单位多了的话这样子设计师不合理的)直接将三种单位的数据分开存储,最后再按M、G、T的顺序遍历输出。但是,写完之后又想到了重复值的问题!map是不允许键重复的。所以改用vector进行存储。由于写题时候旁边坐了个在上网课的大侄子...当时思路没有捋清,所以也没测试,不知道系统的测试案例是怎样的,仅是自己能想到的测试案例进行了测试,如果有大神觉得有什么问题的欢迎批评指正~
再编辑:
a!昨天晚上睡前突然就想到了为啥要告诉进制转换,我还跟憨批一样不理会这个这个信息。1000000M大于1G呀!看上去我的出发点就是错的!反思一下,再去改代码liao~
这个貌似也可以用于操作系统中的存储管理里面的可变分区中的最佳适应算法。最佳适应算法的话单位比这个多,比较完大小之后把空闲块的物理地址存起来就行了。
改完之后的思路:用冒泡排序对数组中的元素重新排序得到最终结果再输出。
自己的一个测试案例:
第一版的代码如下,虽然有问题还是想记录一下(忽略了重复数值):
#include<iostream> #include<algorithm> #include<map> using namespace std; int main() { int n; cin >> n; char c[1001][11];//最多不超过1000个字符串,每个字符串长度不超过10位 map<int, char> m1, m2, m3;//用m1,m2,m3分别来完成内存块为M,G,T的数字的存储 //初始化数据 for (int i = 0; i < n; i++) { cin >> c[i]; } for (int i = 0; i < n; i++) { int number = 0; int j = 0; //将前面的数据部分从char类型转换成int类型 while (c[i][j] >= '0'&&c[i][j] <= '9') { number = number*10 + c[i][j] - '0'; j++; } //判断最后一个字符是M/G/T,决定将数据存入哪一个map中 char flag; for (int k = 0; k < 11; k++) { if (c[i][k] == 'M'){ flag = 'M'; break; } else if (c[i][k] == 'G') { flag = 'G'; break; } else if(c[i][k] == 'T') { flag = 'T'; break; } } if (flag == 'M') { m1.insert(pair<int, char>(number, 'M')); } else if (flag == 'G') { m2.insert(pair<int, char>(number, 'G')); } else { m3.insert(pair<int, char>(number, 'T')); } } //遍历输出三个map中的值,顺序位M/G/T map<int, char>::iterator mit; for (mit = m1.begin(); mit != m1.end(); mit++) { cout << mit->first << mit->second << endl; } for (mit = m2.begin(); mit != m2.end(); mit++) { cout << mit->first << mit->second << endl; } for (mit = m3.begin(); mit != m3.end(); mit++) { cout << mit->first << mit->second << endl; } system("pause"); return 0; }
改正后的(忽略单位换算):
#include<iostream> #include<algorithm> #include<vector> using namespace std; int main() { int n; cin >> n; char c[1001][11];//最多不超过1000个字符串,每个字符串长度不超过10位 vector<int> m1, m2, m3;//用m1,m2,m3分别来完成内存块为M,G,T的数字的存储 //初始化数据 for (int i = 0; i < n; i++) { cin >> c[i]; } for (int i = 0; i < n; i++) { int number = 0; int j = 0; //将前面的数据部分从char类型转换成int类型 while (c[i][j] >= '0'&&c[i][j] <= '9') { number = number*10 + c[i][j] - '0'; j++; } //判断最后一个字符是M/G/T,决定将数据存入哪一个map中 char flag; for (int k = 0; k < 11; k++) { if (c[i][k] == 'M'){ flag = 'M'; break; } else if (c[i][k] == 'G') { flag = 'G'; break; } else if(c[i][k] == 'T') { flag = 'T'; break; } } if (flag == 'M') { m1.push_back(number); } else if (flag == 'G') { m2.push_back(number); } else { m3.push_back(number); } } //对vector进行排序 sort(m1.begin(),m1.end()); sort(m2.begin(), m2.end()); sort(m3.begin(), m3.end()); //遍历输出三个map中的值,顺序位M/G/T vector<int>::iterator mit; for (mit = m1.begin(); mit != m1.end(); mit++) { cout << *mit << "M" << endl; } for (mit = m2.begin(); mit != m2.end(); mit++) { cout << *mit << "G" << endl; } for (mit = m3.begin(); mit != m3.end(); mit++) { cout << *mit << "T" << endl; } system("pause"); return 0; }
排序之后的代码:
#include<iostream> #include<algorithm> #include<string> using namespace std; /*求当前字符串的单位*/ char danwei(char c[]) { char flag; for (int k = 0; k < 11; k++) { if (c[k] == 'M') { flag = 'M'; break; } else if (c[k] == 'G') { flag = 'G'; break; } else if (c[k] == 'T') { flag = 'T'; break; } } return flag; } /*将字符串转换为数字*/ int getNumber(char c[]) { int number = 0; int j = 0; //将前面的数据部分从char类型转换成int类型 while (c[j] >= '0'&&c[j] <= '9') { number = number * 10 + c[j] - '0'; j++; } return number; } int main() { int n; cin >> n; char c[1001][11];//最多不超过1000个字符串,每个字符串长度不超过10位 //初始化数据 for (int i = 0; i < n; i++) { cin >> c[i]; } //使用冒泡排序 for (int i = 0; i < n; i++) { for (int j = 0; j < n-i-1; j++) { if (danwei(c[j]) == danwei(c[j + 1])) { //单位相同 if (getNumber(c[j]) > getNumber(c[j + 1])) { //直接比较数字大小 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j+1]); strcpy_s(c[j+1],temp); } } else { //单位不同 switch (danwei(c[j])) { case 'M': switch (danwei(c[j + 1])) { case 'G': if (getNumber(c[j])/1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; case'T' : if (getNumber(c[j]) / 1024/1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; } break; case 'G': switch (danwei(c[j + 1])) { case 'M': if (getNumber(c[j])*1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; case'T': if (getNumber(c[j]) / 1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; } break; case 'T': switch (danwei(c[j + 1])) { case 'M': if (getNumber(c[j])* 1024*1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; case'G': if (getNumber(c[j])*1024 > getNumber(c[j + 1])) { //换算单位后比较 char temp[11]; strcpy_s(temp, c[j]); strcpy_s(c[j], c[j + 1]); strcpy_s(c[j + 1], temp); } break; } break; } } } } for (int i = 0; i < n; i++) { cout << c[i] << endl; } system("pause"); return 0; }
唯有热爱方能抵御岁月漫长。