J Pointer Analysis
题意
一个程序中有 26 个对象, 每个对象有 26 个成员指针变量. 同时还有 26 个普通的指针变量. 给定 n 条赋值 语句, 询问在以任意顺序执行每条语句无限多次的过程中, 每个指针变量可能指向的对象集合.
解析
1、以任意顺序执行每条语句无限多次,只需要将所有语句按照顺序执行 n 遍
2、对于每一种情况分别处理
3、使用vector数组记录指针指向的对象
4、因为有一个指针可能会多次指向同一个对象,所以使用一个布尔数组来记录改指针是否指向过某个对象
代码
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 210;
int n;
char in[N][2][5];
bool okP[26][26], okO[26][26][26];
vector<int> p[26], o[26][26];
int main () {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s = %s", in[i][0], in[i][1]);
}
for (int t = 0; t < n; t++) {
for (int i = 0; i < n; i++) {
if (in[i][1][0] <= 'z' && in[i][1][0] >= 'a') {
// 第一种情况
int A = in[i][0][0] - 'A', x = in[i][1][0] - 'a';
if (!okP[A][x]) {
okP[A][x] = true;
p[A].push_back(x);
}
} else if (in[i][0][1] == 0 && in[i][1][1] == 0) {
// 第二种情况
int A = in[i][0][0] - 'A', B = in[i][1][0] - 'A';
for (int j = 0; j < p[B].size(); j++) {
if (!okP[A][p[B][j]]) {
okP[A][p[B][j]] = true;
p[A].push_back(p[B][j]);
}
}
} else if (in[i][0][1] == '.') {
// 第三种情况
int A = in[i][0][0] - 'A', B = in[i][1][0] - 'A', f = in[i][0][2] - 'a';
for (int j = 0; j < p[A].size(); j++) {
int o0 = p[A][j];
for (int k = 0; k < p[B].size(); k++) {
if (!okO[o0][f][p[B][k]]) {
okO[o0][f][p[B][k]] = true;
o[o0][f].push_back(p[B][k]);
}
}
}
} else {
// 第四种情况
int A = in[i][0][0] - 'A', B = in[i][1][0] - 'A', f = in[i][1][2] - 'a';
for (int j = 0; j < p[B].size(); j++) {
int o0 = p[B][j];
for (int k = 0; k < o[o0][f].size(); k++) {
if (!okP[A][o[o0][f][k]]) {
okP[A][o[o0][f][k]] = true;
p[A].push_back(o[o0][f][k]);
}
}
}
}
}
}
for (int i = 0; i < 26; i++) {
printf("%c: ", i + 'A');
sort(p[i].begin(), p[i].end());
for (int j = 0; j < p[i].size(); j++) {
printf("%c", p[i][j] + 'a');
}
printf("\n");
}
return 0;
}