?? 050320161cfl.cpp
字號:
/********************************************************************************
程序功能:給定一個上下文無關文法的n條產生式規則,編程判斷該文法對應的語言是否為空
********************************************************************************/
#include <fstream.h>
#include <string.h>
#include <ctype.h>
void main()
{
int n,i;
//**非終結符只有26個大寫字母,所以總共只有26種可能****
//如果值為1 表示該非終結符在下面的規則下可以轉化為終結符
//如果值為0 表示該非終結符在下面的規則下可以轉化為終結符
short int flag[26];
ifstream input("input.txt");
ofstream output("output.txt");
input>>n;
//用來存儲規則的左邊
char *left=new char [n+1];
//用來存儲規則的右邊
char** right=new char* [n+1];
//用來處理讀取數據的中間過渡變量
char tmp[500];
//讀取文本數據處理過程
for(i=1;i<=n;i++)
{
input>>tmp;
left[i]=tmp[0];
input>>tmp;
right[i]=new char [strlen(tmp)+1];
strcpy(right[i],tmp);
}
//初始化為0,表示不能轉化為終結符
for(i=0;i<=25;i++)
flag[i]=0;
char* temp;
//**用來表示每完成一次掃描,是否有一個新的非終結符號可以轉化為
//***非終結符,如果有則繼續新的掃描,沒有的話則退出整個掃描過程
bool pd=true;
while (pd)
{
pd=false;
for(i=1;i<=n;i++)
{
//指針指向規則右部的第一字符
temp=right[i];
//先判斷該規則左部的非終結符是否已經可以化為終結符,可以的話掃描
//下一條規則,不可以的話繼續掃描該規則,判斷是否可以轉化為終結符
if (flag[left[i]-65]==0)
{
while (*temp)
{
//如果該字符是非終結符,則判斷該非終結符
//如果該字符是終結符,則判斷規則的下一個字符
if ( isupper(*temp) )
{
//該字符如果不可以化為非終結符,則跳出
//可以的話則判斷該規則的下一個字符
if (flag[*temp-65]==0)
break;
else
temp++;
}
else
temp++;
}
//如果這個時候指針指向的時候是空的時候,代表該規則左部的非終結符可以化為終結符
//如果非空,代表該規則左部的非終結符在這一次掃描中沒辦法化為終結符
if (!(*temp))
{
flag[left[i]-65]=1;
pd=true;
}
}
}
//如果S可以化為終結符,則跳出整個掃描過程
if (flag[18]==1)
pd=false;
}
if (flag[18]==0)
output<<"yes";
else
output<<"no";
//釋放空間
delete []left;
for(i=1;i<=n;i++)
{
delete [] right[i];
}
delete [] right;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -