M - Variable Shadowing Gym - 100513M(模拟)

In computer programming, variable shadowing occurs when a variable declared within a certain scope has the same name as a variable declared in an outer scope. The outer variable is said to be shadowed by the inner variable, and this can lead to a confusion. If multiple outer scopes contain variables with the same name, the variable in the nearest scope will be shadowed.

Formally, a declared variable shadows another declared variable if the following conditions are met simultaneously:

the other variable is declared in outer scope and before (in terms of position in program source code) the declaration of the first variable,
the other variable is nearest among all variables satisfying the condition above.
Here is an example containing exactly one variable shadowing:

/* Prints a+max(b,c) */
int main() {
int a, b, c;
cin » a » b » c;
if (b > c) {
int a = b; // <– variable ‘a’ shadows outer ‘a’
int x = c;
b = x;
c = a;
}
int x = a + c; // <– no shadowing here
cout « x « endl;
}
Variable shadowing is permitted in many modern programming languages including C++, but compilers can warn a programmer about variable shadowing to avoid possible mistakes in a code.

Consider a trivial programming language that consists only of scopes and variable declarations. The program consists of lines, each line contains only characters ‘{’, ‘}’, ‘a’ … ‘z’ separated by one or more spaces.

Scopes. A scope (excluding global) is bounded with a pair of matching curly brackets ‘{’ and ‘}’. A scope is an inner scope relative to another scope if brackets of the first scope are enclosed by brackets of the second scope.
Variables. A variable declaration in this language is written just as a name of the variable. In addition all variables are lowercase Latin letters from ‘a’ to ‘z’ inclusive (so there are at most 26 variable names). A variable is declared in each scope at most once.
Given a syntactically correct program (i.e. curly brackets form a regular bracket sequence), write an analyzer to warn about each fact of variable shadowing. Warnings should include exact positions of shadowing and shadowed variables. Your output should follow the format shown in the examples below.

Input
The first line contains integer n (1 ≤ n ≤ 50) — the number of lines in the program. The following n lines contain the program. Each program line consists of tokens ‘{’, ‘}’, ‘a’ … ‘z’ separated by one or more spaces. The length of each line is between 1 and 50 characters. Each program line contains at least one non-space character.

The curly brackets in the program form a regular bracket sequence, so each opening bracket ‘{’ has uniquely defined matching closing bracket ‘}’ and vice versa. A variable is declared in a scope at most once. Any scope (including global) can be empty, i.e. can contain no variable declarations.

Output
For each fact of shadowing write a line in form “r1:c1: warning: shadowed declaration of ?, the shadowed position is r2:c2”, where “r1:c1” is the number of line and position in line of shadowing declaration and “r2:c2” is the number of line and position in line of shadowed declaration. Replace ‘?’ with the letter ‘a’ … ‘z’ — the name of shadowing/shadowed variable. If multiple outer scopes have variables named as the shadowing variable, the variable in the nearest outer scope is shadowed.

Print warnings in increasing order of r1, or in increasing order of c1 if values r1 are equal. Leave the output empty if there are no variable shadowings.

Examples
Input
1
{ a { b { a } } } b
Output
1:11: warning: shadowed declaration of a, the shadowed position is 1:3

Input
1
{ a { a { a } } }
Output
1:7: warning: shadowed declaration of a, the shadowed position is 1:3
1:11: warning: shadowed declaration of a, the shadowed position is 1:7

Input
7
a b {
a { a }
c b {
c
} }
{ a d z
} z
Output
2:2: warning: shadowed declaration of a, the shadowed position is 1:1
2:6: warning: shadowed declaration of a, the shadowed position is 2:2
3:6: warning: shadowed declaration of b, the shadowed position is 1:3
4:3: warning: shadowed declaration of c, the shadowed position is 3:2
6:3: warning: shadowed declaration of a, the shadowed position is 1:1

Input
1
{ a } { b } a { a } { a } { a x { a b x } } b x
Output
1:17: warning: shadowed declaration of a, the shadowed position is 1:13
1:23: warning: shadowed declaration of a, the shadowed position is 1:13
1:29: warning: shadowed declaration of a, the shadowed position is 1:13
1:35: warning: shadowed declaration of a, the shadowed position is 1:29
1:39: warning: shadowed declaration of x, the shadowed position is 1:31

题意:
n n 行由‘{’ ‘}’ 和一个字符变量组成的代码。
如果一个变量发生了重定义(就是在某个地方定义,这个地方的加上括号后的子结构里再定义了一次),那么给出警告。只用寻找最近地方发生的重定义。

思路:
模拟题。你就通过括号划分出层次,对于每一个变量,往前for,找到一个层次更高,且变量相同即可。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <string>
#include <iostream>
using namespace std;

const int maxn = 1e4 + 7;
char s[105][105];
int len[105],cnt;
int n;

struct Node {
    int r1,c1;
    int r2,c2;
    char cha;
}a[maxn];

int cmp(Node a,Node b) {
    if(a.r1 == b.r1) return a.c1 < b.c1;
    return a.r1 < b.r1;
}

Node get(int x,int y,char cha) { //第x行,第y列
    int flag = 0;
    Node ans;
    ans.r1 = x;ans.c1 = y;ans.cha = cha;
    ans.r2 = 0;ans.c2 = 0;
    for(int i = x;i >= 1;i--) {
        int j = len[i];
        if(i == x) j = y - 1;
        for(;j >= 1;j--) {
            if(s[i][j] == '}') flag--;
            else if(s[i][j] == '{' && flag < 0) flag++;
            else if(flag == 0 && s[i][j] == cha) {
                ans.r2 = i;ans.c2 = j;
                return ans;
            }
        }
    }
    return ans;
}

void Print() {
    for(int i = 1;i <= n;i++) {
        printf("%d ",len[i]);
        for(int j = 1;j <= len[i];j++) {
            printf("%c",s[i][j]);
        }
        printf("\n");
    }
}

int main() {
    scanf("%d",&n);
    getchar();
    for(int i = 1;i <= n;i++) {
        cin.getline(s[i] + 1,100);
        for(int j = 100;j >= 1;j--) {
            if(s[i][j] != '\0' ) {
                len[i] = j;break;
            }
        }
    }
    
//    Print();
    
    for(int i = 1;i <= n;i++) {
        for(int j = 1;j <= len[i];j++) {
            if(s[i][j] >= 'a' && s[i][j] <= 'z') {
                Node now = get(i,j,s[i][j]);
                if(now.r2 != 0) {
                    a[++cnt] = now;
                }
            }
        }
    }
    
    sort(a + 1,a + 1 + cnt,cmp);
    
    for(int i = 1;i <= cnt;i++) {
        printf("%d:%d: warning: shadowed declaration of %c, the shadowed position is %d:%d\n",a[i].r1,a[i].c1,a[i].cha,a[i].r2,a[i].c2);
    }
    return 0;
}
原创文章 930 获赞 38 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/106053783
M
^M