M27300: 模型整理
sortings, AI, http://cs101.openjudge.cn/pctbook/M27300/
深度学习模型(尤其是大模型)是近两年计算机学术和业界热门的研究方向。每个模型可以用 “模型名称-参数量” 命名,其中参数量的单位会使用两种:M,即百万;B,即十亿。同一个模型通常有多个不同参数的版本。
例如,Bert-110M,Bert-340M 分别代表参数量为 1.1 亿和 3.4 亿的 Bert 模型,GPT3-350M,GPT3-1.3B 和 GPT3-175B 分别代表参数量为 3.5亿,13亿和 1750 亿的 GPT3 模型。
参数量的数字部分取值在 [1, 1000) 区间(一个 8 亿参数的模型表示为 800M 而非 0.8B,10 亿参数的模型表示为 1B 而非 1000M)。
计算机专业的学生小 A 从网上收集了一份模型的列表,他需要将它们按照名称归类排序,并且同一个模型的参数量从小到大排序,生成 “模型名称: 参数量1, 参数量2, ...” 的列表。请你帮他写一个程序实现。
输入
第一行为一个正整数 n(n <= 1000),表示有 n 个待整理的模型。
接下来 n 行,每行一个 “模型名称-参数量” 的字符串。模型名称是字母和数字的混合。
输出
每行一个 “模型名称: 参数量1, 参数量2, ...” 的字符串,符号均为英文符号,模型名称按字典序排列,参数量按从小到大排序。
样例输入
5
GPT-1.3B
Bert-340M
GPT-350M
Bert-110M
GPT-175B样例输出
Bert: 110M, 340M
GPT: 350M, 1.3B, 175B提示
tags: string, sort
来源
2023fall zyn
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
class Model {
private:
string raw; // 原始参数量字符串,比如 "350M" 或 "1.3B"
double value; // 换算成 B 的数值,方便比较
public:
string name; // 模型名公开
// 构造函数:接收 "模型名-参数量" 字符串
Model(const string& fullname) {
size_t pos = fullname.find('-');
name = fullname.substr(0, pos);
raw = fullname.substr(pos + 1);
char unit = raw.back();
double num = stod(raw.substr(0, raw.size() - 1));
if (unit == 'M') {
value = num / 1000.0; // 百万 → 十亿
} else {
value = num; // 已经是 B
}
}
// 提供获取原始参数量字符串的方法
string getRaw() const {
return raw;
}
// 重载 < 运算符用于排序
bool operator<(const Model& other) const {
if (name == other.name) {
return value < other.value;
}
return name < other.name;
}
};
int main() {
int n;
cin >> n;
vector<Model> models;
models.reserve(n);
for (int i = 0; i < n; i++) {
string s;
cin >> s;
models.emplace_back(s);
}
sort(models.begin(), models.end());
cout << models[0].name << ": " << models[0].getRaw();
for (int i = 1; i < n; i++) {
if (models[i].name == models[i - 1].name) {
cout << ", " << models[i].getRaw();
} else {
cout << "\n" << models[i].name << ": " << models[i].getRaw();
}
}
cout << "\n";
return 0;
}reserve → 提前分配内存
emplace_back → 直接构造对象,避免不必要拷贝
struct= 数据结构(默认 public)
class= 面向对象(默认 private)功能上完全等价,选择哪种主要看语义:
- 你只是存数据 → struct 更清晰
- 你需要封装/隐藏/继承 → class 更合适
如果用
class:cppclass Model { string name; double value; };
- 默认是 private
- 你必须提供 getter 或者把成员改成
public:cppclass Model { public: string name; double value; };
思路:核心在数据的接收上,排序可以直接sort(),只要数据接收正确就可以,用时约10分钟
#include <iostream>
#include <sstream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
// 把参数量字符串转成数值 (统一为实际参数个数)
long parseParam(const string& s)
{
double num = stod(s.substr(0, s.size() - 1));
char unit = s.back();
if (unit == 'M') return (long)(num * 1e6 + 0.5);
if (unit == 'B') return (long)(num * 1e9 + 0.5);
return 0;
}
int main()
{
int n;
cin >> n;
//以模型名称为键,参数量为值
map<string, vector<pair<long , string>>> models;
for (int i = 0; i < n; i++)
{
string input;
cin >> input;
// 拆分 模型名称 和 参数量
size_t pos = input.find('-');
string name = input.substr(0, pos);
string param = input.substr(pos + 1);
long value = parseParam(param);
models[name].push_back({ value, param });
}
// 按名称字典序输出
for (auto& temp : models)
{
string name = temp.first;
auto& vec = temp.second;
// 按数值排序
sort(vec.begin(), vec.end());
cout << name << ": ";
for (int i = 0; i < vec.size(); i++)
{
if (i > 0) cout << ", ";
cout << vec[i].second;
}
cout << "\n";
}
return 0;
}