题目大意:
有这样一种语言&K*语言,有两种基本类型,void和errtype,同有两种运算方式:
- typedef A B 将A定义为B,B中不可以带&*
- typeof A 输出A对应的void类型
这个语言有一个非常强大的指针系统,void * 表示指针,&表示取消引用,即:&void(5个星号) = void(4个星号),星号的优先级始终高于&,即:&void * = void,如果&&void * 则会导致错误的类型errtype,错误的类型一旦出现,无论什么操作都是错误类型,即errtype ****** = errtype,typedef A B如果A没有没定义过,那么B仍然是错误类型(WA点),对于每一个typeof操作,输出对应的void类型。
解题思路:
大模拟,理清思路就简单了,这里用三个map,一个用来存定义B的类型A,一个用来存B类型里面星号的个数,vis用于存储该类型是否出现过,每次先计算最后应该剩下的星号个数,如果小于0,则说明该类型就是错误类型,如果>=0 则存入map,处理完后判断是否只剩viod,如果只剩void则不用存map,反之要存入定义他的A类型和A类型对应的星号个数 + 现有的星号个数即可。
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int mod = 1e9 + 7;
const int N = 150;
const int inf = 0x3f3f3f3f;
typedef long long ll;
map<string, int> mp;
map<string, string> mp1;
map<string, int> vis;
int main()
{
int t;
cin >> t;
while (t--)
{
string op;
cin >> op;
if (op == "typedef")
{
string a, b;
cin >> a >> b;
int l = 0, r = a.size() - 1, r1 = 0;
while (a[l] == '&') l++;
while (a[r] == '*') r--, r1 ++;
string ty = "";
for (int i = l; i <= r; i ++)//处理去掉&*后的类型名
ty += a[i];
if (ty == "void")//如果是void则不用加上父级的星号个数
{
mp1[b] = "void";
mp[b] = r1 - l;
vis[b] = 1;
}
else//如果不是则需要加上父级个数,如果父级为errtype,那么他也是错误类型
{
mp1[b] = ty;
if (mp[ty] >= 0 && vis[ty])
mp[b] = mp[ty] + (r1 - l);
else
mp[b] = -1;
vis[b] = 1;//标记是否出现过
}
}
else
{
string a;
cin >> a;
int l = 0, r = a.size()-1, r1 = 0;
while (a[l] == '&') l++;
while (a[r] == '*') r--, r1 ++;
string ty = "";
for (int i = l; i <= r; i ++)//这里还是先处理,处理完之后再加上父级的星号个数
ty += a[i];
if (!vis[ty])//如果没有出现过则需要判断是什么类型,不是void就是错误
{
if (ty != "void")
cout << "errtype" << endl;
else
cout << "void" << endl;
continue;
}
if (mp[ty] < 0 || mp[ty] + (r1 - l) < 0)//如果父级小于0则无论再怎么操作都是错误的类型
cout << "errtype" << endl;
else
{
cout << "void";
for (int i = 1; i <= mp[ty] + (r1 - l); i ++)
cout << "*";
cout << endl;
}
}
}
//system("pause");
return 0;
}