题目

请实现一个对代码仓中各编程语言的代码量进行统计的系统,支持以下功能:

功能说明

初始化

CodeStatsSystem(products[]) – 初始化产品及其代码仓关系,所有代码仓的代码量初始为 0:

  • products[i] = [productId, repoIds[]] 表示一个产品及其代码仓列表
  • 产品、代码仓均是全局唯一的
  • 一个代码仓仅会归属某一个产品
  • 一个代码仓内可能有多种语言

代码行数变更

changeCodelines(int repoId, int languageId, int codeline) – 代码仓 repoId 中某种语言 languageId 的代码行变化量为 codeline(正值表示增加,负值表示减少)。最后返回此代码仓中该语言的代码总行数。

  • 用例保证代码仓已存在
  • 一个代码仓中某语言的代码行不会减少为负值

统计功能

statLanguage(int productId) – 统计产品 productId 所用到的各语言的代码总行数,并按要求返回语言id列表。

  • productId 为 0 表示所有产品,非 0 表示指定的产品(用例保证产品已存在)
  • 返回要求:
    • 只返回代码量大于 0 的语言
    • 优先按语言的代码量降序
    • 若代码量相同,则再按语言id升序

输入输出规范

输入

  • 每行表示一个函数调用
  • 初始化函数仅首行调用一次
  • 累计函数调用不超过1000次

数据范围

  • 1 <= products.length <= 100
  • 0 < products[i].productId <= 100
  • 1 <= repoIds.length <= 10
  • 0 <= repoIds[j]、repoId < 1000(repoId ∈ repoIds)
  • -100000 <= codeline <= 100000
  • languageId 取值范围 0~6,分别表示:
    • 0: “c”
    • 1: “c++”
    • 2: “go”
    • 3: “java”
    • 4: “javascript”
    • 5: “python”
    • 6: “rust”
  • 0 <= productId <= 100

输出

  • 答题时按照函数/方法原型中的要求(含返回值)进行实现
  • 输出由框架完成(其中首行固定输出 null)

算法标签: 模拟

思路

构建有映射关系, 有多个产品, 每个产品有 i d id id和对应管理的代码仓, 每个代码仓有多种语言的代码, 然后进行模拟

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>

using namespace std;

typedef pair<int, int> PII;
const int N = 110, M = 1010, K = 7;

vector<pair<int, vector<int>>> vec;
int sto[M][7];
vector<int> pro[N];
vector<int> ids;

bool cmp(const PII &a, const PII &b) {
   
    auto &[id1, val1] = a;
    auto &[id2, val2] = b;
    if (val1 == val2) return id1 < id2;
    return val1 > val2;
}

class CodeStatsSystem {
   
public:
    //存储产品id和对应的代码仓列, 一个代码仓仅会归属于一个产品, 一个代码仓可能有多个语言
    CodeStatsSystem(const vector<pair<int, vector<int>>> &products) {
   
        memset(sto, 0, sizeof sto);
        vec.clear();
        ids.clear();
        for (int i = 0; i < N; ++i) pro[i].clear();
        vec = products;
        for (auto &[id, tmp] : vec) {
   
            ids.push_back(id);
            pro[id] = tmp;
        }
    }

    //对代码仓中某个语言的代码行数进行变化
    int ChangeCodelines(int repoId, int languageId, int codeline) {
   
        int &val = sto[repoId][languageId];
        if (val + codeline < 0) return val;
        val += codeline;
        return val;
    }

    //统计产品用的各种语言的代码总数, 0代表返回所有产品, 只返回代码量大于0的语言, 降序, 代码量相同按照id升序
    vector<int> StatLanguage(int productId) {
   
        vector<PII> cnt(K);
        for (int i = 0; i < K; ++i) cnt[i].first = i, cnt[i].second = 0;

        if (productId == 0) {
   
            for (int id : ids) {
   
                for (int sto_id : pro[id]) {
   
                    for (int i = 0; i < K; ++i) {
   
                        cnt[i].second += sto[sto_id][i];
                    }
                }
            }
        }
        else {
   
            for (int sto_id : pro[productId]) {
   
                for (int i = 0; i < K; ++i) {
   
                    cnt[i].second += sto[sto_id][i];
                }
            }
        }
        sort(cnt.begin(), cnt.end(), cmp);
        vector<int> ans;
        for (int i = 0; i < K; ++i) {
   
            auto &[id, val] = cnt[i];
            if (val > 0) ans.push_back(id);
        }

        return ans;
    }
};