最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C++編寫一個文章生成器

 更新時間:2023年03月17日 09:52:25   作者:cumt等等  
這篇文章主要為大家介紹一個有趣的小程序,就是利用C++編寫一個文章生成器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下

1.概況

由用戶輸入啟動詞,根據(jù)語料庫中統(tǒng)計的詞語前后綴關系,自動生成一片新的文章。

比如:春天來了,大地媽媽穿上了碧綠的衣裳。嫩綠的小草從地下探出頭來,陶醉在美麗的春天里。

前后綴關系:[前綴,后綴]。上面這段話的前后綴關系有:[春天,來/里],[天來,了],[天里,。],[來了,,]等。

說明:

啟動詞:用戶輸入的一個詞,由這個詞開始生成文章所有內容。

前/后綴:一個詞前后連續(xù)的n個字符。比如前綴為“春天”,由例句中得到后綴可為“來”或“里”,即表示一種語言的前后關系。

2.基本要求

1.準備語料庫:準備相關文章,存為文件。利用程序讀取文章內容,獲取文章語句中詞語的前后關系,即語料庫。語料庫的豐富程度由文章的數(shù)量決定,語料庫又決定程序運行的時間和生成的文章質量。

2.構建前后綴關系:根據(jù)語料庫,依據(jù)設定的前后綴長度,構建字詞的前后綴關系。

3.生成文章:用戶輸入啟動詞,根據(jù)啟動詞為前綴生成后綴得到文段,再根據(jù)文段生成新的前綴,以新前綴生成新后綴以此類推,得到一片文章。

4.應盡量避免循環(huán):有時語料庫中可能出現(xiàn)類似“為所欲為”的接龍結構,造成死循環(huán),同時生成的內容也沒有了意義。

5.輸入輸出形式:

//輸入:
    2    //前綴詞長度
    2    //后綴詞長度
    春天    //啟動詞
//輸出:
    [一篇文章]

3.程序分析

3.1 文件流讀寫

讀文件:從多篇文章中讀取文件內容為字符串,以前/后綴的長度遍歷獲取前/后綴,并建立前后綴關系。

寫文件:為觀察程序執(zhí)行情況,將前/后綴字符對和生成的文章寫入文件。

3.2 建立前后綴關系

當需要在兩種數(shù)據(jù)間建立一種關系時,可以使用結構化數(shù)據(jù)進行存儲,比如建立前后綴關系可以采用字典類結構進行存儲,C++也有相應的頭文件。

除此之外,還可以將其抽象為一種類,可以定制類的行為和結構。這里選擇自建一個類進行存儲。

類設計:

  • 一個類記錄一個前綴和它的所有后綴,
  • 記錄后綴的出現(xiàn)次數(shù)
  • 記錄后綴的個數(shù)
class wordpair{
    private:
        char **suffix    //后綴字符串數(shù)組,一個后綴存為一個字符串
        int *freq        //一個后綴出現(xiàn)的次數(shù)
    public:
        char *prefix    //前綴字符串,聲明為公共成員,方便外部查找
        int length        //記錄后綴的個數(shù)
}

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++處理字符串很麻煩,現(xiàn)在倒覺得還是很方便的。

3.4 變長數(shù)組

C語言和C++中,基礎的數(shù)組長度相對固定,但也不是不能改變,只是相對麻煩一些。在這個程序中,一個wordpair只存儲一個前綴和它的后綴們,所以需要創(chuàng)建一個wordpair類型的列表來存儲全部的前后綴。

我用的方法是來回地復制

int main(){
    int len;
    int list[len];    //假設有一個長度為len的整型數(shù)組
    int p[len+1];    //開辟一個len+1個整型長度的空間
    //    把 list 復制到 p,然后
    list = new int[len+1];    //將list長度+1
    //把 p 復制過來
}

4.代碼實現(xiàn)

4.1 函數(shù):數(shù)組加長

由于數(shù)組加長在程序中多次調用,且需要增長的數(shù)組各不相同,所以在這里我定義了一個函數(shù)模板,以盡可能少的代碼完成相同的任務。

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;    // 整型數(shù)組,依此記錄后綴的頻率
    public:
        string prefix;    // 前綴 
        int length;        // 記錄長度 , 一個前綴對應size個后綴 
        Wordpair(string prefix, string suffix){    //構造函數(shù)
            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(){                                //構造函數(shù)
            this->prefix = "",
            this->suffix = new string[1];
            this->suffix[0] = "";
            this->freq = new int[1];
            this->freq[0] = 0;
            this->length = 0;
        }
        /* 判斷這個后綴是否已經有記錄,有返回下標,沒有則返回-1 */
        int hasRecorded(string word){}
        
        /* 添加一個后綴 */
        bool push(string word){}
        
        /* 找出出現(xiàn)次數(shù)最多的后綴的下標,采用更可信的后綴 */
         string maxFrequency(){}
        
        /* 轉化為字符串,方便輸出 */
        string to_String()const{}
        /* 重載賦值運算符,方便與其他類型的列表共用函數(shù) */
        Wordpair& operator=(Wordpair &pair){}
};

除此之外,還可以重載輸出運算符<<,便于調試時在函數(shù)中輸出wordpair值:

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

4.3 函數(shù):讀取文件

程序運行時,需要讀取文件為字符串,當文件較多時把這個功能抽象出來,調用很方便。

// 讀文件 
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 函數(shù):寫入文件

主要是寫入生成的字符對,方便調試

// 寫文件,記錄詞組對 
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];        //在這里就體現(xiàn)了重載<<運算符的好處
    }
    fout.close();
    cout<<"詞組對已經寫入文件< "<<path<<" >"<<endl; 
}

4.5 核心函數(shù):字符串分割

讀取到文件后,將字符串從下標0開始,讀取前綴+后綴的長度,然后從1開始讀取前綴+后綴的長度。循環(huán)的次數(shù)應該是字符串總長度 - (前綴長度+后綴長度 -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中發(fā)現(xiàn)一個中文字符相當于兩個英文字符,不乘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 核心函數(shù):文章拼接

得到語料庫之后,需要根據(jù)語料庫拼接出文章。我這里采用的方法有點問題,當完全防止出現(xiàn)循環(huán)文本的時候,文章過短,當放開一點對循環(huán)文本的時候,循環(huán)文本總是出現(xiàn),算法上想不通。希望有大佬提供一點思路。

// 判斷前綴是否在列表內,有則返回下標,沒有則返回-1
int 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();
        // 避免循環(huán) 
        if(alticle.find(newword)==string::npos    //表示這個前綴沒有在文章中出現(xiàn)過 
//         || alticle_len - alticle.rfind(newword) > 600    //表示相同的詞之間最少間隔多少。加上這個條件后有循環(huán),注釋后文章顯著變短 
         ){
            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;
}

5.總結

在沒有機器學習的支持下,這種拼接的文章十分粗糙,無法準確的給出最優(yōu)的選擇。另一方面,代碼寫的過于拖沓,算法有待優(yōu)化。

到此這篇關于基于C++編寫一個文章生成器的文章就介紹到這了,更多相關C++文章生成器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt數(shù)據(jù)庫應用之通用數(shù)據(jù)庫同步

    Qt數(shù)據(jù)庫應用之通用數(shù)據(jù)庫同步

    數(shù)據(jù)庫同步的主要功能是將本地的數(shù)據(jù)庫記錄同步到遠程的數(shù)據(jù)庫。本文將利用Qt實現(xiàn)通用數(shù)據(jù)庫同步功能,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-03-03
  • 詳解Matlab如何繪制小提琴圖

    詳解Matlab如何繪制小提琴圖

    小提琴圖 (Violin Plot)是用來展示多組數(shù)據(jù)的分布狀態(tài)以及概率密度。這種圖表結合了箱形圖和密度圖的特征,主要用來顯示數(shù)據(jù)的分布形狀。本文將介紹如何利用Matlab繪制小提琴圖,需要的可以參考一下
    2022-02-02
  • C語言實現(xiàn)個人財務管理軟件

    C語言實現(xiàn)個人財務管理軟件

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)個人財務管理軟件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言數(shù)據(jù)結構系列隊列篇

    C語言數(shù)據(jù)結構系列隊列篇

    本章我們將學習 "隊列" ,首先介紹隊列的概念和結構,然后我們將著重講解棧的實現(xiàn)。我們從零開始寫隊列的接口,并從零開始步步解讀。本章將繼續(xù)鞏固畫思路草圖的能力,只要思路草圖畫好了,就可以很輕松地將其轉換成代碼
    2022-02-02
  • C++寫注冊表項實例

    C++寫注冊表項實例

    這篇文章主要介紹了C++寫注冊表項實例,可實現(xiàn)開機啟動的功能,是進行Windows桌面應用程序開發(fā)中非常重要的技巧,需要的朋友可以參考下
    2014-10-10
  • 詳解C語言中Char型指針數(shù)組與字符數(shù)組的區(qū)別

    詳解C語言中Char型指針數(shù)組與字符數(shù)組的區(qū)別

    這篇文章主要介紹了詳解C語言中Char型指針數(shù)組與字符數(shù)組的區(qū)別的相關資料,希望通過本文能幫助到大家掌握理解這部分內容,需要的朋友可以參考下
    2017-10-10
  • 詳解C++ 多態(tài)的兩種形式(靜態(tài)、動態(tài))

    詳解C++ 多態(tài)的兩種形式(靜態(tài)、動態(tài))

    這篇文章主要介紹了C++ 多態(tài)的兩種形式,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下
    2020-08-08
  • c++中將二維數(shù)組元素變換為逆向存放的實現(xiàn)代碼

    c++中將二維數(shù)組元素變換為逆向存放的實現(xiàn)代碼

    編程將一個二維數(shù)組元素變換為逆向存放,即按元素在內存中的物理排列位置,第一個元素變成倒數(shù)第一個元素,第二個元素變成倒數(shù)第二個元素,依此類推
    2020-11-11
  • C語言實現(xiàn)飛機游戲(豪華版)的示例代碼

    C語言實現(xiàn)飛機游戲(豪華版)的示例代碼

    在前文中已經實現(xiàn)了基礎版和進階版的飛機游戲,但是存在的問題很明顯:已經發(fā)射出去的子彈會隨著飛機位置的實時改變而改變,并且不能實現(xiàn)連發(fā)。本篇文章將利用數(shù)組進一步改進空戰(zhàn)游戲,感興趣的可以了解一下
    2022-10-10
  • C++中線程同步與互斥的四種方式介紹及對比詳解

    C++中線程同步與互斥的四種方式介紹及對比詳解

    在C++中,當兩個或更多的線程需要訪問共享數(shù)據(jù)時,就會出現(xiàn)線程安全問題,這是因為,如果沒有適當?shù)耐綑C制,一個線程可能在另一個線程還沒有完成對數(shù)據(jù)的修改就開始訪問數(shù)據(jù),這將導致數(shù)據(jù)的不一致性和程序的不可預測性,本文介紹了C++中線程同步與互斥的四種方式介紹及對比
    2025-01-01

最新評論

安阳县| 桃源县| 襄城县| 盐城市| 浏阳市| 桂平市| 资源县| 沿河| 桦川县| 芒康县| 泽州县| 新绛县| 科技| 塘沽区| 左云县| 黑龙江省| 成武县| 崇阳县| 克东县| 抚顺市| 基隆市| 来安县| 前郭尔| 石首市| 鄂托克旗| 峨眉山市| 密山市| 囊谦县| 盐源县| 凌海市| 辰溪县| 拜城县| 邓州市| 北川| 雷州市| 塘沽区| 龙口市| 兴仁县| 遂昌县| 庄浪县| 东源县|