求算法,贝叶斯统计算法多少个单词

在list中统计单词的数目(泛型算法应用)
#include &iostream&
#include &list&
#include &string&
#include &algorithm&
using std::
using std::
using std::
using std::
using std::
int main()
string sval, searchV
list&string&
cout && "Enter some strings(Ctrl + Z
to end):" &&
while(cin && sval)
slst.push_back(sval);
cin.clear();
cout && "Enter a string you want to
search:" &&
cin && searchV
cout && count(slst.begin(),
slst.end(), searchValue) && "
elements in the list are \"" &&
searchValue && "\""
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。中文字数(不含标点)0
英文单词数0
英文字母总数0
大写英文字母数0
小写英文字母数0
这个在线字数统计工具适用于IE、Chrome、FireFox等主流浏览器。
此在线字数统计工具适用于Chrome、FireFox、IE等主流浏览器。能计算出输入文本的中文汉字数,英文单词数,英文字符数,数字个数。
如果这个字数统计工具能够帮助到你,请点右边侧边栏的分享按钮,将这个在线统计器分享给你的朋友吧,也许你的朋友正需要一个字数统计器。
感谢使用绿色安全的在线字数统计工具、字数统计器。你可以向下方的邮件地址发送你的宝贵建议。谢谢你的使用。
Copyright&@&&&Chen Zuhuang&&All Rights Reserved&&&&Powered by Chen Zuhuang
湘ICP备号-1一步一步写算法(之单词统计)_c语言_51自学网
一步一步写算法(之单词统计)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @】 在面试环节中,有一道题目也是考官们中意的一道题目:如果统计一段由字符
【 声明:版权所有,欢迎转载,请勿用于商业用途。& 联系信箱:feixiaoxing @】
&&& 在面试环节中,有一道题目也是考官们中意的一道题目:如果统计一段由字符和和空格组成的字符串中有多少个单词?
&&& 其实,之所以问这个题目,考官的目的就是想了解一下你对状态机了解多少。
&&& (1) 题目分析
&&& 从题目上看,如果对一个字符串进行处理,,那么可以有下面几种情形:初始状态,字符状态,空格状态,结束状态。那么这几种状态之间应该怎么迁移呢?
&&& 初始状态: 如果输入符号是空格,那么进入空格状态;如果是字符,那么就进入字符状态,同时单词个数+1;如果是结束状态,那么直接返回;
&&& 字符状态:如果输入符号是空格,那么进入空格状态;如果是字符,那么什么也不做;如果是结束,直接返回;
&&& 空格状态:如果输入符号是空格,那么什么也不做;如果是字符,那么进入字符状态,同时单词个数+1;如果结束状态,那么直接返回。
/*&&&&&&&&& 输入是字符
*&&&&&&&&&& --------&&&& 字符状态----------
*&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | --&
*&&&&& 初始状态& 输入字符& |& |& 输入空格&&&&&&&&&&& 结束状态
*&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& --&
*&&&&&&&&& ---------&&&& 空格状态----------|
*&&&&&&&&&&& 输入是空格
/*&&&&&&&&& 输入是字符
*&&&&&&&&&& --------&&& &字符状态----------
*&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | --&
*&&&&& 初始状态& 输入字符& |& |& 输入空格&&&&&&&&&&& 结束状态
*&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& --&
*&&&&&&&&& ---------&&&& 空格状态----------|
*&&&&&&&&&&& 输入是空格
&&& (2)根据上面描述的状态迁移过程,编写对应的代码
typedef enum{&
&&& INIT_STATE = 1,&
&&& WORD_STATE,&
&&& SPACE_STATE,&
int count_word_number(const char* pStr)&
&&& int count = 0;&
&&& int state = INIT_STATE;&
&&& if(NULL == pStr)&
&&&&&&& return 0;&
&&& while(value = *pStr++){&
&&&&&&& switch (state)&
&&&&&&& {&
&&&&&&& case INIT_STATE:&
&&&&&&&&&&& if(' ' != value)&
&&&&&&&&&&&&&&& count ++, state = WORD_STATE;&
&&&&&&&&&&& else&
&&&&&&&&&&&&&&& state = SPACE_STATE;&
&&&&&&&&&&&&
&&&&&&& case WORD_STATE:&
&&&&&&&&&&& if(' ' == value)&
&&&&&&&&&&&&&&& state = SPACE_STATE;&
&&&&&&&&&&& else if('\0' == *pStr)&
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&& case SPACE_STATE:&
&&&&&&&&&&& if(' ' != value)&
&&&&&&&&&&&&&&& count ++, state = WORD_STATE;&
&&&&&&&&&&& else if('\0' == *pStr)&
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&& default:&
&&&&&&&&&&&&
&&&&&&& }&
typedef enum{
&&&&&& INIT_STATE = 1,
&&&&&& WORD_STATE,
&&&&&& SPACE_STATE,
int count_word_number(const char* pStr)
&&&&&& int count = 0;
&&&&&& int state = INIT_STATE;
&&&&&& if(NULL == pStr)
&&&&&&&&&&&&& return 0;
&&&&&& while(value = *pStr++){
&&&&&&&&&&&&& switch (state)
&&&&&&&&&&&&& {
&&&&&&&&&&&&& case INIT_STATE:
&&&&&&&&&&&&&&&&&&&& if(' ' != value)
&&&&&&&&&&&&&&&&&&&&&&&&&&& count ++, state = WORD_STATE;
&&&&&&&&&&&&&&&&&&&& else
&&&&&&&&&&&&&&&&&&&&&&&&&&& state = SPACE_STATE;
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& case WORD_STATE:
&&&&&&&&&&&&&&&&&&&& if(' ' == value)
&&&&&&&&&&&&&&&&&&&&&&&&&&& state = SPACE_STATE;
&&&&&&&&&&&&&&&&&&&& else if('\0' == *pStr)
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& case SPACE_STATE:
&&&&&&&&&&&&&&&&&&&& if(' ' != value)
程序自动生成迷宫
(责任编辑:admin)
------分隔线----------------------------
对比下面两个不同程序的输出:char s[10]=s[0]=0;printf(%s\n,s)char *s=mysoh...
在UNIX 系统中,一个子进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那...
首先说明这个问题困扰了我很长时间了,严格地说应该有两天,不过终于通过sqlite的官方...
先看出错的代码:public class HolderT { private T public Holder() { } publ...
SC_HANDLE scm,sH SERVICE_STATUS ServiceS scm=OpenSCManager(NULL,NULL...
#include stdafx.h#include stdarg.h#include windows.h#include locale.h#include st...&&/&&&&/&&&&/&&
统计文件的字符数、单词数以及总行数,包括:
每行的字符数和单词数
文件的总字符数、总单词数以及总行数
空白字符(空格和tab缩进)不计入字符总数;
单词以空格为分隔;
不考虑一个单词在两行的情况;
限制每行的字符数不能超过1000。
请先看代码:
#include &stdio.h&
#include &string.h&
int *getCharNum(char *filename, int *totalNum);
int main(){
char filename[30];
// totalNum[0]: 总行数
totalNum[1]: 总字符数
totalNum[2]: 总单词数
int totalNum[3] = {0, 0, 0};
printf(&Input file name: &);
scanf(&%s&, filename);
if(getCharNum(filename, totalNum)){
printf(&Total: %d lines, %d words, %d chars\n&, totalNum[0], totalNum[2], totalNum[1]);
printf(&Error!\n&);
* 统计文件的字符数、单词数、行数
文件统计数据
成功返回统计数据,否则返回NULL
int *getCharNum(char *filename, int *totalNum){
// 指向文件的指针
char buffer[1003];
//缓冲区,存储读取到的每行的内容
int bufferL
// 缓冲区中实际存储的内容的长度
// 当前读到缓冲区的第i个字符
// 读取到的字符
int isLastBlank = 0;
// 上个字符是否是空格
int charNum = 0;
// 当前行的字符数
int wordNum = 0; // 当前行的单词数
if( (fp=fopen(filename, &rb&)) == NULL ){
perror(filename);
return NULL;
printf(&line
chars\n&);
// 每次读取一行数据,保存到buffer,每行最多只能有1000个字符
while(fgets(buffer, 1003, fp) != NULL){
bufferLen = strlen(buffer);
// 遍历缓冲区的内容
for(i=0; i&bufferL i++){
c = buffer[i];
if( c==' ' || c=='\t'){
// 遇到空格
!isLastBlank && wordNum++;
// 如果上个字符不是空格,那么单词数加1
isLastBlank = 1;
}else if(c!='\n'&&c!='\r'){
// 忽略换行符
charNum++;
// 如果既不是换行符也不是空格,字符数加1
isLastBlank = 0;
!isLastBlank && wordNum++;
// 如果最后一个字符不是空格,那么单词数加1
isLastBlank = 1;
// 每次换行重置为1
// 一行结束,计算总字符数、总单词数、总行数
totalNum[0]++;
totalNum[1] += charN
// 总字符数
totalNum[2] += wordN
// 总单词数
printf(&%-7d%-7d%d\n&, totalNum[0], wordNum, charNum);
// 置零,重新统计下一行
charNum = 0;
wordNum = 0;
return totalN
在D盘下创建文件demo.txt,并输入如下的内容:
运行程序,输出结果为:
上面的程序,每次从文件中读取一行,放到缓冲区buffer,然后遍历缓冲区,统计当前行的字符和单词数。
fgets()函数用于从文件中读取一行或指定个数的字符,其原型为:
& &char * fgets(char *buffer, int size, FILE * stream);
参数说明:
buffer为缓冲区,用来保存读取到的数据。
size为要读取的字符的个数。如果该行字符数大于size-1,则读到 size-1 个字符时结束,并在最后补充' \0';如果该行字符数小于等于 size-1,则读取所有字符,并在最后补充 '\0'。即,每次最多读取 size-1 个字符。读取的字符包括换行符。
stream为文件指针。
有的读者问,为什么不使用getc(),每次从文件中读取一个字符,也无需开辟缓冲区。
这样没有问题,但是在处理换行时要注意跨平台问题,因为不同的平台对文本文件换行的处理不一样,Linux以'\n'为换行符,Windows以'\n\r'为换行符,Mac又以'\r\n'为换行符。所以,使用getc()函数处理换行时比较麻烦。
这里去繁就简,通过fgets()读取整行数据,然后再处理每个字符,直接忽略'\n'和'\r'。
注意:由于每行的结尾会有最多2个字节长度的换行符,fgets()还会添加NUL,所以缓冲区的长度至少为1003,才能容纳每行1000个字符,否则strlen()可能返回垃圾值。
请看代码第43行,打开文件出错时,返回NULL,而不是生硬的exit()。这样可以通知主调函数发生了错误,让主调函数做出适当的处理,或者通知用户,提高软件的用户体验。每日一题5:单词统计
一篇文章(或一本书)由很多单词构成,有的时候我们想统计一下文章中单词出现的次数,怎样快速地做呢?《编程珠玑》书中提到的一种方式是使用散列表,本文实现了该方法。
为了简单,单词定义为仅由英文字母构成的,暂时忽略连字符号,所有单词由空格分开,所以先对一篇文章进行预处理:
int pre_process(const char* filename)
input.open(filename);
o.open("C:/Users/liaojian/Documents/result_no_digital.txt");
int n = 0;
while(input&&word)
const char* p = word.c_str();
char c = *p;
if(c &= 'z' && c &= 'a' || c &= 'Z' && c &= 'A')
if(s != "")
o&&s&&' ';
input.close();
o.close();
统计过程中需要同时记录单词及其出现次数,并且使用散列表对于不同的单词可能会计算出同样的hash值,为了避免冲突,使用链地址法,所以为每个单词建立如下结构体:
struct word_node
char* str;
word_node*
散列表每个元素也是一个结构体,记录了该元素下保存了几个单词:
struct list_head
word_node*
使用网络上下载的《圣经》作为输入,该书有70多万个单词(预处理函数统计值),《编程珠玑》书中所使用的《圣经》版本有近80万个单词,去除重复后,约有30万个单词,所以本次实现也可以使用《编程珠玑》里使用的29989作为散列表的长度,hash函数乘数因子为31:
const int NHASH = 29989;
const int MULT = 31;
下面是hash函数:
unsigned int my_hash(const char* str)
const char* p = str;
unsigned int h = 0;
h = MULT*h + *p;
return h % NHASH;
上面的unsigned关键字很重要,可以避免hash值变成负数(主要由溢出引起的)。
定义一个find函数来查找当前处理的单词是否已经存在:
word_node* find(list_head* hash_list,const char* str)
word_node* p = hash_list-&
if(strcmp(str,p-&str) == 0) return
return NULL;
如果没有找到,那么就要建立一个新节点,然后将其插入的相应的hash元素后的链表中,每个新节点都插入到表头后第一元素:
void insert(list_head* hash_list,word_node* node)
node-&next = hash_list-&
hash_list-&next =
++hash_list-&
hash表使用结束后,还要释放内存空间:
void free_list(list_head *word_list,int list_count)
for (int i = 0; i & list_ ++i)
word_node* p = word_list[i].next;
word_node* q = p-&next;
delete []word_
word_list = NULL;
接下来就可以进行统计了,首先建立一个hash表,然后读入每一个单词(从预处理后的文件中),对每个单词计算其hash值,找到其应该放置hash表位置,然后检查该位置是否已经包含了该单词,如果包含了,在对应的节点上将count加1,否则为其建立一个word_node新节点,然后将该节点插入到hash表相应元素后的链表中,为了后面排序方便,该函数还记录了出现次数最高的单词的出现次数,其值保存在most_wort_count中:
list_head* count(const char* filename,int &most_word_count)
input.open(filename);
list_head* hash_list = new list_head[NHASH];
memset(hash_list,0,NHASH*sizeof(list_head));
most_word_count = 1;
while(input&&word)
const char* wordptr = word.c_str();
unsigned int h = my_hash(wordptr);
word_node* node = find(&hash_list[h],wordptr);
if(node-&count & most_word_count)
most_word_count = node-&
node = new word_
node-&count = 1;
node-&str = new char[strlen(wordptr) + 1];
strcpy(node-&str,wordptr);
insert(&hash_list[h],node);
return hash_
统计完成后,可以对统计结果进行排序,由于单词出现的最高次数不是很大(对于《圣经》而言是6万左右),出现同样次数的单词也不少,所以使用桶排序非常合适,该函数word_list表示count函数统计得到的hash表,list_count表示hash表的长度,most_word_count表示单词出现的最高次数:
list_head* sort(list_head* word_list,int list_count,int most_word_count)
list_head* sorted_word_list = new list_head[most_word_count];
memset(sorted_word_list,0,most_word_count*sizeof(list_head));
for (int i = 0; i & list_ ++i)
word_node* p = word_list[i].next;
word_node* node = new word_
copy(node,p);
insert(&sorted_word_list[most_word_count - p-&count],node);
p = p-&next;
return sorted_word_
该函数中的copy函数主要把待排序的节点复制到一个新节点中,然后插入到排序的数组中(当然也可以直接将该节点拿出来,然后插入到排序的数组中):
void copy(word_node* dst_node,const word_node* src_node)
dst_node-&count = src_node-&count;
dst_node-&str = new char[strlen(src_node-&str) + 1];
strcpy(dst_node-&str,src_node-&str);
测试代码如下(预处理的代码不在贴出):
int _tmain(int argc, _TCHAR* argv[])
char* src_file_name = "The Bible.txt";
char* dst_file_name = "count_result_no_digital_sorted.txt";
o.open(dst_file_name);
int most_word_
list_head* hash_list = count(src_file_name,most_word_count);
list_head* sorted_word_list = sort(hash_list,NHASH,most_word_count);
for (int i = 0; i & most_word_ ++i)
word_node* p = sorted_word_list[i].
o&&p-&str&&' '&&p-&count&&
free_list(hash_list,NHASH);
free_list(sorted_word_list,most_word_count);
程序运行结果如下:
未排序未排序之前的结果如下:
程序运行的结果与时间(4s左右,连同排序时间)均与《编程珠玑》里描述的基本一致。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?}

我要回帖

更多关于 算法训练 字串统计 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信