问题描述及需求分析

有一个魔王总是使用自己的一种非常精炼而抽象的语言讲话,没有人能听懂。但他的语言是可以逐步解释成人能懂的语言的,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
(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;
}

总结

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

魔王语言问题c语言实现及思路求解的更多相关文章

  1. 【C语言】C语言简介

    目录: 1. [什么是C语言?] 2. [C语言历史] 3. [C语言标准] 4. [C语言特点] 1. 什么事C语言? · C语言是一门高级编程语言,用于人与计算机之间的沟通,就如同人与人之间沟通时 ...

  2. Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?

    [编者按]本文作者@徐珂铭,一位看好Html5的移动互联网的从业人士.喜爱玩技术,会点JAVA.HTML及CSS,有自己的想法及姑且能表达想法的文字,因此有了自己的文章. 基于HTML5的Web Ap ...

  3. 初识GO语言——安装Go语言

    本文包括:1)安装Go语言.2)运行第一个Go语言.3)增加vim中对Go语言的高亮支持. 1.安装Go语言 本文采用源码安装Go语言,Go语言的源代码在百度网盘 http://pan.baidu.c ...

  4. 【C语言】01-C语言概述

      说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略 为什么iOS开发要先学C语 ...

  5. Java语言与C++语言的差异总结

    Java的设计者曾说过,设计这门语言的灵感主要来自于C++. 世上先有C++,然后才有Java,整个Java语言的发展历史就是一部对C++的填坑史.所以在Java语言学习过程中,将其与C++语言对比是 ...

  6. 为什么和其他语言相比C语言是快速的语言

    初入门的我们经常听见别人说"真正的程序员用C语言编程,C是最快的语言因为它是最靠近及其底层的语言."那么和其他语言相比C语言到底有什么特别的呢? C语言没有什么特别,这就是它快速的 ...

  7. Swift语言指南(七)--语言基础之布尔值和类型别名

    原文:Swift语言指南(七)--语言基础之布尔值和类型别名 布尔值 Swift有一个基本布尔类型,叫做布尔(bool),布尔值又称逻辑值(logical),因为它只能为真(true)或假(false ...

  8. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  9. Swift语言指南(三)--语言基础之整数和浮点数

    原文:Swift语言指南(三)--语言基础之整数和浮点数 整数 整数指没有小数的整数,如42,-23.整数可以是有符号的(正数,零,负数),也可以是无符号的(正数,零). Swift提供了8,16,3 ...

  10. Swift语言指南(一)--语言基础之常量和变量

    原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...

随机推荐

  1. Nginx lavarel框架伪静态配置

    location / { try_files $uri $uri/ /index.php$is_args$query_string; }

  2. 入门VUEX

    我对VUEX的理解就是,vuex提供了一个数据仓库 相比较vue里的 data{      return{      ****:**,      ***:*** } } vuex提供的仓库会一直在项目 ...

  3. mysql 以自增id等于某个random()函数算出的值为条件查出两条数据

    SELECT id FROM users WHERE id = FLOOR( rand() * ( (SELECT max(id) FROM users) - (SELECT min(id) FROM ...

  4. 使用ActiveMQ中遇到的端口占用问题

    原Linux虚拟机中安装了ActiveMQ,EMQX.后期使用中主要使用EMQX来实现消息服务,停止了ActiveMQ.但是虚拟机挂起之后,长时间未再使用.近期由于有使用ActiveMQ的需要,而临时 ...

  5. 04-Spring中的AOP编程之基于xml开发

    AOP编程 ​ AOP为Aspect Oriented Programming的缩写,意为:面向切面编程.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的 ...

  6. linux 查看进程的启动开始时间

    先使用命令查看需要查看的进程 ps -ef | grep java root 29861 13755 2 09:42 pts/0 00:10:48 java -jar XXXX.jar ps axo ...

  7. Python学习笔记--第二阶段啦

    初识对象 示例: 类的成员方法 上图中的self必须填写!!! 示例: 类和对象 有c和c++语言基础的话,就会发现其实是一样的道理,只是实现代码有差异 构造方法(init) 示例: 注意: 其他内置 ...

  8. 最近写了一个demo,想看看java和go语言是怎么写的

    最近写了一个demo:demo的github地址 一. 简单介绍 1. Server端 它是一个WebApi服务,把它当成一个黑盒就行了. 2. MiddleServer端 是重点,它是一个WebAp ...

  9. CAS 单点登录系统

    一.什么是单点登录 单点登录(Sign Sion On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系 ...

  10. 怎么在php7项目中安装event扩展

    今天就跟大家聊聊有关怎么在php7项目中安装event扩展,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获. 安装支持库libevent wget ...