此版本存在严重的乱码问题和决策策略问题,现已重构2.0版本:【C++】狗屁不通文章生成器2.0
由用户输入启动词,根据语料库中统计的词语前后缀关系,自动生成一片新的文章。
比如:春天来了,大地妈妈穿上了碧绿的衣裳。嫩绿的小草从地下探出头来,陶醉在美丽的春天里。
前后缀关系:[前缀,后缀]。上面这段话的前后缀关系有:[春天,来/里],[天来,了],[天里,。],[来了,,]等。
说明:
- 启动词:用户输入的一个词,由这个词开始生成文章所有内容。
- 前/后缀:一个词前后连续的n个字符。比如前缀为“春天”,由例句中得到后缀可为“来”或“里”,即表示一种语言的前后关系。
- 准备语料库:准备相关文章,存为文件。利用程序读取文章内容,获取文章语句中词语的前后关系,即语料库。语料库的丰富程度由文章的数量决定,语料库又决定程序运行的时间和生成的文章质量。
- 构建前后缀关系:根据语料库,依据设定的前后缀长度,构建字词的前后缀关系。
- 生成文章:用户输入启动词,根据启动词为前缀生成后缀得到文段,再根据文段生成新的前缀,以新前缀生成新后缀以此类推,得到一片文章。
- 应尽量避免循环:有时语料库中可能出现类似“为所欲为”的接龙结构,造成死循环,同时生成的内容也没有了意义。
- 输入输出形式:
- 读文件:从多篇文章中读取文件内容为字符串,以前/后缀的长度遍历获取前/后缀,并建立前后缀关系。
- 写文件:为观察程序执行情况,将前/后缀字符对和生成的文章写入文件。
当需要在两种数据间建立一种关系时,可以使用结构化数据进行存储,比如建立前后缀关系可以采用字典类结构进行存储,C++也有相应的头文件。
除此之外,还可以将其抽象为一种类,可以定制类的行为和结构。这里选择自建一个类进行存储。
类设计:
- 一个类记录一个前缀和它的所有后缀,
- 记录后缀的出现次数
- 记录后缀的个数
在C++的头文件中,可以使用string类型代替char类型的字符串,而且对于字符串的操作也更方便。比如
以前一直觉得C语言和C++处理字符串很麻烦,现在倒觉得还是很方便的。
C语言和C++中,基础的数组长度相对固定,但也不是不能改变,只是相对麻烦一些。在这个程序中,一个wordpair只存储一个前缀和它的后缀们,所以需要创建一个wordpair类型的列表来存储全部的前后缀。
我用的方法是来回地复制
由于数组加长在程序中多次调用,且需要增长的数组各不相同,所以在这里我定义了一个函数模板,以尽可能少的代码完成相同的任务。
首先是类成员,应该有:
除此之外,还可以重载输出运算符<<,便于调试时在函数中输出wordpair值:
程序运行时,需要读取文件为字符串,当文件较多时把这个功能抽象出来,调用很方便。
主要是写入生成的字符对,方便调试
读取到文件后,将字符串从下标0开始,读取前缀+后缀的长度,然后从1开始读取前缀+后缀的长度。循环的次数应该是字符串总长度 - (前缀长度+后缀长度 -1),以保证下标不会溢出。
在此基础上,对每次读文件都进行一次,就能获取全部文件的字符对。
得到语料库之后,需要根据语料库拼接出文章。我这里采用的方法有点问题,当完全防止出现循环文本的时候,文章过短,当放开一点对循环文本的时候,循环文本总是出现,算法上想不通。希望有大佬提供一点思路。