魔王语言问题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;
}
总结
这里对文章进行总结,把魔王语言进行两种解释方式,并采用不同的结构,代码很烂,可供参考,希望大佬指点小弟,在评论区指点迷津。
魔王语言问题c语言实现及思路求解的更多相关文章
- 【C语言】C语言简介
目录: 1. [什么是C语言?] 2. [C语言历史] 3. [C语言标准] 4. [C语言特点] 1. 什么事C语言? · C语言是一门高级编程语言,用于人与计算机之间的沟通,就如同人与人之间沟通时 ...
- Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?
[编者按]本文作者@徐珂铭,一位看好Html5的移动互联网的从业人士.喜爱玩技术,会点JAVA.HTML及CSS,有自己的想法及姑且能表达想法的文字,因此有了自己的文章. 基于HTML5的Web Ap ...
- 初识GO语言——安装Go语言
本文包括:1)安装Go语言.2)运行第一个Go语言.3)增加vim中对Go语言的高亮支持. 1.安装Go语言 本文采用源码安装Go语言,Go语言的源代码在百度网盘 http://pan.baidu.c ...
- 【C语言】01-C语言概述
说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略 为什么iOS开发要先学C语 ...
- Java语言与C++语言的差异总结
Java的设计者曾说过,设计这门语言的灵感主要来自于C++. 世上先有C++,然后才有Java,整个Java语言的发展历史就是一部对C++的填坑史.所以在Java语言学习过程中,将其与C++语言对比是 ...
- 为什么和其他语言相比C语言是快速的语言
初入门的我们经常听见别人说"真正的程序员用C语言编程,C是最快的语言因为它是最靠近及其底层的语言."那么和其他语言相比C语言到底有什么特别的呢? C语言没有什么特别,这就是它快速的 ...
- Swift语言指南(七)--语言基础之布尔值和类型别名
原文:Swift语言指南(七)--语言基础之布尔值和类型别名 布尔值 Swift有一个基本布尔类型,叫做布尔(bool),布尔值又称逻辑值(logical),因为它只能为真(true)或假(false ...
- Swift语言指南(二)--语言基础之注释和分号
原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...
- Swift语言指南(三)--语言基础之整数和浮点数
原文:Swift语言指南(三)--语言基础之整数和浮点数 整数 整数指没有小数的整数,如42,-23.整数可以是有符号的(正数,零,负数),也可以是无符号的(正数,零). Swift提供了8,16,3 ...
- Swift语言指南(一)--语言基础之常量和变量
原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...
随机推荐
- CVE-2016-2183(SSL/TLS)漏洞的办法
运行gpedit.msc,打开"本地组策略编辑器" 启用"SSL密码套件顺序" TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_ ...
- 07-Spring的事务处理
Spring中提供了七种事务的传播行为: PROPAGATION_REQUIRED:默认值,最常用,统一事务,出现异常,全部回滚 其余参考Spring事务处理word文档. 0.原转账业务(不含事务处 ...
- 关于windows cmd 控制台输出中文
由于中文在window 输出总是优乱码可能性 ,先建cmd.reg 负责下面内容 ,双击运行即可. Windows Registry Editor Version 5.00 [HKEY_CURR ...
- linux 查看进程的启动开始时间
先使用命令查看需要查看的进程 ps -ef | grep java root 29861 13755 2 09:42 pts/0 00:10:48 java -jar XXXX.jar ps axo ...
- Android笔记--内容提供者+Server端+Client端
什么是内容提供者ContentProvider 为App存取内部数据提供的统一的外部接口,让不同的应用之间得以实现数据共享 Client App端 用户输入数据的一端,或者说是用户读取到存储的数据的一 ...
- Android--观察APP运行日志以及APP的工程目录结构解释
运行日志 Log:d--便于跟踪调试 APP开发基础 APP的运行环境 第一种情况,就是在Android studio软件客户端上面使用模拟器运行APP 第二种情况,就是使用真实的手机运行APP程序 ...
- Go语言:利用 TDD 测试驱动开发帮助理解数组与动态数组(切片)的区别
Array VS Slice 数组允许你以特定的顺序在变量中存储相同类型的多个元素. 对于数组来说,最常见的就是迭代数组中的元素. 我们创建一个 Sum 函数,它使用 for 来循环获取数组中的元素并 ...
- Hive 与 HBase 之间的区别和联系
首先要知道 Hive 和 HBase 两者的区别,我们必须要知道两者的作用和在大数据中扮演的角色 概念 Hive 1.Hive 是 hadoop 数据仓库管理工具,严格来说,不是数据库,本身是不存储数 ...
- conda环境下使用nvcc -V报错nvcc: command not found的一种解决方法
前言 缘起 实验室的学弟问我为什么他使用nvcc命令报错,起先我以为他用的是老师给的root账户,按照参考文献1便可以解决问题. 但由于并非root用户,/usr/local下没有cuda,于是便 ...
- 跨域解决方案CORS
这里说的 js 跨域是指通过 js 在不同的域之间进行数据传输或通信,例如通过 ajax 向一个不同的域请求数据,或者通过 js 获取页面中不同域中(iframe)的数据.只要协议.域名.端口有任何一 ...