北邮oj-first集

该代码实现了一个算法,用于处理一组文法生成式,计算所有非终结符的First集合。它遍历生成式,根据右侧的第一个字符是终结符、非终结符还是特殊符号('#’)来更新非终结符的First集合。最终,按照非终结符字母顺序和First集合内容输出结果。在处理过程中,还进行了多次迭代以确保First集合的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

题目要求

给定一定数量的文法生成式,求出所有非终结符的first集合。

题目思路

由于答案要求,非终结符按照字母顺序输出,非终结符的first集合也需要按照字母顺序输出。所以采用map中加入set的结构。
输入数据结构定义

struct test {		
	char left;		//生成式左边的非终结符
	string right;	//生成式右边的字母集合
};
vector<test> v;		//用于存放输入案例

输出数据结构定义

map<char, set<char> >  m;

遍历一趟所有数据的代码

for (int i = 0; i < n; i++) {
				char c = v[i].right[0];
				if ((c >= 'a' && c <= 'z') || c == '#') {		//如果右边第一个字母为 非终结符 或 #,直接将该非终结符加入左边的first集中,跳过该次循环
					m[v[i].left].insert(c);
					continue;
				} else {
					int j;
					for (j = 0; j < v[i].right.size(); j++) {
						char r = v[i].right[j];
						if ( r >= 'A' && r <= 'Z') {  //如果是非终结符,如果该非终结符first集合中包含#,将所有first集中非#的终结符加入左边first集中后继续循环
//							cout <<  v[i].left << " " << r << " = ";
							for (set<char>::iterator it = m[r].begin(); it != m[r].end(); it++) {
								if ((*it) != '#') {
//									cout << (*it) << " ";
									m[v[i].left].insert((*it));
								}
							}
//							cout << endl;
							if (m[r].find('#') == m[r].end()) {	//如果不包含#说明first集合到此结束,跳出循环
								break;
							}
						} else if (r >= 'a' && r <= 'z') {  //如果存在非终结符,直接跳出循环
							m[v[i].left].insert(r);
							break;
						}
					}
					if (j == v[i].right.size()) {	//如果右侧所有非终结符的first集中都包含#说明左侧的first集中也包含#,将#加入到左侧的first集合中
						m[v[i].left].insert('#');
					}
				}

			}

包含set的map输出

	for (map<char, set<char> >::iterator iter = m.begin(); iter != m.end(); iter ++) {
			cout << iter->first << " " ;
			set<char>::iterator it = iter->second.begin();
			if (iter->second.find('#') == iter->second.end()) { //判断该非终结符的first集中有没有#,如果有的话按照题目要求放到最后输出
				for ( ; it != iter->second.end(); it++) {
					if (++it == iter->second.end()) {
						it--;
						cout << (*it) << endl;
					} else {
						it--;
						cout << (*it) << " ";
					}
				}
			} else {
				for (it++ ; it != iter->second.end(); it++) {
					cout << (*it) << " ";
				}
				cout << "#" << endl;
			}
		}

AC代码

#include <bits/stdc++.h>
#include <set>
#include <string>
#include <map>
#include <vector>

using namespace std;

struct test {		//用于存放输入案例
	char left;
	string right;
};

int main() {
	int n;
	while (cin >> n) {
		vector<test> v;
		for (int i = 0; i < n; i++) {
			test t;
			cin >> t.left >> t.right;
			v.push_back(t);
		}
		map<char, set<char> >  m;
		int circle = 5;
		while (circle--) {
			for (int i = 0; i < n; i++) {
				char c = v[i].right[0];
				if ((c >= 'a' && c <= 'z') || c == '#') {
					m[v[i].left].insert(c);
					continue;
				} else {
					int j;
					for (j = 0; j < v[i].right.size(); j++) {
						char r = v[i].right[j];
						if ( r >= 'A' && r <= 'Z') {
//							cout <<  v[i].left << " " << r << " = ";
							for (set<char>::iterator it = m[r].begin(); it != m[r].end(); it++) {
								if ((*it) != '#') {
//									cout << (*it) << " ";
									m[v[i].left].insert((*it));
								}
							}
//							cout << endl;
							if (m[r].find('#') == m[r].end()) {
								break;
							}
						} else if (r >= 'a' && r <= 'z') {
							m[v[i].left].insert(r);
							break;
						}
					}
					if (j == v[i].right.size()) {
						m[v[i].left].insert('#');
					}
				}

			}
		}
		for (map<char, set<char> >::iterator iter = m.begin(); iter != m.end(); iter ++) {
			cout << iter->first << " " ;
			set<char>::iterator it = iter->second.begin();
			if (iter->second.find('#') == iter->second.end()) {
				for ( ; it != iter->second.end(); it++) {
					if (++it == iter->second.end()) {
						it--;
						cout << (*it) << endl;
					} else {
						it--;
						cout << (*it) << " ";
					}
				}
			} else {
				for (it++ ; it != iter->second.end(); it++) {
					cout << (*it) << " ";
				}
				cout << "#" << endl;
			}
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值