1 条题解

  • 0
    @ 2026-10-27 1:47:48

    思路与算法

    给每个类型存大小、对齐和按定义顺序排列的成员偏移。新成员起点为不小于当前末尾且为其对齐倍数的最小值;类型大小最后按最大成员对齐取整。全局变量同样对齐连续分配。名称查询逐级沿成员路径累加偏移;地址查询先定位变量,再逐层找覆盖该偏移的成员,到基本类型才输出完整名称,找不到则ERR。

    正确性说明

    取整函数ceil(end/align)*align正是满足形式化对齐规则的最小地址,按成员与变量顺序归纳可知存储布局准确。路径访问的每一级偏移相加就是实际地址。各成员字节范围互不相交,地址查询至多属于一个成员;若落在间隙或尾部填充则不属于任何基本对象,输出ERR正确。下降到基本成员给唯一全路径。

    复杂度

    设F为总成员数、Q为操作数、H为最大嵌套深度、K为最大成员数。含布局和容器初始化,O(F+QHK)时间、O(F+Q)空间;路径字符串处理另按实际长度线性计。

    易错点

    结构体尾部也补齐,变量之间也有空隙;地址0合法。只有基本类型字节属于可输出名称。大小与地址达1e18,使用64位,内层成员名字可在不同类型重复。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Field {
        string name;
        int type;
        long long offset;
    };
    struct Type {
        long long size, align;
        vector<Field> f;
    };
    long long alignUp(long long x, long long a) {
        return (x + a - 1) / a * a;
    }
    int main() {
        int n;
        cin >> n;
        vector<Type> types = {{1, 1, {}}, {2, 2, {}}, {4, 4, {}}, {8, 8, {}}};
        map<string, int> bytype = {{"byte", 0}, {"short", 1}, {"int", 2}, {"long", 3}};
        struct Var {
            long long base;
            int type;
            string name;
        };
        vector<Var> vars;
        map<string, int> byvar;
        long long used = 0;
        while (n--) {
            int op;
            cin >> op;
            if (op == 1) {
                string name;
                int k;
                cin >> name >> k;
                Type t{0, 1, {}};
                while (k--) {
                    string ty, field;
                    cin >> ty >> field;
                    int id = bytype.at(ty);
                    t.size = alignUp(t.size, types[id].align);
                    t.f.push_back({field, id, t.size});
                    t.size += types[id].size;
                    t.align = max(t.align, types[id].align);
                }
                t.size = alignUp(t.size, t.align);
                bytype[name] = types.size();
                types.push_back(t);
                cout << t.size << " " << t.align << "\n";
            } else if (op == 2) {
                string ty, name;
                cin >> ty >> name;
                int id = bytype.at(ty);
                used = alignUp(used, types[id].align);
                byvar[name] = vars.size();
                vars.push_back({used, id, name});
                cout << used << "\n";
                used += types[id].size;
            } else if (op == 3) {
                string s;
                cin >> s;
                replace(s.begin(), s.end(), '.', ' ');
                istringstream in(s);
                string name;
                in >> name;
                Var v = vars[byvar.at(name)];
                long long at = v.base;
                int type = v.type;
                while (in >> name) {
                    for (auto f : types[type].f)
                        if (f.name == name) {
                            at += f.offset;
                            type = f.type;
                            break;
                        }
                }
                cout << at << "\n";
            } else {
                long long at;
                cin >> at;
                int v = -1;
                for (int i = 0; i < (int)vars.size(); i++)
                    if (vars[i].base <= at && at < vars[i].base + types[vars[i].type].size) {
                        v = i;
                        break;
                    }
                if (v < 0) {
                    cout << "ERR\n";
                    continue;
                }
                long long rem = at - vars[v].base;
                int type = vars[v].type;
                string result = vars[v].name;
                bool ok = true;
                while (type >= 4) {
                    bool found = false;
                    for (auto f : types[type].f)
                        if (f.offset <= rem && rem < f.offset + types[f.type].size) {
                            rem -= f.offset;
                            type = f.type;
                            result += '.' + f.name;
                            found = true;
                            break;
                        }
                    if (!found) {
                        ok = false;
                        break;
                    }
                }
                cout << (ok ? result : "ERR") << "\n";
            }
        }
    }
    
    • 1

    【23CSPS提高组】结构体(struct)

    信息

    ID
    1978
    时间
    1000ms
    内存
    512MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者