【C++】狗屁不通文章生成器2.0

【C++】狗屁不通文章生成器2.0

  • 1 前言
  • 2 改进
    • 2.1 字词的前后关系
    • 2.2 文章生成系统
  • 3 实现(部分)
    • 3.1 class wordpair
      • 3.1.1 转化为 json
      • 3.1.2 添加后缀词
      • 3.1.3 选择后缀词
    • 3.2 class createArticle
      • 3.2.1文本分割
      • 3.2.2生成文章
  • 4演示
    • 4.1 wordpair(3x2), 启动词(春天)
    • 4.2 wordpair(2x1),启动词(春天)
    • 4.3 wordpair(2x2),启动词(春天)
  • 5总结

1 前言

继上次【C++】狗屁不通文章生成器之后,很久不想看一眼这个代码,因为当时写这个代码深受中文字符的处理烦恼。而且现在回看,程序的模块化、可读性使我大受震惊,是在想不到当时的我为什么要这样做。于是昨天无心工作,想到了把这堆乐色改进一下,至少做到能看的水平。遂记之。

2 改进

2.1 字词的前后关系

为了表示字词的前后关系,即将句子划分为前缀词+后缀词的关系,依然需要定义一个class wordpair,这里去除一些数据上的冗余,强化了类的封闭性。

class wordpair
{
private:string preword;            // 前缀map<string, int> sufwords; // 后缀,次数int count;                 // 总次数public:wordpair(string pre);wordpair(string pre, string suf);wordpair(string pre, map<string, int> suf);~wordpair();string getPreword() const;map<string, int> getSufwords() const;void setPreword(string pre);void setSufwords(map<string, int> suf);string toJson() const;void addSufword(string suf);string chooseSufword() const;
};

采用map记录后缀的出现次数,数据的结构性更强,也易于查找。记录所有后缀出现的总次数是为了在生成文章时选择后缀提供方便(具体作用看3.1.3)

2.2 文章生成系统

将太多的操作塞进main()函数的做法不够美观,且容易忘记各个部分的功能。于是这里将文章生成的功能抽象出来,作为一个类。主要的工作是记录所有的字词对、记录生成的、文件流操作、文章生成等逻辑

class createArticle
{
private:vector<wordpair> wordpairlist;string article;public:createArticle();~createArticle();void importWords(string filename, int len_pre = 1, int len_suf = 1);void exportWords(string filename);void addWordPair(string pre, string suf);void generateArticle(string startword, int lenout = 10000);void printArticle(string filename);
};

3 实现(部分)

由于大多函数都很简单,这里只贴出部分比较重要的函数。

3.1 class wordpair

除去构造函数、类成员输出输入等函数,我们直接进入主题。

3.1.1 转化为 json

这个函数主要是为了输出格式化的词对,而文本文件中json格式的结构性且简单。
ps: 其实这个函数不太重要,主要目的是检查。不过也可以为直接读词对做准备(虽然这里没有从文件导入词对的功能)

string wordpair::toJson() const
{string str = "\"";str += this->preword + "\" : {";for (auto &it : this->sufwords){str += "\"" + it.first + "\"" + ":" + to_string(it.second) + ",";}str += "}";return str;
}

效果演示:
在这里插入图片描述

3.1.2 添加后缀词

添加后缀的函数,逻辑是:

  • if 这个后缀已经有记录 then count++
  • else 添加新的后缀到map
void wordpair::addSufword(string suf)
{for (auto &it : this->sufwords){if (it.first == suf){it.second++;return;}}this->sufwords[suf] = 1; // if the word is not in the map, add it with a count of 1
}

3.1.3 选择后缀词

这个函数的主要功能是从众多后缀词中选取一个(语料库大的话就会多啦),选择的策略是随机数的方案,类似于转盘抽奖。实现方法如下:

string wordpair::chooseSufword() const
{if (this->sufwords.size() == 1)//如果只有一个后缀词就直接输出,减少算力负担{return this->sufwords.begin()->first;}else{// 随机选择一个后缀词random_device rd;ranlux48 engine(rd());uniform_int_distribution<> dist(0, this->count);//在类中定义了count,这里就省掉了遍历int random_number = dist(engine);//产生一个随机数std::string result;for (auto &it : this->sufwords)//抽奖{if (random_number < it.second){result = it.first;}elserandom_number -= it.second;}return result;}
}

3.2 class createArticle

3.2.1文本分割

vector<string> charlist = splitchar(filestr);//先将从文件读到的字符串分割string preword = "", sufword = "";for (int i = 0; i < charlist.size() - len_suf - len_pre; i++)//每次向后移动一个字符,进行切割{preword = "", sufword = "";for (int j = i; j < i + len_pre + len_suf; j++){if (j - i < len_pre){preword += charlist[j];//从第i个字符开始,到第i+len_pre个字符连接起来作为前缀}else{sufword += charlist[j];//从第i+len_pre个到字符开始,到第i+len_pre+len_suf个字符连接作后缀}}this->addWordPair(preword, sufword);//添加进wordpairlist}

3.2.2生成文章

/*
startword——启动词
lenout——长度限制(避免无限循环)
*/
void createArticle::generateArticle(string startword, int lenout)
{this->article += startword;bool stop; // 加一个停止标志,当无法匹配到前缀时停止int prewordlen = this->wordpairlist.front().getPreword().length();int sufwordlen = this->wordpairlist.front().getSufwords().begin()->first.length();string lastword;for (int i = 0; i < lenout; ++i){stop = true;if (this->article.length() >= prewordlen) // 如果文章长度大于词对中前缀词的长度,则直接拼接{lastword = this->article.substr(this->article.length() - prewordlen, prewordlen);//article最后的len_pre个字符,作为前缀for (auto &it : this->wordpairlist){if (it.getPreword() == lastword)//通过lastword匹配词对{this->article += it.chooseSufword();stop = false;break;}}if (stop)//遍历了一边词对的list没有匹配的词对时,退出循环break;}else//启动词长度小于词对前缀的情况,例如词对分割为3+2时,启动词长度为2,小于前缀长度3,无法正常拼接,于是走此处{lastword = this->article;for (auto &it : this->wordpairlist)//同上遍历{int position = it.getPreword().find(lastword);if (position != string::npos){this->article += (it.getPreword() + it.chooseSufword()).substr(position+lastword.length(), sufwordlen);//先将前后缀连接,再从匹配到的位置开始截取stop = false;break;}}if (stop)break;}}
}

4演示

4.1 wordpair(3x2), 启动词(春天)

在这里插入图片描述

4.2 wordpair(2x1),启动词(春天)

在这里插入图片描述

4.3 wordpair(2x2),启动词(春天)

在这里插入图片描述可见,加了长度限制的重要性。

5总结

目前,这个版本的处理方法不会出现中文乱码,即使是中英文混合字符串也能正确读取和分割。而且拼接时采用的随机数策略,在语料库足够大的情况下可以有较好的灵活性。但是任然无法产出具备可读性的文章。

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

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

相关文章

Vue按需加载:提升应用性能的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【进程概念】进程控制块task_struct-PCB

文章目录 进程的概念如何描述进程?**为什么要描述一个进程**&#xff1f;进程描述--PCBtask_struct 组织进程查看进程通过系统调用获取进程标示符getpid()以及getppid() 进程的概念 在【百度百科】中&#xff0c;关于进程---- 狭义定义&#xff1a;进程是 正在运行 的程序的实…

若依ruoyi-vue中的文件上传和下载

文章目录 文件上传后端实现前端实现 文件下载后端实现前端实现 在若依&#xff08;Ruoyi&#xff09;框架中&#xff0c;结合 Vue 前端框架&#xff0c;文件的上传和下载通常使用以下方法实现&#xff1a; 文件上传 若依现成的功能里面没有文件上传&#xff0c;但是集成了文件…

基于php健身房管理系统flask-django-python

根据现实需要&#xff0c;此系统我们设计出一下功能&#xff0c;主要有以下功能模板。 &#xff08;1&#xff09;前台功能&#xff1a;首页、运动器材、教练信息、营业信息、公告栏、在线留言、后台管理、个人中心。 &#xff08;2&#xff09;会员功能&#xff1a;首页、个人…

Springboot笔记(web开启)-08

有一些日志什么的后续我会补充 1.使用springboot: 创建SpringBoot应用&#xff0c;选中我们需要的模块&#xff1b;SpringBoot已经默认将这些场景配置好了&#xff0c;只需要在配置文件中指定少量配置就可以运行起来自己编写业务代码&#xff1b; 2.SpringBoot对静态资源的映…

【记录39】html element-ui 加载

环境 html使用element-ui组件、用vue框架搭建 方法一&#xff1a; 方法二&#xff08;推荐&#xff09; 将相关资源下载下来&#xff0c;在对应的html文件中相对路径引入。注意&#xff1a;css加载放在js之前

Controller中接收数组参数

1、场景 需要根据用户id集合批量删除用户数据&#xff0c;前端使用post请求&#xff0c;controller中参数接收数组参数并根据用户id删除用户基本信息 2、分析处理&#xff1a; 2.1、前端请求类型contentType:application/json 请求体中为json字符串&#xff0c;后端新建一个U…

javaSwing愤怒的小鸟

一、简介 游戏名称是“愤怒的小鸟”&#xff0c;英文称为“AngryBird”。 “愤怒的小鸟”是著名游戏公司Rovio偶然间开发出来的益智游戏&#xff0c;从2009年12月上市到iOS。&#xff0c;讲述了鸟类和猪因为猪偷鸟蛋反生的一系列故事。游戏的类型版本是横向版本的水平视角&…

怎么在Linux系统下Docker部署Excalidraw白板工具并实现无公网IP远程访问?

文章目录 1. 安装Docker2. 使用Docker拉取Excalidraw镜像3. 创建并启动Excalidraw容器4. 本地连接测试5. 公网远程访问本地Excalidraw5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 本文主要介绍如何在Ubuntu系统使用Docker部署开源白板工具Excal…

C++临时变量

本博客将讲述我学习过程中对临时变量的疑惑与理解 为什么写这篇文章&#xff1f; 我在学习C过程中&#xff0c;发现C在发生隐式转换时或者出现未命名的变量如字符串再或者在求值的时候&#xff0c;会出现C临时变量&#xff08;系统自动生成&#xff09;&#xff0c;而这个临时…

PgSQL根据身份证号查询年龄

1、需求&#xff1a;数据库中有身份证号码&#xff0c;也有年龄字段&#xff0c;但是年龄字段不会自动更新&#xff0c;现在需要返回最新的年龄数据。 2、思路&#xff1a;获取当前年份&#xff0c;截取省份证中的年龄部分数据&#xff0c;再进行相减即可&#xff1b; 3、具体…

MySQL高级学习笔记

1、MySQL架构组成 1.1 高级MySQL介绍 什么是DBA&#xff1f; 数据库管理员&#xff0c;英文是Database Administrator&#xff0c;简称DBA&#xff1b; 百度百科介绍 数据库管理员&#xff08;简称DBA&#xff09;&#xff0c;是从事管理和维护数据库管理系统&#xff08;D…

搜索测试题题解(3月21号总结)

目录 1.Shufflem Up 2.Pots 3.Open the Lock 1.Shufflem Up 样例 InputcopyOutputcopy 2 4 AHAH HAHA HHAAAAHH 3 CDE CDE EEDDCC 1 2 2 -1 题意&#xff1a;本题要求将s1和s2合并&#xff0c;再将合并的s分为s1和s2&#xff0c;知道s为我们需要得到的期望s&#xff0c;输…

巨细!Python爬虫详解

爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在 FOAF 社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff1b;它是一种按照一定的规则&#xff0c;自动地抓取网络信息的程序或者脚本。 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那…

北航最新!基于条纹投影的半透明物体3D重建方法

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

雷池 WAF 社区版:下一代 Web 应用防火墙的革新

黑客的挑战 智能语义分析算法&#xff1a; 黑客们常利用复杂技术进行攻击&#xff0c;但雷池社区版的智能语义分析算法能深入解析攻击本质&#xff0c;即使是最复杂的攻击手法也难以逃脱。 0day攻击防御&#xff1a; 传统防火墙难以防御未知攻击&#xff0c;但雷池社区版能有效…

01_Kubernetes基础

Kubernetes为什么叫K8S&#xff1a;因为K和S之间有8个字母 为什么需要K8S 对于云计算来说有自己的交互标准 Paas的下一代标准就是容器化&#xff0c;容器的集群化有没有很好的方案&#xff1f;有需求就会有产品&#xff0c;这个产品就叫做资源管理器。 首先是Apache的MESOS&…

LeetCode每日一题【206. 反转链表】

思路&#xff1a;双指针&#xff0c;一前一后&#xff0c;逐个把指向后面的指针指向前面。 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), ne…

刷题训练之滑动窗口

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握滑动窗口算法&#xff0c;并且能把下面的…

又一个城市火了,媒介盒子盘点城市爆火原因

近日&#xff0c;“甘肃天水麻辣烫”在各大平台频频登上热搜榜&#xff0c;甘肃当地也及时接住了这泼天富贵&#xff0c;开通“麻辣烫专线”、机场高铁免费接、免费送门票等。这些措施似曾相识&#xff0c;因为在天水前&#xff0c;已经有淄博和哈尔滨这两个城市的案例可以供天…