【数据结构与算法】魔王语言解释(C/C++)

news2024/11/27 0:31:56

实践要求

1. 问题描述

有一个魔王总是使用自己的一种非常精炼而抽象的语言讲话,没有人能听懂。但他的语言是可以逐步解释成人能懂的语言的,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
形式一
α → β 1 β 2 . . . β m \alpha \to \beta _{1} \beta_{2}...\beta_{m} αβ1β2...βm
形式二
( θ δ 1 δ 2 . . . δ n ) → θ δ n θ δ n − 1 . . . . θ δ 1 θ (\theta \delta _{1}\delta_{2}...\delta _{n}) \to \theta\delta _{n}\theta\delta _{n-1}....\theta \delta _{1}\theta (θδ1δ2...δn)θδnθδn1....θδ1θ


2. 基本要求

用下述两条具体规则和上述规则形式(2)实现。设大写字母表示魔王语言解释的词汇,小写字母表示人的语言的词汇;希腊字母表示可以用大写或小写字母代换的变量。魔王语言可含人的词汇。
规则一
B → t A d A B \to tAdA BtAdA
规则二
A → s a e A \to sae Asae


3. 测试数据

3.1 input

B(einxgz)B

3.2 output

tsaedsaeezegexeneietsaedsae


4. 实现提示

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


实践报告

1. 题目分析

说明程序设计的任务,强调的是程序要做什么,此外列出各成员分工

程序设计任务:
设计一个解释魔王语言的程序将含有大写字母、小写字母、圆括号的字符串全部转化为人类语言(全部都为小写字母)。


2. 数据结构设计

说明程序用到的数据结构的定义,主程序的流程及各模块之间的层次关系

栈(用链表实现的,栈顶指针指向最上面的一个元素)

主程序流程图

请添加图片描述

各模块的层级关系

注:在此只列出有调用其他函数的函数

Main函数

在这里插入图片描述

InputAndCheck函数

在这里插入图片描述


3. 程序设计

实现概要设计中的数据类型,对主程序、模块及主要操作写出伪代码,画出函数的调用关系

数据类型

在这里插入图片描述

主程序操作伪代码

在这里插入图片描述

模块伪代码

操作伪代码

InputAndCheck

在这里插入图片描述

操作伪代码

字符串逆置

在这里插入图片描述

将一句话倒着插入栈中

在这里插入图片描述

将一句话正着插入栈中

在这里插入图片描述


4. 调试分析

遇到的问题

  1. 在调用inputAndCheck函数时若输入大写字母的解释仍有大写字母将进行递归,递归传入的参数中有栈,需要注意的是不能传入一开始的栈,而是需要新开一个栈并传入也就是代码中的Stack newSta。如下:用户输入B(exingz)B -> 用户需要输入B的解释 -> 输入tAdA -> 需要用户输入A的解释 -> 输入sae。如果递归时候不传入一个新的栈,那么对A的解释将会变成tsae。
  2. 在调用inputAndCheck函数的最后会将对该大写字母的解释存入test数组中,若不在最后加上 \0 则输出最终字符串时会产生输入多余的乱码的情况如(会输出tsaed潪saeezegexeneiets笅aedsae)虽然字符没错,但是会输出多余的乱码。

程序复杂度分析

T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n)


5. 测试结果

列出测试结果,包括输入和输出

测试结果

input 1st

B(einxgz)B

output 1st

请输入B字符的解释

input 2st

tAdA

output 2st

请输入A字符的解释

input 3st

sae

output 3st

tsaedsaeezegexeneietsaedsae

在这里插入图片描述


6. 用户使用说明

给出主界面及主要功能界面

7. 附录

源程序文件清单:
Mowangyuyan.cpp //主程序

8. 全部代码

mowangyuyan.cpp

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define MAX_SIZE 100

// 定义一个结构体,用来表示栈中的节点
struct node
{
    char val;
    node *next;
};

// 定义一个栈类
class Stack
{
private:
    // 栈顶指针
    node *top_ptr = nullptr;

public:
    // 判断栈是否为空
    bool isEmpty()
    {
        return top_ptr == nullptr ? true : false;
    }
    // 获取栈顶元素
    char top()
    {
        return top_ptr->val;
    }
    // 入栈操作
    void push(char c)
    {
        node *new_node = new node{c, top_ptr};
        top_ptr = new_node;
    }
    // 弹出栈顶元素
    bool pop()
    {
        if (isEmpty())
            return false;
        node *to_be_deleted = top_ptr;
        top_ptr = top_ptr->next;
        delete to_be_deleted;
        return true;
    }
    // 置空栈
    void clear()
    {
        while (top_ptr)
        {
            node *tmp = top_ptr;
            top_ptr = top_ptr->next;
            delete tmp;
        }
    }
    // 析构函数
    ~Stack()
    {
        clear();
    }
};
// 将字符串逆置
void reverseStr(char str[], int length)
{
    int start = 0;
    int end = length - 1;
    while (start < end)
    {
        swap(str[start], str[end]);
        start++;
        end--;
    }
}
// 将一条语句倒着放入栈中
void invert(Stack &sta, char setence[])
{
    // 一句话的长度
    int len = strlen(setence) / sizeof(char);
    for (int i = len - 1; i >= 0; --i)
    {
        sta.push(setence[i]);
    }
}
// 将一句话正着放入栈中
void reverseInvert(Stack &sta, char setence[])
{
    // 一句话的长度
    int len = strlen(setence) / sizeof(char);
    for (int i = 0; i <= len - 1; ++i)
    {
        sta.push(setence[i]);
    }
}

// 检查输入的字符是否全为小写字符 ch为输入的字符,index为其字符的ASCII码 - A的ASCII的值, text为预处理后的各大写字母的表示
void inputAndCheck(Stack &sta, char ch, int index, char test[26][MAX_SIZE])
{
    char supperVoca[MAX_SIZE]; // 存放用户输入该大写字母的表示
    int vocaVal;               // 输入解释字符的ASCII码
    char final[MAX_SIZE];      // 最终的解释
    printf("请输入%c字符的解释", ch);
    scanf("%s", supperVoca);
    for (int i = 0; i < strlen(supperVoca) / sizeof(char); i++) // 挨个检查输入的解释是否为小写字母
    {
        vocaVal = supperVoca[i];
        if (isupper(vocaVal) && test[vocaVal - 'A'][0] == '\0') // 如果输入的是大写字母且该大写字母并无解释
        {
            if (vocaVal - 'A' != index) // 检查是否为已经处理过的字母,避免死循环
            {
                Stack newSta;                                              // 创建一个空栈(易漏)
                inputAndCheck(newSta, supperVoca[i], vocaVal - 'A', test); // 递归
            }
        }
        if (isupper(vocaVal) && test[vocaVal - 'A'][0] != '\0') // 如果输入的是大写字母且该大写字母有相应的解释
        {
            reverseInvert(sta, test[vocaVal - 'A']); // 将该大写字母的解释正着插入栈中
        }
        else
            sta.push(supperVoca[i]); // 如果是小写字母则直接插入栈中
    }
    int i = 0; // 共有多少个字符
    while (!sta.isEmpty())
    {
        char tmp = sta.top();
        sta.pop();
        final[i] = tmp;
        i++;
    }
    reverseStr(final, i);
    int j = 0;
    while (j < i)
    {
        test[index][j] = final[j];
        j++;
    }
    test[index][j] = '\0'; // 在每个大写字母的最终解释后加个\0
}
int main()
{
    // test
    char test[26][MAX_SIZE];        // 存放26个大写英文字母的所对应的小写字母解释
    char language[MAX_SIZE];        // 一开始的魔王语言
    char inBrackets[MAX_SIZE];      // 括号内的字符
    char translatedInBra[MAX_SIZE]; // 转化括号内的字符
    char translation[MAX_SIZE];     // 最终解释的字符
    bool flag = false;              // 是否在括号内的标志
    Stack translatedLanguage;       // 经过大小写转换后的栈
    Stack finalInterp;              // 每个大写字母最终解释的栈
    for (int i = 0; i < 26; ++i)    // 初始化
    {
        test[i][0] = '\0';
    }
    scanf("%s", language);                            // 输入魔王语言
    int langLength = strlen(language) / sizeof(char); // 求出输入字符的长度
    for (int i = 0; i < langLength; i++)
    {
        int Char = language[i]; // 字符的ASCII码值
        if (isupper(Char))
        {
            if (test[Char - 'A'][0] == '\0')
            {
                // 输入并检查是否含有大写字幕
                inputAndCheck(finalInterp, language[i], Char - 'A', test);
            }
        }
    }
    reverseInvert(translatedLanguage, language);
    int i = 0;
    int j = 0;
    while (!translatedLanguage.isEmpty())
    {
        char tmp = translatedLanguage.top();
        translatedLanguage.pop();
        if (isupper(tmp))
        {
            reverseInvert(translatedLanguage, test[tmp - 'A']);
        }
        else if (tmp == ')')
        {
            flag = true;
        }
        else if (tmp == '(')
        {
            flag = false;
            int inBracketsLength = strlen(inBrackets) / sizeof(char);
            int counter1 = 0;
            int counter2 = 0;
            while (counter1 != inBracketsLength)
            {
                translatedInBra[counter2] = inBrackets[inBracketsLength - 1];
                if (counter1 != (inBracketsLength - 1))
                {
                    translatedInBra[counter2 + 1] = inBrackets[counter1];
                }
                counter1 = counter1 + 1;
                counter2 = counter2 + 2;
            }
            reverseInvert(translatedLanguage, translatedInBra);
        }
        else
        {
            if (flag)
            {
                inBrackets[i] = tmp;
                i = i + 1;
            }
            if (!flag)
            {
                translation[j] = tmp;
                j++;
            }
        }
    }
    reverseStr(translation, j);
    for (int k = 0; k < j; k++)
    {
        printf("%c", translation[k]);
    }
    return 0;
}

结束语

  因为是算法小菜,所以提供的方法和思路可能不是很好,请多多包涵~如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无线耳机推荐的品牌有哪些?八款无线蓝牙耳机推荐

无线蓝牙耳机无疑是当前最受欢迎的数码产品之一&#xff0c;平听闲暇时刻听听歌或者是运动健身&#xff0c;常常能看到蓝牙耳机的身影&#xff0c;作为一个热衷于听歌的精致boy&#xff0c;佩戴过的蓝牙耳机数不胜数&#xff0c;现在&#xff0c;除了手机品牌会开发无线蓝牙耳机…

西电_矩阵论_学习笔记

文章目录 【 第一章 线性空间 】【 第二章 范数 】【 第三章 矩阵函数 】【 第四章 矩阵分解 】【 第五章 矩阵特征值估计 】【 第六章 广义逆 】【 考试重点内容总结 】 这是博主2023春季西电所学矩阵论的思维导图&#xff08;软件是幕布&#xff09;&#xff0c;供大家参考&a…

ROS:工作空间覆盖

目录 一、概念二、示例2.1操作2.2原因 三、存在的问题 一、概念 所谓工作空间覆盖&#xff0c;是指不同工作空间中&#xff0c;存在重名的功能包的情形。 ROS 开发中&#xff0c;会自定义工作空间且自定义工作空间可以同时存在多个&#xff0c;可能会出现一种情况: 虽然特定工…

【数学建模】 灰色预测模型

数学建模——预测模型简介 https://www.cnblogs.com/somedayLi/p/9542835.html 灰色预测模型 https://blog.csdn.net/qq_39798423/article/details/89283000?ops_request_misc&request_id&biz_id102&utm_term%E7%81%B0%E8%89%B2%E9%A2%84%E6%B5%8B%E6%A8%…

开放式耳机哪个好?2023开放式耳机排行榜推荐

​耳机成为了当代青年必不可少的一款数码单品&#xff0c;无论在什么时间、哪个地点总能看到很多人戴着耳机。耳机也分有很多类型&#xff0c;就比如市面上大火的开放式耳机&#xff0c;很多人还不清楚开放式耳机如何挑选的&#xff0c;下面我来推荐几款很不错的开放式耳机&…

【一】部署Zabbix监控详解

Zabbix监控 1.Zabbix监控概述1.1 zabbix是什么1.2 zabbix监控原理1.3 Zabbix 6.0新特性1.4 Zabbix 6.0功能组件1.5 Zabbix与prometheus区别对比 2. 部署Zabbix6.02.1 安装NginxPHP2.2 部署Mariadb数据库2.3 安装zabbix Server服务端2.4 部署Web前端&#xff0c;进行访问2.5 部署…

软件测试中的二八定律到底是什么?

目录 前言&#xff1a; 一、80%的软件缺陷&#xff0c;集聚在软件20%的模块中 二、软件测试工作尽早介入 三、反映在软件测试的自动化方面 四、80%的缺陷&#xff0c;集中在某20%的开发工程师代码中&#xff1b; 一、缺陷是解决不完的 二、是不可能发现100%缺陷的 三、…

Web APls-day04

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 日期对象 日期对象&#xff1a;用来表示时间的对象 作用&#xff1a;可以得到当前系统时间 实例化 在代码中发现…

【设计模式】第九章:外观模式(门面模式)详解及应用案例

系列文章 【设计模式】七大设计原则 【设计模式】第一章&#xff1a;单例模式 【设计模式】第二章&#xff1a;工厂模式 【设计模式】第三章&#xff1a;建造者模式 【设计模式】第四章&#xff1a;原型模式 【设计模式】第五章&#xff1a;适配器模式 【设计模式】第六章&…

17 MFC进程通信

文章目录 剪切板管道匿名管道父进程写入数据子进程读出数据 命名管道 邮槽邮槽服务器邮槽客户端 剪切板 设置界面 发送 //设置剪切板数据 void CClipboardDlg::OnBnClickedBtnSend() {UpdateData(TRUE);if (m_strSend.IsEmpty()){MessageBox(L"请输入需要设置的文本&quo…

spring的事务处理@Trasactional Aop处理第二弹

书接上回 &#xff0c;我们针对spring中的ApplicationContext类的扩展功能-事件发布和监听处理源码进行了解析&#xff0c;知道了消息是如何存放和传递给监听器处理的。这章我们看下另外一个重量级的组件Transactional事务处理是如何实现的。 我们可能都了解过声明式的事务处理…

十三、弹性容器flex的样式1

目录&#xff1a; 1.基础准备 2.属性解析 一、基础准备 设置ul为弹性元素&#xff0c;默认是flex-direction:row&#xff0c;所以不用设置&#xff0c;然后在让里面的方块不进行伸缩。 我们看到小方块超出了边框 <style>*{margin: 0;padding: 0;list-style: none;}ul{wi…

vant List组件实现上拉加载中 首次进行load事件执行两次的问题

需求&#xff1a; 进行tab切换时&#xff0c;其中一次tab下有上拉加载的功能 问题&#xff1a; 在第一次切换到带有上拉加载列表功能的tab&#xff0c;执行加载list的load事件执行了两次造成数据的重复加载&#xff0c;另外如果这个list的高度全部在可视范围内&#xff0c;首次…

STM32:Custom HID实现USB双向通信

本文章主要讲了使用STM32的USB Device&#xff0c;实现控制板和电脑通信功能。从而实现&#xff0c;上位机对控制板进行调试。 USB Device可以有多种类型&#xff0c;实现双向通信的话&#xff0c;推荐使用Custom HID类型。 首先使用STM32CubeMx实现功能引脚配置并且生成对应…

Win11的两个实用技巧系列之关闭输入法悬浮窗方法、记住窗口位置禁用或启用的方法

Win11输入法悬浮窗怎么去掉? win11关闭输入法悬浮窗方法 Win11输入法悬浮窗怎么去掉&#xff1f;win11安装的输入法有悬浮窗&#xff0c;想要去掉悬浮窗&#xff0c;该怎么操作呢&#xff1f;下面我们就来看看win11关闭输入法悬浮窗方法 很多用户将自己win11更新到了最新版本…

面试题 16.02. 单词频率

设计一个方法&#xff0c;找出任意指定单词在一本书中的出现频率。 你的实现应该支持如下操作&#xff1a; WordsFrequency(book)构造函数&#xff0c;参数为字符串数组构成的一本书get(word)查询指定单词在书中出现的频率 示例&#xff1a; WordsFrequency wordsFrequency …

git cherry-pick 用法

1. 切换到目标分支 说明&#xff1a;本人基于 master 新建分支 master-fxd&#xff0c;那么目标分支为 master-fxd git checkout <target-branch>2. 从其他分支选择并应用单个提交 说明&#xff0c;其他分支例如 dev 提交的代码&#xff0c;使用 jihulab.com 比较 master…

针对WordPress程序无法升级最新版本的问题分析

WordPress程序是当前使用率最高的CMS系统之一&#xff0c;因开发功能完善&#xff0c;WordPress模板和插件众多而著称&#xff0c;茹莱神兽做三个网站&#xff0c;其中有两个网站使用的是WordPress程序搭建&#xff0c;可见它的受欢迎程度。 而WordPress程序本身也相当给力&a…

刷简单的题也很吃力怎么办?(经验分享)

目录 一、前言 1.刷简单的题也很吃力怎么办&#xff1f; 2.不重视这种问题会怎么样&#xff1f; 二、找到属于自己的解决方案 三、根据问题进行分解或建立思维导图​​​​​​​ 四、分享刷题网站 一、前言 1.刷简单的题也很吃力怎么办&#xff1f; 有的时候在当时学完…

ZMQ在windows下配合VS2017使用(c++)

ZMQ专题学习之四&#xff1a;libzmq的发布及订阅方式_jyl_sh的博客-CSDN博客 一、背景介绍 高速并发消息通信框架——ZeroMQ详解&#xff08;一&#xff09; - 知乎 (zhihu.com) zmq将socket进行了封装&#xff0c;可以快速在两个进程间进行通信 二、编译libzip https:/…