日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

词频统计 求最大k个数

發(fā)布時(shí)間:2025/10/17 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 词频统计 求最大k个数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題外話:想當(dāng)年,編譯原理課偷懶沒自己實(shí)現(xiàn)這玩意,欠的終究還是要還的,現(xiàn)在補(bǔ)回來了。。。

Write a program for displaying the ten most frequent words in a file

such that your program should be efficient in all complexity measures.

/*(針對大量數(shù)據(jù)的作法)
思路:每讀一個單詞 ,存入字典序的平衡二叉搜索樹中,這樣判斷是否新單詞或舊單詞詞頻加一
的掃描時(shí)間復(fù)雜度大大減小;讀取完整個文本,建好樹后,遍歷一遍樹,用最小堆存取
詞頻最大的10個單詞,堆頂為詞頻最小的單詞,所以每次只要與堆頂比較,需要替換則重排,
遍歷完即出結(jié)果
*/
/*
本來打算建一張10個數(shù)據(jù)結(jié)構(gòu)大小的哈希表,存儲10個出現(xiàn)頻數(shù)最大的單詞詞頻,逐個讀短文單詞
邊插入樹結(jié)點(diǎn)時(shí)邊更新表,
之后想若同一單詞出現(xiàn)的頻數(shù)很多,這樣同一個單詞得更新表很多次,不劃算,
不如建好等平衡樹后
遍歷一遍,找出count最大的十個單詞,這樣每個不同的單詞只遍歷一次。
*/
/*
以下程序strcpy雖然能正確執(zhí)行,但實(shí)際上有問題,可以換為如下,我就不換了,就重寫個strcpy函數(shù)就好
strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '/0';
len = strlen(path);
*/

#include<stdio.h> #include<string> #include<string.h> #include<vector> #include<stdlib.h> using namespace std;#define wordLength 20 #define maxCountNum 10struct AVLTree {char word[wordLength];//單詞int count;//計(jì)數(shù)int height;//樹的深度struct AVLTree* lTree;//左子樹struct AVLTree* rTree;//右子樹 };/*存儲出現(xiàn)頻率最大的十個結(jié)點(diǎn)*/ struct MAXCount {//string word;char word[wordLength];//單詞int count;//計(jì)數(shù) }; vector <struct MAXCount> maxCount(maxCountNum);/*返回大值*/ int Max(int a,int b); /*返回結(jié)點(diǎn)的深度*/ int Height(struct AVLTree* node); /*插入子結(jié)點(diǎn)*/ struct AVLTree* insertNode(char *word,struct AVLTree* root); /*刪除樹所有結(jié)點(diǎn)*/ void deleteTree(struct AVLTree** root); /*遍歷顯示樹*/ void display(struct AVLTree* root); /*右旋轉(zhuǎn)*/ struct AVLTree* LLRotate(struct AVLTree* root); /*左旋轉(zhuǎn)*/ struct AVLTree* RRRotate(struct AVLTree* root); /*先左后右旋轉(zhuǎn)*/ struct AVLTree* LRRotate(struct AVLTree* root); /*先右后左旋轉(zhuǎn)*/ struct AVLTree* RLRotate(struct AVLTree* root); /*判斷是否是出現(xiàn)頻率最多的10個單詞 與堆頂最小值比較 是:替換,重排*/ void maxCountWord(struct AVLTree* root); /*去除單詞尾的標(biāo)點(diǎn)符號 并把首字母為大寫的轉(zhuǎn)換為小寫*/ void punctuationRid_LetterChange(char *temp); /*堆排序 最小堆*/ void heapSort(vector<struct MAXCount> &maxCount, int root, int end); /*結(jié)果顯示 詞頻最大的十個單詞*/ void showMaxCountWord(); /*返回大值*/ int Max(int a,int b) {return a>b?a:b; }/*返回結(jié)點(diǎn)的深度*/ int Height(struct AVLTree* node) {if(node == NULL)return -1;return node->height; }/*按字典序比較strcmp() str1>str2 返回正數(shù)str1=str2 返回零str1<str2 返回負(fù)數(shù) *//*插入子結(jié)點(diǎn)*/ struct AVLTree* insertNode(char *word,struct AVLTree* root) {if(root == NULL){root=(struct AVLTree*)malloc(sizeof(struct AVLTree));strcpy(root->word,word);root->count=1;root->height=0;root->lTree=NULL;root->rTree=NULL;}else if(strcmp(word,root->word) == 0){root->count++;}/*插入左子樹*/else if(strcmp(word,root->word) < 0){root->lTree=insertNode(word,root->lTree);if (Height(root->lTree) - Height(root->rTree) == 2) /*AVL樹不平衡*/{if (strcmp(word,root->lTree->word) < 0)//LL 右旋轉(zhuǎn){/*插入到了左子樹左邊, 做單旋轉(zhuǎn)*/root = LLRotate(root);}else //LR 先左后右{/*插入到了左子樹右邊, 做雙旋轉(zhuǎn)*/root = LRRotate(root);}}}/*插入右子樹*/else if(strcmp(word,root->word) > 0){root->rTree=insertNode(word,root->rTree);if (Height(root->rTree) - Height(root->lTree) == 2) /*AVL樹不平衡*/{if (strcmp(word,root->rTree->word) > 0)//RR 左旋轉(zhuǎn){/*插入到了右子樹右邊, 做單旋轉(zhuǎn)*/root = RRRotate(root);}else //RL 先右后左{/*插入到了右子樹左邊, 做雙旋轉(zhuǎn)*/root = RLRotate(root);}}}root->height=Max(Height(root->lTree),Height(root->rTree))+1;return root; }/*刪除樹所有結(jié)點(diǎn)*/ void deleteTree(struct AVLTree** root) {if(root == NULL || *root == NULL)return;deleteTree(&((*root)->lTree));deleteTree(&((*root)->rTree));free(*root);*root=NULL; }/*遍歷顯示樹*/ void display(struct AVLTree* root) {if(root==NULL)return;static int cnt=0;display(root->lTree);//輸出每個單詞的詞頻//printf("[%2d]word:%20s\tcount:%d\r\n",cnt++,root->word,root->count);/*判斷是否是出現(xiàn)頻率最多的10個單詞*/maxCountWord(root);display(root->rTree); }/*右旋轉(zhuǎn)*/ struct AVLTree* LLRotate(struct AVLTree* root) {struct AVLTree* node;node=root->lTree;root->lTree=node->rTree;node->rTree=root;/*結(jié)點(diǎn)的位置變了, 要更新結(jié)點(diǎn)的高度值*/root->height=Max(Height(root->lTree),Height(root->rTree))+1;node->height=Max(Height(node->lTree),Height(node->rTree))+1;return node; }/*左旋轉(zhuǎn)*/ struct AVLTree* RRRotate(struct AVLTree* root) {struct AVLTree* node;node = root->rTree;root->rTree = node->lTree;node->lTree = root;/*結(jié)點(diǎn)的位置變了, 要更新結(jié)點(diǎn)的高度值*/root->height=Max(Height(root->lTree),Height(root->rTree))+1;node->height=Max(Height(node->lTree),Height(node->rTree))+1;return node; }/*先左后右旋轉(zhuǎn)*/ struct AVLTree* LRRotate(struct AVLTree* root) {root->lTree=RRRotate(root->lTree);return LLRotate(root); }/*先右后左旋轉(zhuǎn)*/ struct AVLTree* RLRotate(struct AVLTree* root) {root->rTree=LLRotate(root->rTree);return RRRotate(root); }/*判斷是否是出現(xiàn)頻率最多的10個單詞 與堆頂最小值比較 是:替換,重排*/ void maxCountWord(struct AVLTree* root) {if(root->count>maxCount[0].count){//替換strcpy(maxCount[0].word,root->word);maxCount[0].count=root->count;heapSort(maxCount,0,10);} }/*去除單詞尾的標(biāo)點(diǎn)符號 并把首字母為大寫的轉(zhuǎn)換為小寫*/ void punctuationRid_LetterChange(char *temp) {char *p=temp;if(*p >= 'A' && *p <= 'Z')*p=*p+32;while( *p != '\0')p++;//若最后一個字符不是字母 ,去除--p;if(*p >= 'a' && *p <= 'z');else*p='\0'; }/*堆排序 最小堆*/ void heapSort(vector<struct MAXCount> &maxCount, int root, int end) {for(int j=end-1;j>root;j--){int parent = (j-1-root)/2+root;//parent=(j-1)/2if(maxCount[parent].count > maxCount[j].count){//交換maxCount[parent].count += maxCount[j].count;maxCount[j].count = maxCount[parent].count - maxCount[j].count;maxCount[parent].count -= maxCount[j].count;char temp[20]="word_count";strcpy(temp,maxCount[parent].word);strcpy(maxCount[parent].word,maxCount[j].word);strcpy(maxCount[j].word,temp);}} }/*結(jié)果顯示 詞頻最大的十個單詞*/ void showMaxCountWord() {printf("------最大詞頻的十個單詞如下-----\r\n");printf("word:\t\t\tcount:\r\n");for(int n=0;n<maxCountNum;n++){printf("%-20s\t%3d\r\n",maxCount[n].word,maxCount[n].count);}printf("------最大詞頻的十個單詞如上-----\r\n"); }int main() {/*打開文件*/FILE *fp;if((fp=fopen("F:\\interview2\\Englishstory.txt","r")) == NULL){printf("File cannot be opened\n");exit(1);}else{/*初始化vector<struct MAXCount> maxCount(10) 建立最小堆*/ char *a="word_count";for(int n=0;n<10;n++){//maxCount[n].word[wordLength]=strcpy(maxCount[n].word,a);maxCount[n].count=0;}heapSort(maxCount,0,maxCountNum);//printf("File can be opened\n");char temp[wordLength];/*依據(jù)單詞首字母依次轉(zhuǎn)換為26棵樹的根節(jié)點(diǎn)地址*/struct AVLTree *rootAddress=NULL;/*循環(huán)讀取文本中的內(nèi)容*/while((fscanf(fp,"%s",temp)) != EOF){//printf("temp:%s\r\n",temp);/*fscanf讀出來的單詞若是句尾,則會包含句尾的標(biāo)點(diǎn)符號,punctuationRid_LetterChange函數(shù) 去掉尾的標(biāo)點(diǎn) 轉(zhuǎn)換頭的大寫*/punctuationRid_LetterChange(temp);//printf("temp:%s\r\n",temp);rootAddress=insertNode(temp,rootAddress);}display(rootAddress);showMaxCountWord();deleteTree(&rootAddress);/*關(guān)閉文件*/fclose(fp);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的词频统计 求最大k个数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。