问题描述及需求分析

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

    简单的一个分块处理:优雅的暴力枚举 #include<bits/stdc++.h>using namespace std; typedef long long ll;const int N ...

  2. WPF中转换与关键帧动画及报错:WPF动画找不到依赖属性:属性未指向路径“(0).(1)[3].(2)”中的 DependencyObject

    WPF中的转换有: // 在二维 x-y 坐标系内围绕指定点按顺时针方向旋转对象. <RotateTransform /> // 在二维 x-y 坐标系中平移(移动)对象. <Tra ...

  3. windows2012通过powershell安装远程组件技巧

    概要: 通过服务器管理器安装远程桌面服务会报错一直没有办法解决 之后了解到安装组件可以通过powershell命令安装   powershell命令说明 https://docs.microsoft. ...

  4. Python基础教程:字典

    字典 = {'键1':'值1','键2':'值2','键3':'值3',...} animal_dict = {'Cow':'Milk','Chicken':'egg'} 字典由键值对构成,这种键值对 ...

  5. Codeforces Round 857 (Div. 2) A-D

    Codeforces Round 857 (Div. 2) A. Likes 求每回合最大的数列:先全使用正数,每个正数对ans++,再全使用负数,每个负数对ans-- 求每回合最小的数列:方法1(模 ...

  6. 痞子衡嵌入式:我当选了2019年度官方论坛i.MXRT板块的顶级贡献者

    痞子衡桌上有一个联邦快递公司件,放了近一个月了,是同事代领的,痞子衡一直没有拆开.今天心血来潮,决定拆开瞧一瞧,这一拆就拆出了一天的好心情. 原来快递里面是一件i.MXRT产品纪念T-shirt,还有 ...

  7. Java笔记第十二弹

    Lambda表达式的标准格式 三要素:形式参数.箭头.代码块 格式:(形式参数)->(代码块) 形式参数:如果有多个参数,参数之间用逗号隔开:如果没有参数,留空即可 ->代表指向动作 La ...

  8. Bootstarp5笔记

    我这次来更新Bootstarp5的相关知识啦! 一.安装教程 1.在官网下载相应版本 官网地址:getbootstrap.com 我下载的是Bootstarp5版本 2.点击下载之后,会得到一个压缩文 ...

  9. (新手向)在Linux中使用VScode编写 "Hello,world"程序,并编写测试-Ubuntu20.4

    本文意在帮助 Go 语言初学者在 Linux环境下编写自己的第一个Golang程序 难点主要在 VScode 中 Go 插件的下载 与 go.mod 以及编译运行和 第一个Go测试程序的使用 前提准备 ...

  10. Windows和Linux时间相差8个小时

    安装linux系统比如deepin.ubuntu之后和Windows两个系统时间相差八个小时的解决方案: 在linux系统下依次输入下方命令: sudo apt install ntpdate sud ...