P2373 题解

· · 题解

思路

这道题很显然是模拟。可以用结构体来存储每一个函数,每个结构体中包含这个函数的名称与这个函数的参数情况。由于没有给出函数的数量范围,所以最后再用一个 vector 来存储所有不重复的函数,输出答案时只需要输出 vector 的大小即可。

函数名

从题目所给出的样例可以看出,函数名与参数之间有空格,所以可以直接用 cin 来读入函数的名称,然后判断是否为 main() 并统一大小写。

参数情况

从样例可以看出,两个参数之间也有空格,所以同样可以使用 cin 读入,一次读入一个参数。由于 int 类型与 char 类型之间的区别就在于参数的描述中是否存在单引号,所以就可以直接在这个字符串中使用 find() 进行查找,如果能够找到单引号则这个参数就为 char 类型,反之则为 int

值得注意的是,按照样例中给出的格式,如果参数的类型为 char 则在这个参数中还存在一个额外的空格,所以在判断参数类型前需要先检查读入的字符串末尾是否为逗号或反括号,如果是则存储进参数情况中,否则则直接读入下一条。

由于参数最多只有 10 个,所以参数情况可以使用一个 long long 类型来存储,第一位数字表示第一个参数的类型,以此类推。若参数类型为 char 则此位的数字为 1,若类型为 int 则数字为 0

判重

在将当前函数的结果存进用于存储答案的 vector 中之前先将其遍历一遍,如果没有相同的情况则将当前的情况存入 vector 中。

AC代码

#include<bits/stdc++.h>

using namespace std;

bool cmp(string, string);

struct faction{ //用于存储函数的结构体 
    string name;
    long long para;
}n2;

vector <faction> n1;
string s;
int n;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> s;
        if(cmp(s, "main")){ //判断函数名称是否为main 
            cin >> s; 
            continue;
        }
        for(int i = 0; i <= s.length() - 1; i++){ //统一函数名字母大小写 
            if(s[i] >= 'a' && s[i] <= 'z'){
                s[i] -= 32; //将小写字母转换为大写 
            }
            n2.name = s;
        }
        n2.para = 0;
        for(;;){
            cin >> s;
            if(s[s.length() - 1] != ')' && s[s.length() - 1] != ','){
                continue;
            }
            n2.para *= 10;
            if(s.find(39) == -1){ //查找是否存在单引号,如存在则参数类型为char 
                n2.para += 1;
            }
            if(s[s.length() - 1] == ')'){ //判断当前函数的参数是否已全部读入 
                break;
            }
        }
        bool flag = true;
        for(int i = 0; i < n1.size(); i++){ //判断是否已存在相同的函数 
            if(cmp(n2.name, n1[i].name) && n2.para == n1[i].para){
                flag = false;
            }
        }
        if(flag){ 
            n1.push_back(n2); //将当前函数存入vector 
        }
    }
    cout << n1.size(); //输出vector的大小,即不完全相同函数的数量 
    return 0;
}

bool cmp(string s1, string s2){ //用于判断字符串是否相同的函数 
    if(s1.length() != s2.length()){
        return false;
    }
    for(int i = 0; i <= s1.length() - 1; i++){
        if(s1[i] != s2[i]){
            return false;
        }
    }
    return true;
}