给定一个英文原文,统计文件里面一共有多少个不同的英文单词

本文介绍了一个使用C++实现的简单程序,该程序能够读取一个文本文件,并统计其中的不同英文单词数量。通过构建链表结构存储单词及其出现次数,程序能够高效地处理大量文本数据。

wordsCounter.cpp

// wordsCounter.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "wordsCounter.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

//功能:
//给定一个英文原文,统计文件里面一共有多少个不同的英文单词,建议使用C++,注意程序效率.
//说明:
//不支持中文,不支持长度大于100的单词

#define ISUPPER(x) (x>='A' && x<='Z')
#define ISLOWER(x) (x>='a' && x<='z')
#define ISNUM(x) (x>='0' && x<='9')
#define isalnum(x) (ISUPPER(x) || ISLOWER(x) || ISNUM(x))

#define CHECK(x) {if(!(x)){printf("ERROR IN " #x);return;}}

struct NODE
{
NODE *next;
char text[100];
int num;
};

void InsertWord(NODE *&root,char *text)
{
CHECK(text);

if(!root)//如果是空链表,就直接插入作为根
{
root=new NODE;
strcpy(root->text,text);
root->num=1;
root->next=0;
}
else
{
NODE *p=root;
NODE *prev=0;

while (p)//否则,找链表中等于当前单词的项
{
if(stricmp(p->text,text)==0)//如果找到,就增加引用次数num
{
p->num++;
break;
}
else//否则继续找
{
prev=p;
p=p->next;
}
}

if(!p)//如果找不到,就插入到链表最后面
{
p=new NODE;
strcpy(p->text,text);
p->num=1;
p->next=0;
prev->next=p;
}
}
}

void Parse(NODE *&root,char *str)
{
char *p1=str,*p2=str;//p1指向单词开头,p2指向单词结尾
char word[100];

while(*p1)
{
//找单词的开头
while (*p1 && !isalnum(*p1))
p1++;

if(!*p1)
break;
else
{
p2=p1;
}

//printf("enter while *p2 ");

//找单词的结尾
while (*p2 && /**p2!=' ' && *p2!=' ' &&*/ isalnum(*p2) )
{
p2++;
}

//printf("p2-p1 %d,*p2 %c ",p2-p1,*p2);

//将单词加入到链表中
if(p2>p1)
{
CHECK(p2-p1<100);
strncpy(word,p1,p2-p1);
word[p2-p1]=0;
//printf("Find %s ",word);
InsertWord(root,word);
p1=p2;
}
else
break;
}
}

void PrintNodes(NODE *root)
{
CHECK(root);
int wordsNum=0;
int diffWordsNum=0;
NODE *pmaxNum=0;

while (root)
{
wordsNum+=root->num;
diffWordsNum++;

if(!pmaxNum)
pmaxNum=root;
else if(pmaxNum->num < root->num)
pmaxNum=root;

printf("%s %d ",root->text,root->num);
root=root->next;
}

printf("共%d个单词,共%d个不同单词,出现最多的单词是 %s [%d] ",wordsNum,diffWordsNum,pmaxNum->text,pmaxNum->num);
}

void ReleaseLinks(NODE *&root)
{

if(!root)
return;

NODE *p=root;

while (root)
{
p=root;
root=root->next;
delete p;
}
}

void _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
CString strHello;
strHello.LoadString(IDS_HELLO);
cout << (LPCTSTR)strHello << endl;

NODE *root=0;
//char str[1000]="hello test what hello HeLLO 123 3432 what is a dog my name is hejinshou";
FILE *fp=fopen("wordscounter.cpp","r");
int len=0;
char *str=0;

CHECK(fp);
fseek(fp,0,2);
len=ftell(fp);
CHECK(len>0);
str=new char[len+1];
fseek(fp,0,0);
fread(str,len,1,fp);
str[len]=0;

Parse(root,str);
PrintNodes(root);

ReleaseLinks(root);
delete []str;
}

return ;
}

一般的文本编辑器都有查找单的功能,该功能可以快速定位特定单在文章中的位置,有的还能统计出特定单在文章中出现的次数。 现在,请你编程实现这一功能,具体要求是:给定一个,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单时,不区分大小写,但要求完全匹配,即给定必须文章中的某一独立单在不区分大小写的情况下完全相同(参见样例1),如果给定仅是文章中某一单的一部分则不算匹配(参见样例2)。 输入描述 共 22 行。 第 11 行为一个字符串,其中只含字母,表示给定; 第 22 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。 输出描述 一行,如果在文章中找到给定则输出两个整数,两个整数之间用一个空格隔开,分别是单在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单首字母在文章中的位置,位置从 00 开始); 如果单在文章中没有出现,则直接输出一个整数 −1−1。 一般的文本编辑器都有查找单的功能,该功能可以快速定位特定单在文章中的位置,有的还能统计出特定单在文章中出现的次数。 现在,请你编程实现这一功能,具体要求是:给定一个,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单时,不区分大小写,但要求完全匹配,即给定必须文章中的某一独立单在不区分大小写的情况下完全相同(参见样例1),如果给定仅是文章中某一单的一部分则不算匹配(参见样例2)。 输入描述 共 22 行。 第 11 行为一个字符串,其中只含字母,表示给定; 第 22 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。 输出描述 一行,如果在文章中找到给定则输出两个整数,两个整数之间用一个空格隔开,分别是单在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单首字母在文章中的位置,位置从 00 开始); 如果单在文章中没有出现,则直接输出一个整数 −1−1。 一般的文本编辑器都有查找单的功能,该功能可以快速定位特定单在文章中的位置,有的还能统计出特定单在文章中出现的次数。 现在,请你编程实现这一功能,具体要求是:给定一个,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单时,不区分大小写,但要求完全匹配,即给定必须文章中的某一独立单在不区分大小写的情况下完全相同(参见样例1),如果给定仅是文章中某一单的一部分则不算匹配(参见样例2)。 输入描述 共 22 行。 第 11 行为一个字符串,其中只含字母,表示给定; 第 22 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。 输出描述 一行,如果在文章中找到给定则输出两个整数,两个整数之间用一个空格隔开,分别是单在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单首字母在文章中的位置,位置从 00 开始); 如果单在文章中没有出现,则直接输出一个整数 −1c++
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值