洛谷 P9680 string[_view] 题解

发布时间 2023-11-10 21:59:21作者: beautiful_chicken233

洛谷 P9680 string[_view] 题解

link

Sol

模拟题。

我们先定义一个结构体,来存储定义的字符串的名字,内容和长度。每一次输入分两个字符串,一个是类型,一个是名字和赋值内容。当遇到 string 时,如果是用字面量赋值,那么就计算引号里字符串的长度 \(l\)。然后把答案加上 \(l\),并把名字,内容,长度存储起来。如果是出现过的变量名赋值,那么在已经存储的字符串里查找,如果查找到了,那么把查找到的字符串的内容和长度赋值给新字符串并存储名字。再把答案加上长度。遇到 string_view 类型时只需去掉"把答案加上长度"这一步即可。

code

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std;

using ll = long long;

const int kMaxN = 1e4 + 10, kInf = (((1 << 30) - 1) << 1) + 1;

int l, ans = 0;
string a, b, tmp;

struct node { // 结构体
  string name, t; // 名字和内容
  int len; // 长度
} s[kMaxN];

int main() {
//  freopen(".in", "r", stdin);
//  freopen(".out", "w", stdout);
  cin >> l; // 输入 l
  for (int i = 1; i <= l; ++ i) {
    cin >> a >> b; // a 时类型,b 是名字和赋值内容
    if (a == "string") { // 如果是 string 类型
      if (b.find("\"") != b.npos) { // 如果是字面量
        int fst = b.find("\""); // 查找第一个 "
        char tmp = b[fst];
        b[fst] = '!';
        int scd = b.find("\""); // 查找第二个 "
        b[fst] = tmp;
        s[i].name = b.substr(0, fst - 1);
        // 存储名字(第一个 " 之前的字符串)
        s[i].t = b.substr(fst + 1, scd - fst - 1);
        // 存储内容(第一个 " 和第二个 " 之间的字符串)
        s[i].len = s[i].t.size();
        // 存储长度
        ans += s[i].len;
        // 答案加上长度
      } else {
        int fst = b.find("("); // 查找 (
        char tmp1 = b[fst];
        b[fst] = '!';
        int scd = b.find(")"); // 查找 )
        b[fst] = tmp1;
        tmp = b.substr(fst + 1, scd - fst - 1); // 已经存储的字符串的名字
        for (int j = 1; j < i; ++ j) { // 查找
          if (s[j].name == tmp) { // 如果是配对的
            s[i].name = b.substr(0, fst); // 存储名字("(" 之前的字符串)
            s[i].t = s[j].t;
            // 把内容赋给新字符串
            s[i].len = s[j].len;
            // 把长度赋给新字符串
            break;
          }
        }
        ans += s[i].len;
      }
    } else {
       /*只少了"把答案加上长度"这一步,不做注释*/
      if (b.find("\"") != b.npos) {
        int fst = b.find("\"");
        char tmp = b[fst];
        b[fst] = '!';
        int scd = b.find("\"");
        b[fst] = tmp;
        s[i].name = b.substr(0, fst - 1);
        s[i].t = b.substr(fst + 1, scd - fst - 1);
        s[i].len = s[i].t.size();
      } else {
        int fst = b.find("(");
        char tmp1 = b[fst];
        b[fst] = '!';
        int scd = b.find(")");
        b[fst] = tmp1;
        tmp = b.substr(fst + 1, scd - fst - 1);
        for (int j = 1; j < i; ++ j) {
          if (s[j].name == tmp) {
            s[i].name = b.substr(0, fst);
            s[i].t = s[j].t;
            s[i].len = s[j].len;
            break;
          }
        }
      }
    }
  }
  cout << ans << '\n';
  return 0;
}