1.问题的描述:有一个魔王总是用自己一种非常精练而抽象的语言讲话,没有人能听懂,但他的语言可以逐步的转换成人的语言,他的语言由以下两种转换规则由人的语言逐步抽象上去的:
2.基本要求:实现用下述两条具体规则和上述规则(2)编写魔语解释系统。设大写字母表示魔王语言的词汇;小写字母表示人的词汇;希腊字母表示可以用大写字母或小写字母代换的变量。魔王语言可以含人的词汇。(1)b tada;(2)a sae.
#include
#include
#include
#include
#define len 20
#define l_size 100
struct
{
char ra[20];
char ra[20];
}rule[len];
struct
{
char ma[20];
char ma[20];
}mean[len];
//栈的操作
typedef struct node
{
char data;
struct node * next;
}linkstacknode, * linkstack;
//初始化栈
void initstack(linkstack * top)
{
(* top) = (linkstack)malloc(sizeof(linkstacknode));
(* top) -> next = null;
}
//入栈
void push(linkstack top, char a)
{
linkstacknode * temp;
temp = (linkstacknode *)malloc(sizeof(linkstacknode));
temp -> data = a;
temp -> next = top -> next;
top -> next = temp;
}
//出栈
void pop(linkstack top, char *x)
{
linkstacknode * temp;
temp = top -> next;
top -> next = temp -> next;
*x = temp -> data;
free(temp);
}
//队列的操作
typedef struct node
{
char data;
struct node * next;
}linkqueuenode;
typedef struct
{
linkqueuenode * front;
linkqueuenode * rear;
}linkqueue;
//队列初始化
void initqueue(linkqueue *q)
{
q -> front = (linkqueuenode *)malloc(sizeof(linkqueuenode));
if(q->front != null)
{
q -> rear = q -> front;
q -> front -> next = null;
}
}
//入队
void enterqueue(linkqueue *q, char x)
{
linkqueuenode * newnode;
newnode=(linkqueuenode *)malloc(sizeof(linkqueuenode));
if(newnode != null)
{
newnode -> data = x;
newnode -> next = null;
q -> rear -> next = newnode;
q -> rear = newnode;
}
}
//出队
void deletequeue(linkqueue *q, char *x)
{
linkqueuenode * p;
p = q -> front -> next;
q -> front -> next = p -> next;
if(q -> rear == p)
q -> rear = q -> front;
*x = p -> data;
free(p);
}
//读规则文件
void read_rulefile() //读取文件
{
file * fp;
char filename[len];
int i = 0;
printf("please enter the name of the file to open rules:");//读取文本文件(rule.txt), 将具体规则的对应关系读入数组
fgets(filename, len, stdin);
fp = fopen("rule.txt", "rt");
if(null == fp)
{
printf("\nfailed to open file,%sfile may not exist\n",filename);
printf("exit\n");
exit(1);
}
while(fscanf(fp, "%s %s", rule[i].ra, rule[i].ra) != eof)
{
printf("%s %s\n", rule[i].ra, rule[i].ra);
i ;
}
fclose(fp);
return;
}
void read_meanfile()
{
file * fp;
char filename[len];
int i = 0;
printf("please enter the name of the file to open the meaning of:");//读取文本文件(mean.txt), 将小写字母及其对应的含义读入数组
fgets(filename, len, stdin);
fp = fopen("mean.txt", "rt");
if(null == fp)
{
printf("\nfailed to open file,%sfile may not exist\n", filename);
printf("exiti\n");
exit(1);
}
while(fscanf(fp, "%s %s", mean[i].ma, mean[i].ma) != eof)
{
printf("%s %s\n", mean[i].ma, mean[i].ma);
i ;
}
fclose(fp) ;
return;
}
//写文件操作
void save_result(char l[]) //把结果写入result.txt文档中
{
file * fp;
char filename[len];
int i = 0, j;
printf("\nplease enter the file to be saved file name:");
scanf("%s", filename);
if((fp = fopen(filename, "wt")) == null)
{
printf("write file error, press any key to exit!");
exit(1);
}
while(l[i] != '\0')
{
for(j = 0; j < 20; j )
{
if(l[i] == mean[j].ma[0])
fprintf(fp, "%s", mean[j].ma);
}
i ;
}
printf("file is saved successfully, press any key to return!\n");
fclose(fp);
}
//去括号
/*思想:当没遇到闭括号时,一直压栈(top栈)。一旦遇到闭括号,首先找到与这个闭括号最近的匹配的开括号找到这两个括号“(” “)”之间的第一个字符利用队列(q 入队)以及(top栈出栈)完成转换,再把转换后的队列,添加到(top栈中)把剩余的字符原样添加到top栈中在把top栈逆置到top1栈中再利用top1栈出栈,给l重新赋值。递归,看l中是否还有括号*/
void tackle_2(linkstacknode * top, linkstacknode * top1, linkqueue * q, char l[])
{
int i = 0, j;
char * a;
char first;
a = (char *)malloc(sizeof(char));
initstack(&top);
initqueue(q); //辅助用来输出括号内的内容
initstack(&top1);
while(l[i] != ')')
{
push(top, l[i]);//当不等于‘)’时,往top栈中压。
i ;
}
if(l[i] == ')') //当等于')'时
{
j = i;
while(l[j] != '(')
{
j--;
if(l[j] == '(')
{
j ;
break;
}
}
first = l[j];//找到当前‘( ’内的第一个字符
for(;j < i - 1; j )
{
enterqueue(q, first);
pop(top, a);
enterqueue(q, *a);
}
pop(top, a); //这个是括号内的第一个字符
enterqueue(q, *a);
pop(top, a); //把‘(’删掉
while(q -> front -> next != null)
{
deletequeue(q,a);
push(top,*a);
}
} //if
i ; //跳过‘)’
while(l[i] != '\0')
{
push(top, l[i]);
i ;
}
while(top -> next != null)
{
pop(top, a);
push(top1, *a);
}
i = 0;
while(top1 -> next != null)
{
pop(top1,a);
l[i] = *a;
i ;
}
l[i] = '\0';
i = 0;
j = 0;
while(l[i] != '\0')
{
i ;
if(l[i] == '(' || l[i] == ')')
j ;
}
if(j == 0)
return;
else
tackle_2(top, top1, q, l);
}
//实现提示:处理规则形式(1)问题并没有规定具体规则的数量.比如增加一条具体规则c→eb那么对魔王语言就要多处理一次,因此处理规则形式(1)时需要递归处理,当语言中没有大写字母后递归结束。
void tackle_1(char l[], linkqueue * q)
{
int i = 0, j, z;
int k = 0;
char * a;
a = (char *)malloc(sizeof(char));
while(l[i] != '\0')
{
z = 0;
for(j = 0; j < 20; j )
{
if(l[i] == rule[j].ra[0])
{
k = 0;
z = 1;
while(rule[j].ra[k] != '\0')
{
enterqueue(q, rule[j].ra[k]);
k ;
}
}
}
if(z == 1)
{
i ;
}
else
{
enterqueue(q, l[i]);
i ;
}
}
i = 0;
while(q -> front -> next != null)
{
deletequeue(q, a);
l[i] = (*a);
i ;
}
l[i] = '\0';
i = 0;
j = 0;
while(l[i] != '\0')
{
if(l[i] >= 'a' && l[i] <= 'z')
j ;
i ;
}
if(j == 0)
return;
else
tackle_1(l, q);////递归调用
}
void tackle_12(char l[])
{
int i = 0;
int j;
while(l[i] != '\0')
{
for(j = 0; j < 20; j )
{
if(l[i] == mean[j].ma[0])
printf("%s", mean[j].ma);
}
i ;
}
printf("\n");
}
int main(int argc, char *argv[])
{
int j = 0;
read_rulefile();
read_meanfile();
char l[l_size]; //魔王说的话
printf("please enter the devil king language:");
scanf("%s", l);
linkstacknode * top, * top1;
top = (linkstacknode * )malloc(sizeof(linkstacknode));
top1 = (linkstacknode * )malloc(sizeof(linkstacknode));
linkqueue *q;
q = (linkqueue *)malloc(sizeof(linkqueue));
tackle_2(top, top1, q, l);
printf("devil king to say what is:%s", l);
tackle_1(l, q);
printf("\ndevil to say what is(convert after lowercase):%s\n", l);
tackle_12(l);
printf("devil to say mean:%s\n", mean[j].ma);
tackle_12(l);
save_result(l);
return exit_success;
}