#include<bits/stdc++.h>usingnamespace std;constint Maxn =110, maxn =20;char fin[maxn], cmp[maxn][maxn];char firstvt[maxn][maxn], lastvt[maxn][maxn];char str[maxn][Maxn], nstr[maxn][maxn], mstr[maxn][maxn], st[maxn], stac[maxn];int firstflag[maxn], lastflag[maxn], fcnt[maxn], lcnt[maxn];intis_fin(char c){for(int i =0; fin[i]!='\0'; i++){if(fin[i]== c)return1;}return0;}intsite(char c){for(int i =0; fin[i]!='\0'; i++){if(fin[i]== c)return i;}}voidget_firstvt(char s,int t){int i, j, ii, jj, tt;for(i =0; i < t; i++){if(str[i][0]== s)break;}if(!firstflag[i]){int k = fcnt[i];for(j =0; str[i][j]!='\0'; j++){if(j ==2|| str[i][j]=='|'){if(is_fin(str[i][j +1]))firstvt[i][k++]= str[i][j +1];else{if(is_fin(str[i][j +2]))firstvt[i][k++]= str[i][j +2];if(str[i][j +1]!= s){get_firstvt(str[i][j +1], t);for(ii =0; ii < t; ii++){if(str[ii][0]== str[i][j +1])break;}for(jj =0; jj < fcnt[ii]; jj++){for(tt =0; tt < k; tt++){if(firstvt[i][tt]== firstvt[ii][jj])break;}if(tt == k)firstvt[i][k++]= firstvt[ii][jj];}}}}}firstvt[i][k]='\0';fcnt[i]= k;firstflag[i]=1;}}voidoutput_firstvt(int T){for(int i =0; i < T; i++)get_firstvt(str[i][0], T);}voidget_lastvt(char s,int t){int i, j, ii, jj, tt;for(i =0; i < t; i++){if(str[i][0]== s)break;}if(!lastflag[i]){int k = lcnt[i];for(j =0; str[i][j]!='\0'; j++){if(str[i][j +1]=='|'|| str[i][j +1]=='\0'){if(is_fin(str[i][j]))lastvt[i][k++]= str[i][j];else{if(is_fin(str[i][j -1]))lastvt[i][k++]= str[i][j -1];if(str[i][j]!= s){get_lastvt(str[i][j], t);for(ii =0; ii < t; ii++){if(str[ii][0]== str[i][j])break;}for(jj =0; jj < lcnt[ii]; jj++){for(tt =0; tt < k; tt++){if(lastvt[i][tt]== lastvt[ii][jj])break;}if(tt == k)lastvt[i][k++]= lastvt[ii][jj];}}}}}lastvt[i][k]='\0';lcnt[i]= k;lastflag[i]=1;}}voidoutput_lastvt(int T){for(int i =0; i < T; i++)get_lastvt(str[i][0], T);}voidget_table(int T,int cnt){int x =0, y =0;int i, j, ii, jj;for(i =0; i < T; i++){for(j =0; str[i][j]!='\0'; j++){if(str[i][j]!='|')nstr[x][y++]= str[i][j];elseif(str[i][j]=='|'){nstr[x][y]='\0';x++;y =0;nstr[x][y++]= str[i][0];nstr[x][y++]='-';nstr[x][y++]='>';}}nstr[x][y]='\0';x++;y =0;}char a ='#';cmp[site(a)][site(a)]='=';for(i =0; i < fcnt[0]; i++)cmp[site(a)][site(firstvt[0][i])]='<';for(i =0; i < lcnt[0]; i++)cmp[site(lastvt[0][i])][site(a)]='>';for(i =0; i < x; i++){for(j =3; nstr[i][j +1]!='\0'; j++){if(is_fin(nstr[i][j])&&is_fin(nstr[i][j +1]))cmp[site(nstr[i][j])][site(nstr[i][j +1])]='=';if(is_fin(nstr[i][j])&&!is_fin(nstr[i][j +1])&&is_fin(nstr[i][j +2])&& nstr[i][j +2]!='\0')cmp[site(nstr[i][j])][site(nstr[i][j +2])]='=';if(!is_fin(nstr[i][j])&&is_fin(nstr[i][j +1])){for(ii =0; ii < T; ii++){if(str[ii][0]== nstr[i][j])break;}for(jj =0; jj < lcnt[ii]; jj++)cmp[site(lastvt[ii][jj])][site(nstr[i][j +1])]='>';}if(is_fin(nstr[i][j])&&!is_fin(nstr[i][j +1])){for(ii =0; ii < T; ii++){if(str[ii][0]== nstr[i][j +1])break;}for(jj =0; jj < fcnt[ii]; jj++)cmp[site(nstr[i][j])][site(firstvt[ii][jj])]='<';}}}}voidoutput(int i,int j,char*str){printf("\t");for(int ii = i; ii <= j; ii++)printf("%c", str[ii]);}intisDX(char c){if(c >='A'&& c <='Z')return1;return0;}voidexchange(){int ecnt =0;for(int i =0; i <10; i++){int mcnt =0;for(int j =3; nstr[i][j]!='\0'; j++){if(isDX(nstr[i][j])&&strlen(nstr[i])!=4)mstr[ecnt][mcnt++]='N';elseif(!isDX(nstr[i][j]))mstr[ecnt][mcnt++]= nstr[i][j];elsebreak;}mstr[ecnt][mcnt]='\0';if(strlen(mstr[ecnt])!=0)ecnt++;}}intget_process(char*st){exchange();int len =strlen(st);int t =0;int bz =1;int i =0, j;stac[0]='#';while(st[i]!='\0'){if(is_fin(stac[t]))j = t;elsej = t -1;int a =site(stac[j]);int b =site(st[i]);if(cmp[a][b]=='<'|| cmp[a][b]=='='){printf("\t%d", bz++);output(0, t, stac);printf("\t%c\t%c", cmp[a][b], st[i]);output(i +1, len -1, st);printf("\tyijin\n");t++;stac[t]= st[i];i++;}elseif(cmp[a][b]=='>'){printf("\t%d", bz++);output(0, t, stac);printf("\t%c\t%c", cmp[a][b], st[i]);output(i +1, len -1, st);printf("\tguiyue\n");int ii, jj, kk;int flag =0;for(ii = t; ii >=0; ii--){for(jj =0; jj < maxn; jj++){int lee =strlen(mstr[jj]);int kkn =0;for(kk = lee -1; kk >=0; kk--){if(stac[ii]== mstr[jj][kk]){ii--;kkn++;}elsebreak;}if(strlen(mstr[jj])== kkn){t = ii +1;stac[t++]='N';stac[t]='\0';t--;flag =1;break;}elseii = ii + kkn;}if(!flag){printf("\tcuowu\n");return0;}else{if(t ==1&& st[i]=='#'){printf("\t%d", bz++);output(0, t, stac);printf("\t=\t%c\t \tjieshou\n", st[i]);return1;}break;}}}}}intmain(){int T;while(~scanf("%d",&T)){int cnt =0;memset(firstflag,0,sizeof(firstflag));memset(lastflag,0,sizeof(lastflag));memset(cmp,0,sizeof(cmp));for(int i =0; i < T; i++){scanf("%s", str[i]);fcnt[i]= lcnt[i]=0;}for(int i =0; i < T; i++){for(int j =0; str[i][j]!='\0'; j++){if((str[i][j]<'A'|| str[i][j]>'Z')&&(str[i][j]!='-'&& str[i][j]!='>')&& str[i][j]!='|')fin[cnt++]= str[i][j];}}fin[cnt++]='#';fin[cnt]='\0';output_firstvt(T);output_lastvt(T);get_table(T, cnt);scanf("%s", st);get_process(st);}return0;}
J - LL(1)文法系列(一)first集和follow集
Description
已知文法G[S]的表达式,计算文法中终结符的first集和follow集。在文法G[S]中使用’@’代表空。现在我们规定文法G[S]中每个表达式只包含一个语句,也就是说不会含有S->A|B这样的表达式。Input
第一行输入一个n(n<10),表示表达式的个数,接下来n行,每行一个表达式。终结符和非终结符的个数都小于10
Output
按照终结符和非终结符输入的顺序输出。如果集合中包含’@’或’#’,要求’@’位于第一个,’#’位于最后一个。
输出格式为:
first[c]= a b c
follow[c]= a b c
每个非终结符后都有空格Samples
Sample #1
Input
Output
4
S->ABC
A->a
B->@
C->c
first[S]= a
first[A]= a
first[B]= @
first[C]= c
follow[S]=#
follow[A]= c
follow[B]= c
follow[C]=#
#include<cstdio>#include<cstring>#include<map>#include<stack>#include<algorithm>usingnamespace std;structnode{char s1[10], s2[20];} g[100];char s[100];int num ;
map<char,int> Map1;//对终结符映射
map<char,int> Map2;//对非终结符映射int Map1_num, Map2_num;//记录终结符个数,非终结符个数char s1[100], s2[100];//存储终结符和非终结符int first[20][20];int follow[20][20];int vis[100];//禁止重复递归int acc[20];//使用以求得的集合int select1[100][20];int c[20][20];char sta[100];int cnt ;voiddfs1(char ch,int dis[]){if( acc[ Map1[ch]]){for(int i =1; i <= Map2_num; i++)dis[i]= first[ Map1[ch]][i];return;}int value[20];memset(value,0,sizeof(value));for(int i =1; i <= num ; i++){if( vis[i])continue;if( g[i].s1[0]!= ch )continue;int j , k , len =strlen(g[i].s2);for(j =0; j < len ; j++){if( Map1[ g[i].s2[j]]){vis[i]=1;dfs1(g[i].s2[j],value);for(k =2; k <= Map2_num ; k++)if( value[k]) dis[k]=1;if( value[1]==0)return;}else{dis[ Map2[ g[i].s2[j]]]=1;break;}}if( j == len )dis[1]=1;}return;}voiddfs2(char ch,int dis[]){int i , j , k , len , flag =0;if( acc[ Map1[ch]]){for(int i =1; i <= Map2_num; i++)dis[i]= follow[ Map1[ch]][i];return;}for(i =1; i <= num ; i++){len =strlen(g[i].s2);for(j =0; j < len ; j++){if( g[i].s2[j]== ch ){flag =1;continue;}if(!flag )continue;if( Map1[ g[i].s2[j]]){for(k =2; k <= Map2_num ; k++)if( first[ Map1[ g[i].s2[j]]][k]) dis[k]=1;if(!first[ Map1[ g[i].s2[j]]][1])flag =0;}else{dis[ Map2[ g[i].s2[j]]]=1;flag =0;}}if(!flag || vis[i])continue;int value[20];memset(value,0,sizeof(value));vis[i]=1;dfs2(g[i].s1[0],value);for(i =1; i <= Map2_num; i++)if( value[i]) dis[i]=1;}}intmain(){int i , j , k , len ;//freopen("data2.in", "r", stdin);//freopen("data2.out", "w", stdout);//输入num = Map1_num = Map2_num =0;Map1.clear();Map2.clear();Map2['@']=++Map2_num;s2[ Map2_num ]='@';int m;scanf("%d",&m);while( m--){scanf("%s", s);len =strlen(s);num++;for(i =0; i <1; i++){g[num].s1[i]= s[i];if(!Map1[ s[i]]){Map1[ s[i]]=++Map1_num ;s1[Map1_num]= s[i];}}g[num].s1[i]='\0';for(i =3; i < len ; i++){g[num].s2[i-3]= s[i];if( s[i]>='A'&& s[i]<='Z'){if(!Map1[ s[i]]){Map1[ s[i]]=++Map1_num ;s1[Map1_num]= s[i];}}else{if(!Map2[ s[i]]){Map2[ s[i]]=++Map2_num;s2[Map2_num]= s[i];}}}g[num].s2[i-3]='\0';}//求firstmemset(first,0,sizeof(first));memset(acc,0,sizeof(acc));for(i =1; i <= Map1_num ; i++){int value[20];memset(vis,0,sizeof(vis));memset(value,0,sizeof(value));dfs1(s1[i],value);for(j =1; j <= Map2_num; j++)first[i][j]= value[j];acc[i]=1;}//求followMap2['#']=++Map2_num ;s2[ Map2_num ]='#';memset(follow,0,sizeof(follow));memset(acc,0,sizeof(acc));for(i =1; i <= Map1_num ; i++){int value[20];memset(vis,0,sizeof(vis));memset(value,0,sizeof(value));if( s1[i]=='S') value[ Map2['#']]=1;dfs2(s1[i],value);for(j =1; j <= Map2_num; j++)follow[i][j]= value[j];acc[i]=1;}//求select1memset(select1,0,sizeof(select1));for(i =1; i <= num ; i++){for(j =0; j <strlen(g[i].s2); j++){if( Map2[ g[i].s2[j]]&& g[i].s2[j]!='@'){select1[i][ Map2[ g[i].s2[j]]]=1;break;}for(k =2; k <= Map2_num ; k++){if( first[ Map1[ g[i].s2[j]]][k]) select1[i][k]=1;}if( first[ Map1[ g[i].s1[j]]][1]==0)break;}if( j ==strlen( g[i].s2 )){for(k =2; k <= Map2_num ; k++)if( follow[ Map1[ g[i].s1[0]]][k]) select1[i][k]=1;}}//预测分析表memset(c,0,sizeof(c));for(i =1; i <= num ; i++){for(j =1; j <= Map2_num ; j++){if( select1[i][j])c[ Map1[ g[i].s1[0]]][j]= i ;}}scanf("%s", s);len =strlen(s);for(i =0; i < len/2; i++){swap( s[i], s[len-1-i]);}cnt =0;i = len-1;char ch;sta[cnt++]='#';sta[cnt++]='S';while( i >=0){if( cnt ==0){printf("@\n");break;}ch = sta[cnt-1];if( Map1[ch]){j = c[ Map1[ch]][ Map2[ s[i]]];if( j ){sta[cnt]='\0';s[i+1]='\0';printf("%s\t%s\t%s->%s\n", sta, s, g[j].s1, g[j].s2);cnt--;for(k =strlen( g[j].s2 )-1; k >=0; k--){if( g[j].s2[k]!='@')sta[cnt++]= g[j].s2[k];}}else{printf("@\n");break;}}else{if( ch == s[i]){sta[cnt]='\0';s[i+1]='\0';printf("%s\t%s\t%c\n", sta, s, ch);cnt--;i--;}else{printf("@\n");break;}}}if( i <0)printf("acc\n");return0;}
L - LL(1)文法系列(二)预测分析表
Description
已知文法G[S]的表达式,计算文法的预测分析表。在文法G[S]中使用’@’代表空。现在我们规定文法G[S]中每个表达式只包含一个语句,也就是说不会含有S->A|B这样的表达式。Input第一行输入一个n(n<10),表示表达式的个数,接下来n行,每行一个表达式。终结符和非终结符的个数都小于10Output
按照终结符和非终结符输入的顺序输出。’#’作为非终结符的最后一个。
按照示例进行输出,使用\\t进行格式控制Samples
Sample #1
Input
Output
4
S->ABC
A->a
B->@
C->ca c #
S ABC
A a
B @
C c
#include<cstdio>#include<cstring>#include<map>#include<stack>#include<algorithm>usingnamespace std;structnode{char s1[10], s2[20];} g[100];char s[100];int num ;
map<char,int> Map1;//对终结符映射
map<char,int> Map2;//对非终结符映射int Map1_num, Map2_num;//记录终结符个数,非终结符个数char s1[100], s2[100];//存储终结符和非终结符int first[20][20];int follow[20][20];int vis[100];//禁止重复递归int acc[20];//使用以求得的集合int select1[100][20];int c[20][20];char sta[100];int cnt ;voiddfs1(char ch,int dis[]){if( acc[ Map1[ch]]){for(int i =1; i <= Map2_num; i++)dis[i]= first[ Map1[ch]][i];return;}int value[20];memset(value,0,sizeof(value));for(int i =1; i <= num ; i++){if( vis[i])continue;if( g[i].s1[0]!= ch )continue;int j , k , len =strlen(g[i].s2);for(j =0; j < len ; j++){if( Map1[ g[i].s2[j]]){vis[i]=1;dfs1(g[i].s2[j],value);for(k =2; k <= Map2_num ; k++)if( value[k]) dis[k]=1;if( value[1]==0)return;}else{dis[ Map2[ g[i].s2[j]]]=1;break;}}if( j == len )dis[1]=1;}return;}voiddfs2(char ch,int dis[]){int i , j , k , len , flag =0;if( acc[ Map1[ch]]){for(int i =1; i <= Map2_num; i++)dis[i]= follow[ Map1[ch]][i];return;}for(i =1; i <= num ; i++){len =strlen(g[i].s2);for(j =0; j < len ; j++){if( g[i].s2[j]== ch ){flag =1;continue;}if(!flag )continue;if( Map1[ g[i].s2[j]]){for(k =2; k <= Map2_num ; k++)if( first[ Map1[ g[i].s2[j]]][k]) dis[k]=1;if(!first[ Map1[ g[i].s2[j]]][1])flag =0;}else{dis[ Map2[ g[i].s2[j]]]=1;flag =0;}}if(!flag || vis[i])continue;int value[20];memset(value,0,sizeof(value));vis[i]=1;dfs2(g[i].s1[0],value);for(i =1; i <= Map2_num; i++)if( value[i]) dis[i]=1;}}intmain(){int i , j , k , len ;//输入num = Map1_num = Map2_num =0;Map1.clear();Map2.clear();Map2['@']=++Map2_num;s2[ Map2_num ]='@';int m;scanf("%d",&m);while( m--){scanf("%s", s);len =strlen(s);num++;for(i =0; i <1; i++){g[num].s1[i]= s[i];if(!Map1[ s[i]]){Map1[ s[i]]=++Map1_num ;s1[Map1_num]= s[i];}}g[num].s1[i]='\0';for(i =3; i < len ; i++){g[num].s2[i-3]= s[i];if( s[i]>='A'&& s[i]<='Z'){if(!Map1[ s[i]]){Map1[ s[i]]=++Map1_num ;s1[Map1_num]= s[i];}}else{if(!Map2[ s[i]]){Map2[ s[i]]=++Map2_num;s2[Map2_num]= s[i];}}}g[num].s2[i-3]='\0';}//求firstmemset(first,0,sizeof(first));memset(acc,0,sizeof(acc));for(i =1; i <= Map1_num ; i++){int value[20];memset(vis,0,sizeof(vis));memset(value,0,sizeof(value));dfs1(s1[i],value);for(j =1; j <= Map2_num; j++)first[i][j]= value[j];acc[i]=1;}//求followMap2['#']=++Map2_num ;s2[ Map2_num ]='#';memset(follow,0,sizeof(follow));memset(acc,0,sizeof(acc));for(i =1; i <= Map1_num ; i++){int value[20];memset(vis,0,sizeof(vis));memset(value,0,sizeof(value));if( s1[i]=='S') value[ Map2['#']]=1;dfs2(s1[i],value);for(j =1; j <= Map2_num; j++)follow[i][j]= value[j];acc[i]=1;}//求select1memset(select1,0,sizeof(select1));for(i =1; i <= num ; i++){for(j =0; j <strlen(g[i].s2); j++){if( Map2[ g[i].s2[j]]&& g[i].s2[j]!='@'){select1[i][ Map2[ g[i].s2[j]]]=1;break;}for(k =2; k <= Map2_num ; k++){if( first[ Map1[ g[i].s2[j]]][k]) select1[i][k]=1;}if( first[ Map1[ g[i].s1[j]]][1]==0)break;}if( j ==strlen( g[i].s2 )){for(k =2; k <= Map2_num ; k++)if( follow[ Map1[ g[i].s1[0]]][k]) select1[i][k]=1;}}//预测分析表memset(c,0,sizeof(c));for(i =1; i <= num ; i++){for(j =1; j <= Map2_num ; j++){if( select1[i][j])c[ Map1[ g[i].s1[0]]][j]= i ;}}for(i =1; i <= Map2_num ; i++){if( i ==1)printf("\t");elseprintf("%c\t", s2[i]);}printf("\n");for(i =1; i <= Map1_num ; i++){printf("%c\t", s1[i]);for(j =2; j <= Map2_num ; j++){if( c[i][j]==0)printf("\t");elseprintf("%s\t", g[ c[i][j]].s2);}printf("\n");}return0;}
M - LR(1)文法
Description
已知文法G[S]的表达式求文法的LR(1)的项目集和Go函数.要求使用广度优先搜索,同时按照字典序进行转换,以保证项目集的序号正确.Input
单组输入,当输入一个@时输入结束.注意: 在输入中以@代表空.规定:文法S的拓广文法为$->SOutput
输出文法的项目集和Go函数,参考示例中的格式Samples
Sample #1
Input
Output
S->rD
D->Dai
D->i
@
Package: 0
$->.S
S->.rD
Package: 1
$->S.
Package: 2
S->r.D
D->.Dai
D->.i
Package: 3
S->rD.
D->D.ai
Package: 4
D->i.
Package: 5
D->Da.i
Package: 6
D->Dai.
01 S
02 r
23 D
24 i
35 a
56 i
#include<iostream>#include<vector>#include<string>#include<map>#include<set>#include<cstring>#include<unordered_map>#include<algorithm>// 用于排序usingnamespace std;vector< vector<char>> G;// 文法G[S]产生式
unordered_map<char, set<char>> ts;// 终结符及它的first集合
unordered_map<char, set<char>> nts;// 非终结符及它的first集合
map< map<string,char>, string> table;// LR分析表structC{// 闭包结构vector< vector<char>> project;// 项目集vector< set<char>> outlook;// 展望集unordered_map<char,int> go;// GO函数};vector<C> c;// 闭包集voidshow_Symbol(){// 输出非终结符for(unordered_map<char, set<char>>::iterator it = nts.begin(); it != nts.end(); it++){cout << it->first;}cout << endl;// 输出终结符for(unordered_map<char, set<char>>::iterator it = ts.begin(); it != ts.end(); it++){cout << it->first;}cout << endl << endl;}voidshow_Closure(){// 打印项目集for(unsignedint i =0; i < c.size(); i++){cout <<"Package: "<< i << endl;for(int j =0; j < c[i].project.size(); j++){for(int k =0; k < c[i].project[j].size(); k++){if(k ==1) cout <<"->";if(c[i].project[j][k]==' ') cout <<".";else cout << c[i].project[j][k];}cout << endl;}}// 修正 Go 函数输出顺序for(unsignedint i =0; i < c.size(); i++){vector<pair<char,int>>goItems(c[i].go.begin(), c[i].go.end());// 按照符号顺序进行排序,保证输出顺序正确sort(goItems.begin(), goItems.end(),[](const pair<char,int>& a,const pair<char,int>& b){return a.first < b.first;});for(auto& it : goItems){cout << i <<" "<< it.second <<" "<< it.first << endl;}}}voidread_G(){// 读取文法G[S]->G'[M],并区分终结符和非终结符char ch;int i =0;vector<char> v;char X;set<char> m;nts['M']= m;while(ch =getchar()){if(ch =='@')break;if(ch =='\n'){if(!v.empty()) G.push_back(v);v.clear();i =0;continue;}if(ch !=' '|| ch !='\t'){if(ch =='|'){G.push_back(v);v.clear();i =3;v.push_back(X);continue;}i++;if(i ==1){X = ch;nts[ch]= m;}elseif(i !=2&& i !=3&& ch !='~') ts[ch]= m;if(i !=2&& i !=3) v.push_back(ch);}}if(G.empty())exit(0);v.clear();v.push_back('$');v.push_back(G[0][0]);G.insert(G.begin(), v);for(unordered_map<char, set<char>>::iterator it = nts.begin(); it != nts.end(); it++){unordered_map<char, set<char>>::iterator iter;iter = ts.find(it->first);if(iter != ts.end()) ts.erase(iter);}}voidget_First(){for(auto& it : ts) it.second.insert(it.first);// 终结符的first集合是它自己int r =0;int change =1;while(change){if(r ==20)break;r++;change =0;for(auto& it : nts){for(unsignedint i =0; i < G.size(); i++){if(G[i][0]== it.first){unsignedint size = it.second.size();unordered_map<char, set<char>>::iterator iter = ts.find(G[i][1]);if(ts.find(G[i][1])!= ts.end()|| G[i][1]=='~'){it.second.insert(G[i][1]);if(it.second.size()> size) change =1;}else{unsignedint col =1;while(1){int flag =0;unordered_map<char, set<char>>::iterator itt = nts.find(G[i][col]);for(auto& iter : itt->second){if(iter =='~') flag =1;else it.second.insert(iter);}if(flag){col++;if(G[i].size()<= col){it.second.insert('~');break;}elseif(ts.find(G[i][col])!= ts.end()){it.second.insert(G[i][col]);break;}}elsebreak;}if(it.second.size()> size) change =1;}}}}}}voidget_Closure(){int i =0;C clo;c.push_back(clo);while(1){if(i == c.size())break;if(i ==0){vector<char>v(G[0]);v.insert(v.begin()+1,' ');c[i].project.push_back(v);set<char> m;m.insert('#');c[i].outlook.push_back(m);}for(unsignedint j =0; j < c[i].project.size(); j++){for(unsignedint k =0; k < c[i].project[j].size(); k++){if(c[i].project[j][k]==' '){if(k == c[i].project[j].size()-1)break;for(unsignedint x =0; x < G.size(); x++){if(G[x][0]== c[i].project[j][k +1]){vector<char>v(G[x]);v.insert(v.begin()+1,' ');int exist =0;for(unsignedint y =0; y < c[i].project.size(); y++){if(c[i].project[y]== v){exist = y;break;}}if(exist ==0) c[i].project.push_back(v);set<char> m;bool kong =true;int t =0;while(kong){kong =false;if(k + t +1== c[i].project[j].size()-1){for(auto it : c[i].outlook[j]) m.insert(it);}elseif(ts.find(c[i].project[j][k + t +2])!= ts.end()){m.insert(c[i].project[j][k +2+ t]);}else{set<char>m1((nts.find(c[i].project[j][k +2+ t]))->second);for(auto it : m1){if(it =='~'){kong =true;t++;}else{m.insert(it);}}}}if(exist){for(auto it : m){c[i].outlook[exist].insert(it);}}else c[i].outlook.push_back(m);}}break;}}}for(unsignedint j =0; j < c[i].project.size(); j++){for(unsignedint k =0; k < c[i].project[j].size(); k++){if(c[i].project[j][k]==' '){if(k == c[i].project[j].size()-1)break;vector<char>new_closure_pro(c[i].project[j]);new_closure_pro[k]= new_closure_pro[k +1];new_closure_pro[k +1]=' ';set<char>new_closure_search(c[i].outlook[j]);bool dif =false;for(unsignedint x =0; x < c.size(); x++){for(unsignedint y =0; y < c[x].project.size(); y++){dif =false;if(new_closure_pro == c[x].project[y]){if(c[x].outlook[0].size()!= new_closure_search.size()){dif =true;continue;}auto iter = c[x].outlook[0].begin();for(auto it : new_closure_search){if(it !=*iter){dif =true;break;}iter++;}if(dif ==false){c[i].go[new_closure_pro[k]]= x;break;}}else dif =true;if(dif ==false)break;}if(dif ==false)break;}if(c[i].go.count(new_closure_pro[k])!=0&& dif){c[c[i].go[new_closure_pro[k]]].project.push_back(new_closure_pro);c[c[i].go[new_closure_pro[k]]].outlook.push_back(new_closure_search);break;}if(dif){C new_closure;new_closure.project.push_back(new_closure_pro);new_closure.outlook.push_back(new_closure_search);c.push_back(new_closure);c[i].go[new_closure_pro[k]]= c.size()-1;}}}}i++;}}intmain(){read_G();cout << endl;get_First();get_Closure();show_Closure();return0;}
N - 翻译布尔表达式
Description
大家都学过了布尔表达式的翻译,其中有一个拉链-回填技术,这次我们就练习这个技术。Input
输入为一行字符串,例如: a < b or c < d and e < f每个符号都用空格间隔。其中逻辑运算符包含 and 和 or , 关系运算符包含 < 、> 、<= 、 >= 、== 、 != 。Output假链跳到0,真链跳到1,表达式序号从100开始排。Samples
Sample #1
Input
Output
a < b or c < d and e < f
100(j<,a,b,1)101(j,_,_,102)102(j<,c,d,104)103(j,_,_,0)104(j<,e,f,100)105(j,_,_,103)
#include<bits/stdc++.h>usingnamespace std;string str, x;int num =100, True =1, False =100;// 序号、真、假
vector<string>v;intmain(){//cin >> str; 无法输入空格getline(cin, str);str +=" #";// 自己额外加的一个结束标志stringstream strr(str);// while(strr >> x){// 以空格为分割点,将str中的字符(串)赋给xif(x =="or"|| x =="#"){if(x =="or") False +=2;else False =0;int len = v.size();for(int i =0; i < len -3; i +=3){printf("%d(j%s,%s,%s,%d)\n", num, v[i+1].c_str(), v[i].c_str(), v[i+2].c_str(), num +2);// 真链num ++;printf("%d(j,_,_,%d)\n", num, False);// 假链False = num++;}printf("%d(j%s,%s,%s,%d)\n", num, v[len-2].c_str(), v[len -3].c_str(), v[len -1].c_str(), True);True = num ++;printf("%d(j,_,_,%d)\n", num, False);num++;v.clear();if(x =="#")break;// 读到结束符停止}elseif(x =="and") False +=2;else v.push_back(x);}return0;}