iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >基于C++如何编写一个文章生成器
  • 666
分享到

基于C++如何编写一个文章生成器

2023-07-05 13:07:39 666人浏览 八月长安
摘要

这篇“基于c++如何编写一个文章生成器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于C++如何编写一个文章生成器”文章吧

这篇“基于c++如何编写一个文章生成器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于C++如何编写一个文章生成器”文章吧。

    1.概况

    由用户输入启动词,根据语料库中统计的词语前后缀关系,自动生成一片新的文章。

    比如:春天来了,大地妈妈穿上了碧绿的衣裳。嫩绿的小草从地下探出头来,陶醉在美丽的春天里。

    前后缀关系:[前缀,后缀]。上面这段话的前后缀关系有:[春天,来/里],[天来,了],[天里,。],[来了,,]等。

    说明:

    启动词:用户输入的一个词,由这个词开始生成文章所有内容。

    前/后缀:一个词前后连续的n个字符。比如前缀为“春天”,由例句中得到后缀可为“来”或“里”,即表示一种语言的前后关系。

    2.基本要求

    准备语料库:准备相关文章,存为文件。利用程序读取文章内容,获取文章语句中词语的前后关系,即语料库。语料库的丰富程度由文章的数量决定,语料库又决定程序运行的时间和生成的文章质量。

    构建前后缀关系:根据语料库,依据设定的前后缀长度,构建字词的前后缀关系。

    生成文章:用户输入启动词,根据启动词为前缀生成后缀得到文段,再根据文段生成新的前缀,以新前缀生成新后缀以此类推,得到一片文章。

    应尽量避免循环:有时语料库中可能出现类似“为所欲为”的接龙结构,造成死循环,同时生成的内容也没有了意义。

    输入输出形式:

    //输入:
        2    //前缀词长度
        2    //后缀词长度
        春天    //启动词
    //输出:
        [一篇文章]

    3.程序分析

    3.1 文件流读写

    读文件:从多篇文章中读取文件内容为字符串,以前/后缀的长度遍历获取前/后缀,并建立前后缀关系。

    写文件:为观察程序执行情况,将前/后缀字符对和生成的文章写入文件。

    3.2 建立前后缀关系

    当需要在两种数据间建立一种关系时,可以使用结构化数据进行存储,比如建立前后缀关系可以采用字典类结构进行存储,C++也有相应的头文件。

    除此之外,还可以将其抽象为一种类,可以定制类的行为和结构。这里选择自建一个类进行存储。

    类设计:

    • 一个类记录一个前缀和它的所有后缀,

    • 记录后缀的出现次数

    • 记录后缀的个数

    class Wordpair{    private:        char **suffix    //后缀字符串数组,一个后缀存为一个字符串        int *freq        //一个后缀出现的次数    public:        char *prefix    //前缀字符串,声明为公共成员,方便外部查找        int length        //记录后缀的个数}

    3.3 字符串切片

    在C++的头文件中,可以使用string类型代替char类型的字符串,而且对于字符串的操作也更方便。比如

    string str1 = "abcd";string str2 = "efghijk";string str3 = str1 + str2;    // = “abcdefghijk”; 字符串拼接string str4 = str3.substr(3,2);    // = "de"; 从下标为3的字符开始,截取长度为2的子字符串

    以前一直觉得C语言和C++处理字符串很麻烦,现在倒觉得还是很方便的。

    3.4 变长数组

    C语言和C++中,基础的数组长度相对固定,但也不是不能改变,只是相对麻烦一些。在这个程序中,一个wordpair只存储一个前缀和它的后缀们,所以需要创建一个wordpair类型的列表来存储全部的前后缀。

    我用的方法是来回地复制

    int main(){    int len;    int list[len];    //假设有一个长度为len的整型数组    int p[len+1];    //开辟一个len+1个整型长度的空间    //    把 list 复制到 p,然后    list = new int[len+1];    //将list长度+1    //把 p 复制过来}

    4.代码实现

    4.1 函数:数组加长

    由于数组加长在程序中多次调用,且需要增长的数组各不相同,所以在这里我定义了一个函数模板,以尽可能少的代码完成相同的任务。

    template<class T>T *append2list(T *list, T t, int len){    T copy[len + 1];            // 用于备份的空间    for(int i=0; i<len; i++){        copy[i] = list[i];}    copy[len] = t;                //在末尾增加元素    len++;    list = new T[len];            //变长    for(int i=0; i<len; i++){    //拷贝回来        list[i] = copy[i];}    return list;}

    4.2 类wordpair定义

    首先是类成员,应该有:

    class Wordpair{    private:        string *suffix;    //后缀列表,一个前缀可能对应多个后缀         int   *freq;    // 整型数组,依此记录后缀的频率    public:        string prefix;    // 前缀         int length;        // 记录长度 , 一个前缀对应size个后缀         Wordpair(string prefix, string suffix){    //构造函数            this->prefix = prefix;            this->suffix = new string[1];            this->suffix[0] = suffix;            this->freq = new int[1];            this->freq[0] = 1;            this->length = 1;        }        Wordpair(){                                //构造函数            this->prefix = "",            this->suffix = new string[1];            this->suffix[0] = "";            this->freq = new int[1];            this->freq[0] = 0;            this->length = 0;        }                int hasRecorded(string word){}                        bool push(string word){}                         string maxFrequency(){}                        string to_String()const{}                Wordpair& operator=(Wordpair &pair){}};

    除此之外,还可以重载输出运算符<<,便于调试时在函数中输出wordpair值:

    ostream& operator<<(ostream& out, const Wordpair& w){    out<<w.to_String();    return out;}

    4.3 函数:读取文件

    程序运行时,需要读取文件为字符串,当文件较多时把这个功能抽象出来,调用很方便。

    // 读文件 string getfile(char *path){  string alticle = "";            //初始化字符串  ifstream fin(path, iOS::in);    //打开文件  if(!fin.is_open()){    cout<<"文件读取错误!"<<endl;    return NULL;  }  string buffer;  while(getline(fin,buffer)){        //读取    alticle.append(buffer);            //新的行添加到alticle尾部  }  fin.close();  return alticle;}

    4.4 函数:写入文件

    主要是写入生成的字符对,方便调试

    // 写文件,记录词组对 void exportData(Wordpair *pairlist, int len, int prelen, int suflen){    char path[32];    sprintf(path,"./word-pairs(%dx%d).txt",prelen,suflen);    ofstream fout(path, ios::out);    for(int i=0; i<len; i++){        fout<<pairlist[i];        //在这里就体现了重载<<运算符的好处    }    fout.close();    cout<<"词组对已经写入文件< "<<path<<" >"<<endl; }

    4.5 核心函数:字符串分割

    读取到文件后,将字符串从下标0开始,读取前缀+后缀的长度,然后从1开始读取前缀+后缀的长度。循环的次数应该是字符串总长度 - (前缀长度+后缀长度 -1),以保证下标不会溢出。

    Wordpair *alticle2Wordpair(Wordpair *pairlist, int &length,string alticle, int prefix_len, int suffix_len){    for(int i=0; i<alticle.length()/2-prefix_len-suffix_len+1; i++){        bool hasrecord = false;        string prefix=alticle.substr(i*2,prefix_len*2);                // i为什么要×2?因为在devcpp中发现一个中文字符相当于两个英文字符,不乘2会乱码。         string suffix=alticle.substr((i+prefix_len)*2,suffix_len*2);        for(int j=0;j<length;j++){            if(pairlist[j].prefix == prefix){    // 如果已经有了这个前缀,则添加后缀                 pairlist[j].push(suffix);                hasrecord = true;                break;            }        }        if(!hasrecord){                            //    没有这个前缀则词组对列表长度增加             Wordpair pair(prefix, suffix);            pairlist = append2list(pairlist, pair, length);            length++;        }    }    return pairlist;}

    在此基础上,对每次读文件都进行一次,就能获取全部文件的字符对。

    4.6 核心函数:文章拼接

    得到语料库之后,需要根据语料库拼接出文章。我这里采用的方法有点问题,当完全防止出现循环文本的时候,文章过短,当放开一点对循环文本的时候,循环文本总是出现,算法上想不通。希望有大佬提供一点思路。

    // 判断前缀是否在列表内,有则返回下标,没有则返回-1int hasrecord(Wordpair *pairlist, int len, string preword){    for(int i=0; i<len; i++){        if(preword == pairlist[i].prefix){            return i;        }    }    return -1;}// 拼接文章 void createAlticle(Wordpair *pairlist, int len, string startword, int prefix_len, int suffix_len){    string preword = startword;    int i=0;    int index = hasrecord(pairlist, len, preword);    string alticle = preword;    int alticle_len = prefix_len;            //长度(中文字符标准)     while(index != -1){        string newword = pairlist[index].maxFrequency();        // 避免循环         if(alticle.find(newword)==string::npos    //表示这个前缀没有在文章中出现过 //         || alticle_len - alticle.rfind(newword) > 600    //表示相同的词之间最少间隔多少。加上这个条件后有循环,注释后文章显著变短          ){            alticle.append(pairlist[index].maxFrequency());            alticle_len += suffix_len;            preword = alticle.substr((alticle_len-prefix_len)*2, alticle_len*2);}        else{            preword = pairlist[index+1].maxFrequency();        }        index = hasrecord(pairlist, len, preword);    }    cout<<alticle<<endl;    ofstream fout(CREATE_ALTICLE, ios::out);    fout<<alticle;    fout.close();    cout<<"文章写入文件 < "<<CREATE_ALTICLE<<" >"<<endl;}

    以上就是关于“基于C++如何编写一个文章生成器”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网其他教程频道。

    --结束END--

    本文标题: 基于C++如何编写一个文章生成器

    本文链接: https://www.lsjlt.com/news/351923.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • 基于C++编写一个文章生成器
      目录1.概况2.基本要求3.程序分析3.1 文件流读写3.2 建立前后缀关系3.3 字符串切片3.4 变长数组4.代码实现4.1 函数:数组加长4.2 类wordpair定义4.3 ...
      99+
      2023-03-19
      C++文章生成器 C++文章生成 C++生成器
    • 基于C++如何编写一个文章生成器
      这篇“基于C++如何编写一个文章生成器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于C++如何编写一个文章生成器”文章吧...
      99+
      2023-07-05
    • 基于Python编写一个二维码生成器
      目录前言1、安装第三方库2、QRCode参数解释3、自定义二维码生成器4、给二维码加图片5、全部代码前言 二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Res...
      99+
      2022-11-11
    • 基于Python怎么编写一个二维码生成器
      这篇“基于Python怎么编写一个二维码生成器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于Python怎么编写一个二维...
      99+
      2023-07-02
    • 基于C++编写一个Json解析器
      目录前言代码JsonSerialize.hJsonSerialize.cppmain.cpp前言 这个是我闲着没事写的,这个解析器还有两个问题 1.读取中文的时候会出错,这个应该是在...
      99+
      2023-03-09
      C++编写Json解析器 C++ Json解析器 C++ Json解析
    • 基于C++怎么编写一个Json解析器
      这篇文章主要介绍了基于C++怎么编写一个Json解析器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于C++怎么编写一个Json解析器文章都会有所收获,下面我们一起来看看吧。代码JsonSerialize.h...
      99+
      2023-07-05
    • 基于C++编写一个简单的服务器
      本文使用上一期写的反射类,另外我发现<WinSock2.h>这个头文件里有RegisterClass 这个结构,还有typedef RegisterClass Regis...
      99+
      2023-03-14
      C++编写简易服务器 C++编写服务器 C++服务器
    • 基于C++怎么编写一个简单的服务器
      这篇文章主要讲解了“基于C++怎么编写一个简单的服务器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于C++怎么编写一个简单的服务器”吧!先写个简易的controller基类继承反射基类,...
      99+
      2023-07-05
    • 基于JavaScript如何编写一个翻卡游戏
      这篇文章主要介绍“基于JavaScript如何编写一个翻卡游戏”,在日常操作中,相信很多人在基于JavaScript如何编写一个翻卡游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于JavaScript如...
      99+
      2023-07-05
    • 基于PyQt5如何制作一个gif动态图片生成器
      这篇文章的内容主要围绕基于PyQt5如何制作一个gif动态图片生成器进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!这个小工具制作的目的是为了将多张图...
      99+
      2023-06-28
    • 基于vite2+Vue3如何编写一个在线帮助文档工具
      本篇内容主要讲解“基于vite2+Vue3如何编写一个在线帮助文档工具”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“基于vite2+Vue3如何编写一个在线帮助文档工具”吧!技术栈vite: ^...
      99+
      2023-06-29
    • 如何用python编写一个生成春联软件
      目录前言效果展示代码打包exe可执行文件总结前言 最近不是快过年了,Python写对联挺火的,但是代码又不是人人都用,那就直接写个界面打包一下呗~ 主要实现只要运行后输入上联下联、横...
      99+
      2022-11-13
    • 如何利用C++编写一个简单的学生成绩管理程序?
      如何利用C++编写一个简单的学生成绩管理程序?导言:在学校或者教育机构中,学生成绩的管理是一个非常重要的任务。为了更加高效地管理学生成绩,我们可以利用C++语言编写一个简单的学生成绩管理程序。本文将介绍如何使用C++语言实现一个简单的学生成...
      99+
      2023-11-03
      C++ 学生成绩 管理程序
    • 我用GPT写了一个关于GPT的文章,大家看看写的如何
      声明:以下内容来自GPT-3.5大模型(图片除外) 目录 I. 引言 1.1 研究背景和意义 1.2 现有研究综述 II. ChatGPT技术介绍 2.1 ChatGPT技术原理 2.2 ChatGPT技术优势 III. ChatGPT技术...
      99+
      2023-10-07
      gpt 人工智能 笔记
    • 如何通过一篇文章了解Python中的生成器
      目录前言生成器也是迭代器生成器推导式无限生成器生成器实际用法1. 读取文件行2.读取文件内容高级生成器用法总结前言 生成器很容易实现,但却不容易理解。生成器也可用于创建迭代器,但生成...
      99+
      2022-11-13
    • Android基于Flutter如何编写文件下载管理器
      这篇文章主要介绍“Android基于Flutter如何编写文件下载管理器”,在日常操作中,相信很多人在Android基于Flutter如何编写文件下载管理器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”And...
      99+
      2023-06-29
    • 如何使用C++编写一个简单的学生选课系统?
      如何使用C++编写一个简单的学生选课系统?随着科技的不断发展,计算机编程已经成为了一种必备的技能。而在学习编程的过程中,一个简单的学生选课系统可以帮助我们更好地理解和应用编程语言。在本文中,我们将介绍如何使用C++编写一个简单的学生选课系统...
      99+
      2023-11-02
      C++ 编写 学生选课系统
    • 如何用C写一个web服务器之基础功能
      目录服务器架构目标架构当前状态功能实现socket系列方法服务器与 PHP cli 交互报文数据处理服务器架构 目标架构 以 nginx 的思想来考虑本服务器架构,初步考虑如下图: ...
      99+
      2022-11-12
    • 如何用nodejs给C#写一个数据表的实体类生成工具
      虽然微软提供了T4模板,但是我感觉非常难用。哪儿比得上直接用脚本来写模板来的爽。 因为要给一个老项目做周边的工具,需要连接到数据库。 我习惯性用EntityFrameworkCore...
      99+
      2022-11-12
    • 如何使用C++编写一个简单的学生信息管理系统?
      如何使用C++编写一个简单的学生信息管理系统?学生信息管理系统是一款非常常见且实用的软件,用于管理和记录学生的基本信息、课程成绩等。本文将指导您如何使用C++编写一个简单的学生信息管理系统。首先,您需要确定学生信息管理系统的基本功能模块。常...
      99+
      2023-11-04
      C++ 编写 学生信息管理
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作