魔王语言问题c语言实现及思路求解


问题描述及需求分析


有一个魔王总是使用自己的一种非常精炼而抽象的语言讲话,没有人能听懂。但他的语言是可以逐步解释成人能懂的语言的,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
(1) α→β1…βm
(2) (θδ1…δn) →θδnθδn-1…θδ1θ 在这两种形式中,从左到右均表示解释;从右到左均表示抽象。试写一个魔王语言的解释系统,把他的话解释成人能听得懂的话。
测试数据:
用下述两条具体规则和上述规则形式(2)实现。设大写字母表示魔王语言解释的词汇,小写字母表示人的语言的词汇;希腊字母表示可以用大写或小写字母代换的变量。魔王语言可含人的词汇。
(1).Β→ tΑdΑ
(2).Α→ sae
测试数据:
B(einxgz)B
解释成 tsaedsaeezegexeneietsaedsae 若将小写字母与汉字建立下表所示的对应关系,则魔王说的话是:“天上一个鹅地上一个鹅鹅追鹅赶鹅下鹅蛋鹅恨鹅天上一个鹅地上一个鹅。”
t d s a e z g x n i
天 地 上 一个 鹅 追 赶 下 蛋 恨

需求分析

1.创建一个队列和栈。
2.要求输入一串魔王语言。
3.解码方式:B->tAdA, A->sae
4.根据魔王语言与对应汉字关系进行输出打印


问题分析及实现路线(队列+栈)

提示:将魔王的语言自右至左进栈,总是处理栈顶。若是开括号,则逐一出栈,将字母顺序入队列,直至闭括号出栈,并按规则要求逐一出队列再处理后入栈。其他情形较简单,请读者思考应如何处理。应首先实现栈和队列的基本运算。

结构体核心代码

//定义队列和栈的结点
typedef struct node{
    char data;
    struct node *next;
}LinkNode;
//定义栈的栈顶指针
typedef struct {
    LinkNode *top;
}LinkStack;
//定义队列的队头和队尾
typedef struct{
    LinkNode * rear,*front;
}LinkQueue;

队列核心代码

入队

//入队
void InQueue(LinkQueue *queue,char x){
    LinkNode *p = (LinkNode*) malloc(sizeof (LinkNode*));
    p->data = x;
    p->next = NULL;
    if(queue->front ==NULL){
        queue->front = queue->rear = p;
    }
    else {
        queue->rear->next = p;
        queue->rear = p;
    }
}

出队

//出栈
char pop(LinkStack *stack ){
    if(stack->top==NULL){
        return 0;
    }
//    出栈
    LinkNode *p = stack->top;
    stack->top = p->next;
    char temp = p->data;        //保存出栈的值
    free(p);
    return temp;
}

栈的核心代码

入栈

//入栈(链栈)
void push(LinkStack *stack,char x){
    LinkNode *p = (LinkNode *)malloc(sizeof (LinkNode));
    p->data = x;
    p->next = stack->top;
    stack->top = p;
}
//入队

出栈

//出栈
char pop(LinkStack *stack ){
    if(stack->top==NULL){
        return 0;
    }
//    出栈
    LinkNode *p = stack->top;
    stack->top = p->next;
    char temp = p->data;        //保存出栈的值
    free(p);
    return temp;
}

全部代码

代码如下(示例):

c
#include <stdio.h>
#include <string.h>
#include <malloc.h>

//定义队列和栈的结点
typedef struct node{
    char data;
    struct node *next;
}LinkNode;
//定义栈的栈顶指针
typedef struct {
    LinkNode *top;
}LinkStack;
//定义队列的队头和队尾
typedef struct{
    LinkNode * rear,*front;
}LinkQueue;
//初始化队列
void InitQueue(LinkQueue *queue) {
    queue->front = queue->rear = NULL;
}
//初始化栈
void InitStack(LinkStack *stack){
    stack->top = NULL;
}
//入栈
void push(LinkStack *stack,char x){
    LinkNode *p = (LinkNode *)malloc(sizeof (LinkNode));
    p->data = x;
    p->next = stack->top;
    stack->top = p;
}
//入队
void InQueue(LinkQueue *queue,char x){
    LinkNode *p = (LinkNode*) malloc(sizeof (LinkNode*));
    p->data = x;
    p->next = NULL;
    if(queue->front ==NULL){
        queue->front = queue->rear = p;
    }
    else {
        queue->rear->next = p;
        queue->rear = p;
    }
}
//出栈
char pop(LinkStack *stack ){
    if(stack->top==NULL){
        return 0;
    }
//    出栈
    LinkNode *p = stack->top;
    stack->top = p->next;
    char temp = p->data;        //保存出栈的值
    free(p);
    return temp;
}
//出队列
char DeQueue(LinkQueue *queue){
    if(queue->front ==NULL){
        return 0;
    }
    LinkNode *p = queue->front;
    char temp = p->data;        //保存出队列的值
    queue->front = p->next;
    free(p);
    return temp;
}
//判断出栈结束位置
void deal(LinkQueue *queue,LinkStack *stack){
    char res = pop(stack);
//    当遇到闭括号时出栈结束
    while(res !=')') {
        InQueue(queue,res);
        res = pop(stack);
    }
    char first = DeQueue(queue);        //保留第一个希腊字母
    push(stack,first);
    while(queue->front!=NULL){
        res = DeQueue(queue);
//        压入原先字母和第一个希腊字母和
        push(stack,res);
        push(stack,first);
    }
}
//匹配文字,输出结果
void metch(char x){
    char password[11] = "tdsaezgxni";
    char chinese[10][8] = {"天","地","上","一个","鹅","追","赶","下","蛋","恨"};
    for(int i = 0;i< strlen(password);i++){
        if(x ==password[i]){
            printf("%s",chinese[i]);
        }
    }

}
//把翻译出来的密码进行翻译,得到最终结果
void printresult(char x){
    char A_string[4] ="sae";
    if(x =='A'){
        for(int k = 0;k< strlen(A_string);k++){
            metch(A_string[k]);     //匹配字符
        }
    }
    else{
        metch(x);
    }
}
int main() {

    printf("解释魔王语言,请输入魔王语言!\n");
    char language[100];
//    获取输入
    gets(language);
    char B_string[5] ="tAdA";
    LinkStack ptr;
    InitStack(&ptr);        //初始化栈
    LinkQueue queue;
    InitQueue(&queue);      //          初始化队列
    int count =0;
    for(int i = strlen(language)-1;i>=0;i--){
//        判断是否已经全部入栈
        if(language[i]=='\000') {
            break;
        }
//        从右往左,入栈到'('时开始,出栈,入队列
        else if(language[i] =='('){
            deal(&queue,&ptr);
        }
        else{
//            先处理‘B'
            if(language[i] =='B'){
                for(int j = strlen(B_string)-1;j>=0;j--){
//                    把B对应密码,倒序压入
                    push(&ptr,B_string[j]);
                }
            }
            else{
//                压栈
                push(&ptr,language[i]);
            }
        }
        count++;
    }
    char temp;
    while(ptr.top!=NULL){
//        打印结果,测试数据B(einxgz)B
        temp = pop(&ptr);
        printresult(temp);      //打印结果
    }
    return 0;
}


单向循环队列和栈(改变B的对应密码)

全部代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义栈的结点
#define Max 100
typedef struct{
    char *base;
    char *top;
    int size;
}seqStack;
//定义队列
typedef struct{
    char *data;
    int front;
    int rear;
}seqQueue;
//初始话栈
void initseqStack(seqStack *stack){
    stack->base = (char*)malloc(Max*sizeof (char));
    if(stack->base==NULL){
        exit(1);
    }
    stack->top = stack->base;
    stack->size = Max;
}
//初始化队列
void initseqQueue(seqQueue *queue){
    queue->data =(char*)malloc(Max*sizeof (char));
    if(queue->data==NULL){
        exit(1);
    }
    queue->front = queue->rear =0;

}
//入队
void inQueue(seqQueue *queue,char x){
    if((queue->rear+1)%Max ==queue->front ){
        printf("队列已满");
        exit(1);
    }
    queue->data[queue->rear] =x;
    queue->rear = (queue->rear+1)%Max;

}
//出队
char deQueue(seqQueue *queue){
    if((queue->rear+1)%Max ==queue->front){
        printf("????????");
        exit(1);
    }
    char temp = queue->data[queue->front];
    queue->front = ((queue->front+1)%Max);
    return temp;

}
//入栈
void push(seqStack *stack,char x){
    if(stack->top - stack->base ==stack->size){
        stack->base = (char*) realloc(stack->base,(stack->size+Max)*sizeof (char));
        if(stack->base ==NULL){
            exit(1);
        }
        stack->top = stack->base+stack->size;
        stack->size +=Max;
    }
    *(stack->top++) =x;

}
//出栈
char pop(seqStack *stack){
    if(stack->base ==stack->top){
        return 0;
    }
    char temp= *(--stack->top);
    return temp;
}
//进行处理
void deal(seqQueue *queue,seqStack *stack){
    char res = pop(stack);
//   保存栈第一个的字符
    while(res !=')') {
        inQueue(queue,res);
        res = pop(stack);
    }
    char first = deQueue(queue);        //保留队列的第一个元素
    push(stack,first);
    while(queue->front!=queue->rear){
        res = deQueue(queue);
//        把3元素压入栈,并且得压入那个添加得元素
        push(stack,res);
        push(stack,first);
    }
}
//匹配结果
void metch(char x){
    char password[11] = "tdsaezgxni";
    char chinese[10][8] = {"天","地","上","一个","鹅","追","赶","下","蛋","恨"};
    for(int i = 0;i< strlen(password);i++){
        if(x ==password[i]){
            printf("%s",chinese[i]);
        }
    }

}
//打印结果
void printresult(char x){
    char A_string[4] ="sae";
    if(x =='A'){
        for(int k = 0;k< strlen(A_string);k++){
            metch(A_string[k]);     //匹配字符
        }
    }
    else{
        metch(x);
    }
}
int main() {
    printf("解释魔王语言,请输入魔王语言!!\n");
    char language[100];
//    获取输入
    gets(language);
    char B_string[100];
    printf("请输入'B'对应得字符");
    gets(B_string);
    seqStack stack;
    initseqStack(&stack);
    seqQueue queue;
    initseqQueue(&queue);
    int count =0;
    for(int i = strlen(language)-1;i>=0;i--) {
//        判断是否已经全部入栈
        if (language[i] == '\000') {
            break;
        } else if (language[i] == '(') {
            deal(&queue, &stack);
        }
//        从右往左,入栈到'('时开始,出栈,入队列
        else {
//            先处理‘B'
            if (language[i] == 'B') {
                for (int j = strlen(B_string) - 1; j >= 0; j--) {
//                    把B对应密码,倒序压入
                    if(B_string[j]!='\000') {
                        push(&stack, B_string[j]);
                    }
                }
            } else {
//                压栈
                push(&stack, language[i]);
            }
        }
    }
    char temp;
    while(stack.top!=stack.base){
//        打印结果,测试数据B(einxgz)B
        temp = pop(&stack);
        printresult(temp);      //打印结果
    }
    return 0;
}

总结

这里对文章进行总结,把魔王语言进行两种解释方式,并采用不同的结构,代码很烂,可供参考,希望大佬指点小弟,在评论区指点迷津。

posted @ 2021-11-12 23:56  Leo哥coding~  阅读(125)  评论(0编辑  收藏  举报  来源