2020牛客暑期多校训练营(第七场) Pointer Analysis

本文介绍了指针分析在静态程序分析中的重要性,并针对一个包含四种语句类型的简化程序,进行了上下文无关的指针分析。通过分析,我们需要找出每个指针可能指向的对象。文章提供了样例输入和输出,以及一种简化处理问题的思路,采用暴力求解方法来应对不同情况。
摘要由CSDN通过智能技术生成

原题
题目描述
指针分析旨在确定在执行过程中可以通过程序中的特定指针变量访问哪些对象,这是静态程序分析的基本部分之一。 现在,我们希望您对测试数据执行上下文无关的指针分析。
一个程序包含 26 26 26个用小写字母表示的 o b j e c t object object,每个 o b j e c t object object也有 26 26 26个用小写字母表示的成员变量(也称fields,是指向某个 o b j e c t object object的指针),和 26 26 26个用大写字母表示的全局指针。
程序有4种语句,用 [ V a r i a b l e ] [Variable] [Variable]表示指针的名称, [ F i e l d ] [Field] [Field]表示成员变量的名称, [ O b j e c t ] [Object] [Object]表示对象。
在这里插入图片描述
上下文无关的指针分析假定该程序的语句将以任何顺序执行足够的次数。 例如,在以下两个程序中, A A A B B B都可以指向对象 x x x和对象 o o o。 这是因为,在现实世界中,很难准确预测语句的执行顺序和执行时间。
在这里插入图片描述
现在,要求您在由 N N N个语句组成的给定程序上执行上下文无关的指针分析,并为每个指针输出它可以指向的对象。
样例1
输入

5
B.f = A
C = B.f
C = x
A = o
B = o

输出

A: o
B: o
C: ox
D: 
E: 
F: 
G: 
H: 
I: 
J: 
K: 
L: 
M: 
N: 
O: 
P: 
Q: 
R: 
S: 
T: 
U: 
V: 
W: 
X: 
Y: 
Z:

样例2
输入

4
A = o
B.f = A
C = B.f
C = g

输出

A: o
B: 
C: g
D: 
E: 
F: 
G: 
H: 
I: 
J: 
K: 
L: 
M: 
N: 
O: 
P: 
Q: 
R: 
S: 
T: 
U: 
V: 
W: 
X: 
Y: 
Z:

样例3
输入

3
A = o
B = A
A = x

输出

A: ox
B: ox
C: 
D: 
E: 
F: 
G: 
H: 
I: 
J: 
K: 
L: 
M: 
N: 
O: 
P: 
Q: 
R: 
S: 
T: 
U: 
V: 
W: 
X: 
Y: 
Z:

思路
这题要用到指针的知识,不懂得可以看看这篇博客
可以用官方给的伪代码写
在这里插入图片描述
由于本人较懒,以上伪代码太烦,所以我们可以换一种思路。
因为一共就只有4种情况 : :
1 、 A = B 1、A=B 1A=B
2 、 A = B . C 2、A=B.C 2A=B.C
3 、 A . C = B 3、A.C=B 3A.C=B
4 、 A . C = B . C 4、A.C=B.C 4A.C=B.C
因为第 2 2 2和第 3 3 3种情况差不多,所以可以一起考虑。
直接暴力就行,具体细节请看代码。
代码

#include<bits/stdc++.h>
using namespace std;
int n,ans[205][205],d[205][205][205];
string a[205],b[205];
char c,p,q;
void sc(){for(int i=0;i<26;i++){printf("%c: ",'A'+i);for(int j=0;j<26;j++)if(ans[i][j])printf("%c",'a'+j);puts("");}}
//输出
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i]>>c>>b[i];
    for(int i=1;i<=n;i++)
        for(int j=1,u,v,k1,k2,k3;j<=n;j++)
        {
            p=a[j][0];q=b[j][0];u=p-'A';v=q-'A';k1=a[j].size();k2=b[j].size();
            if(k1==1&&k2==1)//A=B
            {
                if(q>='a') ans[u][v-32]=1;
                else for(int k=0;k<26;k++)ans[u][k]|=ans[v][k];
            }
            else if(k1==3)//A.C=B或A=B.C
            {
                k3=a[j][2]-'a';
                for(int k=0;k<26;k++)if(ans[u][k])for(int r=0;r<26;r++)d[k][k3][r]|=ans[v][r];
            }
            else//A.C=B.C
            {
                k3=b[j][2]-'a';
                for(int k=0;k<26;k++)if(ans[v][k])for(int r=0;r<26;r++)ans[u][r]|=d[k][k3][r];
            }
        }
    sc();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值