设计任务
从网上下载一些英文小说,用多线程实现文本本件中所含单词总数的统计。
从网上下载一些英文小说,统计单词出现频率并从中找出Top10热词。
解决方案
区分单词原则:凡是一个非字母或数字的字符跟在字母或数字的后面,那么
这个字母或数字就是单词的结尾.
允许线程使用互斥锁来修改临界资源,确保线程间的同步与协作。
如果两个线程需要安全地共享一个公共计数器,需要把公共计数器加锁。
文件名为1.txt 2.txt ....
#include <iostream>
#include <fstream>
#include <map>
#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <pthread.h>
#include <malloc.h>
#include <semaphore.h>
using namespace std;
struct node
{
string s;
int cnt;
node(string ss,int cnt_)
{
s=ss;cnt=cnt_;
}
bool operator < (const node &a)const
{
return a.cnt>cnt;
}
};
priority_queue<struct node>q;
int sum_num=0;
pthread_mutex_t mutex;
map<string,int>mp;
void *find(void* id)
{
int now=*(int *)id;
char frename[20];
sprintf(frename,"%d.txt",now);
// printf("%s\n",frename);
FILE* p=fopen(frename,"r");
string word="";
char c;
int i=0;
c=fgetc(p);
while(c!=EOF)
{
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))
{
word+=c;
}
else
{
if(word=="")
{
c=fgetc(p);
continue;
}
while(pthread_mutex_lock(&mutex)!=0);
mp[word]++;
sum_num++;
word="";
pthread_mutex_unlock(&mutex);
}
c=fgetc(p);
}
fclose(p);
}
int main()
{
while(pthread_mutex_init(&mutex,NULL)!=0);
int p_num;
printf("请输入小说篇数: ");
scanf("%d",&p_num);
pthread_t* tidp=(pthread_t *)malloc(sizeof(pthread_t)*(p_num+1));
int* id=(int *)malloc(sizeof(int)*(p_num+1));
for(int i=1;i<=p_num;i++)
{
id[i]=i;
while(pthread_create(&tidp[i],NULL,find,&id[i])!=0);
}
for(int i=1;i<=p_num;i++)
{
pthread_join(tidp[i],NULL);
}
pthread_mutex_destroy(&mutex);
printf("%d\n",sum_num);
printf("top:\n");
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
{
q.push(node(it->first,it->second));
}
for(int i=1;i<=10&&!q.empty();i++)
{
cout<<q.top().s;
printf(" %d\n",q.top().cnt);
q.pop();
}
free(tidp);
free(id);
return 0;
}