全自动构造first集合,构造last也同理
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
int main()
{
vector<string> wenFa;
wenFa.push_back("E->E+T");
wenFa.push_back("E->T");
wenFa.push_back("T->T*F");
wenFa.push_back("T->F");
wenFa.push_back("F->P^F");
wenFa.push_back("F->P");
wenFa.push_back("P->(E)");
wenFa.push_back("P->i");
//string s;
//while (cin >> s) {
// wenFa.push_back(s);
//}
vector<char> vn, vt;
for (auto i : wenFa) {
for (auto j : i) {
if (j >= 'A' && j <= 'Z') {
vn.push_back(j);
}
}
for (int k = 3; k < i.size(); k++) {
if (i[k] != '|' && (i[k] > 'Z' || i[k] < 'A')) {
vt.push_back(i[k]);
}
}
}
sort(vn.begin(), vn.end());
auto uniq1 = unique(vn.begin(), vn.end());
vn.erase(uniq1, vn.end());
sort(vt.begin(), vt.end());
auto uniq2 = unique(vt.begin(), vt.end());
vt.erase(uniq2, vt.end());
unordered_map<char, int> vnmap, vtmap;
for (int i = 0; i < vn.size(); i++) {
vnmap[vn[i]] = i;
}
for (int i = 0; i < vt.size(); i++) {
vtmap[vt[i]] = i;
}
vector<vector<char>> first(vn.size(), vector<char>(vt.size()));
for (auto &i : first) {
for (auto &j : i) {
j = '0';
}
}
for (auto i : wenFa) {
if (find(vt.begin(), vt.end(), i[3]) != vt.end()) {
first[vnmap[i[0]]][vtmap[i[3]]] = '1';
}
if (i.size() > 4) {
if ((find(vt.begin(), vt.end(), i[4]) != vt.end()) && (find(vn.begin(), vn.end(), i[3]) != vn.end())) {
first[vnmap[i[0]]][vtmap[i[4]]] = '1';
}
}
}
unordered_map<char, char> ways;
for (auto i : wenFa) {
if (find(vn.begin(), vn.end(), i[3]) != vn.end()) {
ways[i[0]] = i[3];
}
}
int flag = 1;
while (flag) {
flag = 0;
for (auto i : ways) {
int P = -1, Q = -1;
P = vnmap[i.first];
Q = vnmap[i.second];
for (int j = 0; j < vt.size(); j++) {
if (first[Q][j] == '1') {
if (first[P][j] == '0') {
flag = 1;
}
first[P][j] = '1';
}
}
}
}
cout << '#' << "\t";
for (auto i : vt) {
cout << i << "\t";
}
cout << endl;
int i1 = 0;
for (auto i : first) {
cout << vn[i1++] << "\t";
for (auto j : i) {
cout << j << "\t";
}
cout << endl;
}
return 0;
}
由于与教材要求不符 修改了一下。
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <unordered_map>
using namespace std;
stack <pair<char, char>> s;
unordered_map<char, int> vnmap, vtmap;
vector<vector<char>> first;
void insert(stack<pair<char, char>> &s, vector<vector<char>> &first, char vn, char vt) {
if (first[vnmap[vn]][vtmap[vt]] == '0') {
first[vnmap[vn]][vtmap[vt]] = '1';
s.push({ vn, vt });
}
return;
}
int main()
{
vector<string> wenFa;
wenFa.push_back("E->E+T");
wenFa.push_back("E->T");
wenFa.push_back("T->T*F");
wenFa.push_back("T->F");
wenFa.push_back("F->P^F");
wenFa.push_back("F->P");
wenFa.push_back("P->(E)");
wenFa.push_back("P->i");
vector<char> vn, vt;
for (auto i : wenFa) {
for (auto j : i) {
if (j >= 'A' && j <= 'Z') {
vn.push_back(j);
}
}
for (int k = 3; k < i.size(); k++) {
if (i[k] != '|' && (i[k] > 'Z' || i[k] < 'A')) {
vt.push_back(i[k]);
}
}
}
sort(vn.begin(), vn.end());
auto uniq1 = unique(vn.begin(), vn.end());
vn.erase(uniq1, vn.end());
sort(vt.begin(), vt.end());
auto uniq2 = unique(vt.begin(), vt.end());
vt.erase(uniq2, vt.end());
for (int i = 0; i < vn.size(); i++) {
vnmap[vn[i]] = i;
}
for (int i = 0; i < vt.size(); i++) {
vtmap[vt[i]] = i;
}
vector<vector<char>> first1(vn.size(), vector<char>(vt.size()));
first.assign(first1.begin(), first1.end());
for (auto& i : first) {
for (auto& j : i) {
j = '0';
}
}
for (auto i : wenFa) {
if (find(vt.begin(), vt.end(), i[3]) != vt.end()) {
insert(s, first, i[0], i[3]);
}
if (i.size() > 4) {
if ((find(vt.begin(), vt.end(), i[4]) != vt.end()) && (find(vn.begin(), vn.end(), i[3]) != vn.end())) {
insert(s, first, i[0], i[4]);
}
}
}
unordered_map<char, char> ways;
for (auto i : wenFa) {
if (find(vn.begin(), vn.end(), i[3]) != vn.end()) {
ways[i[0]] = i[3];
}
}
while (!s.empty()) {
char Q = s.top().first;
char a = s.top().second;
s.pop();
for (auto i : wenFa) {
if (i[3] == Q) {
insert(s, first, i[0], a);
}
}
}
cout << '#' << "\t";
for (auto i : vt) {
cout << i << "\t";
}
cout << endl;
int i1 = 0;
for (auto i : first) {
cout << vn[i1++] << "\t";
for (auto j : i) {
cout << j << "\t";
}
cout << endl;
}
return 0;
}