软件工程-构建之法 WordCount小程序 统计文件中字符串个数,单词个数,词频,行数

一、前言

     在之前写过一个词频统计的C语言课设,别人说你一个大三的怎么写C语言课程,我只想说我是先学习VB,VB是我编程语言的开始,然后接触到C语言及C++;再后来我是学习C++,然后反过来学习C语言,记得那时候自己在C++中没有好好学习,考试之前疯狂的背代码,然后过了。后来学习C语言的时候,自己知道基础很重要,然后认真学习。这WC这回自己就轻车熟路,记得那时候丁国辉课设老师,问我有多少是自己写的,我说有80%自己写的,然后他让我当场给程序增加一个总的单词数和每一个单词的频率,当时记得自己在旁边改了十分钟左右才弄完,因为自己太大意,出现了低级错误,然后自己还一直没有发现。自己学习的map来写词频统计map<string,int>mp,发现更快。代码更短,效率更高。

二、分析

1、在命令行中直接输入一串英文字符串,统计单词的个数,自己是C语言学习的一个初学者,在C语言机考中自己总是会很快的敲出来。

#include <iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
//统计单词的个数
int main()
{
    char a;
    int count=0;
    while((a=getchar())!='\n')
    {
        if(a==' ')
             count++;
    }
    cout << count+1 << endl;
    return 0;
}

2、使用的map的写的统计单词的出现的次数

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<map>
#include<string.h>
using namespace std;

int main()
{
    cout<<"输入以0结尾"<<endl;
    map<string,int>mp;
    string str1;

    while(str1!="0")
    {
        cin>>str1;
        mp[str1]++;
    }
        map<string,int>::iterator iter;
        for(iter=mp.begin();iter!=mp.end();iter++)
        {
            if(iter->first!="0")   //字符的判断与0
                 cout<<iter->first<<" "<<iter->second<<endl;
        }
    return 0;
}

3、在文件中怎么读取字符呢。我们定义一个文件指针

FILE *fp;           //文件指针

使用的时候记得“读”就行打开了就要关闭

if((fp=fopen(name,"r+"))==NULL){
        printf("Open the file failure...\n");
        exit(0);
    }
    fp=fopen(name,"r");
    wordCount();

    fclose(fp);

4、定义了一个结构体,使用链表的存储结构

typedef struct word        //连表 单词结构
{
    char w[Word_Max];    //单词
    int count;                //个数
    struct word *next;
}link;

5、指针指向的字符是否为字母还是其他的格式字符

int isnotWord(char a)        //判断是否为字母
{
    if(a <= 'z' && a >= 'a')
    {
        littleletter++;
        return 0;
    }
    else if(a <= 'Z' && a >= 'A')
    {
        bigletter++;
        return 0;
    }
    else if(a==' ')
    {
        space++;
        return 1;
    }
    else if(a>='1'&&a<='9')
    {
        number++;
        return 1;
    }
    else if(a=='\n')
    {
        hang_num++;
        return 1;
    }
    else
    {
        other++;
        return 1;
    }

}

6、如果是添加单词,就要记录该单词,下次指针再次指到,字符串比较strcmp(str1,str2)==0,如果不是就要动态存储分配malloc。

void addWord(char *w1)        //添加单词
{

    link *p1,*p2;
    //if(w1[0] <= 'Z' && w1[0] >= 'A')    //转成小写字母
    //{
    //    w1[0]+=32;
    //}
    for(p1=head;p1!=NULL;p1=p1->next)    //判断单词在连表中是否存在
    {
        if(!strcmp(p1->w,w1))
        {
            p1->count++;   //存在就个数加1
            return;
        }
    }

    p1=(struct word *)malloc(sizeof(word));//不存在添加新单词
    strcpy(p1->w,w1);
    p1->count=1;
    p1->next=NULL;
    count++;    //总的单词数加加

    if(head==NULL)
    {
        head=p1;
    }
    else
    {
        for(p2=head;p2->next!=NULL;p2=p2->next);
        p2->next=p1;
    }
}

7、单词统计函数

void wordCount()    //统计单词
{
    int i=0,j=0;
    char word[Word_Max],c;
    while(!feof(fp))
    {
        fscanf(fp,"%c",&c);

        if(isnotWord(c))
        {
            word[j]='\0';
            if(j>0)
            {
                addWord(word);

            }
            j=0;
        }
        else
        {

            word[j]=c;
            j++;
        }
        //count9(word);
        i++;
    }
}

三、运行结果及源代码

文件test.txt默认路径是程序编译下的文件夹中。

 

有人会说,”I“不是出现了吗?我统计的个数是0-4(不包括0和4),而“I”这个单词出现的次数是5,不在范围之内。注意:是.txt中有自动换行功能,所以我统计的是自己用回车键换行的行数,这个才是真正的文本的行数。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;

#define Name_Max 30    //文件名最大长度
#define Word_Max 60    //每个单词最大长度

typedef struct word        //连表 单词结构
{
    char w[Word_Max];    //单词
    int count;                //个数
    struct word *next;
}link;

int count=0;
link *head=NULL;    //连表头
FILE *fp;           //文件指针
int bigletter=0,littleletter=0,space=0,number=0,other=0,hang_num=0;;

int isnotWord(char a)        //判断是否为字母
{
    if(a <= 'z' && a >= 'a')
    {
        littleletter++;
        return 0;
    }
    else if(a <= 'Z' && a >= 'A')
    {
        bigletter++;
        return 0;
    }
    else if(a==' ')
    {
        space++;
        return 1;
    }
    else if(a>='1'&&a<='9')
    {
        number++;
        return 1;
    }
    else if(a=='\n')
    {
        hang_num++;
        return 1;
    }
    else
    {
        other++;
        return 1;
    }

}

void addWord(char *w1)        //添加单词
{

    link *p1,*p2;
    //if(w1[0] <= 'Z' && w1[0] >= 'A')    //转成小写字母
    //{
    //    w1[0]+=32;
    //}
    for(p1=head;p1!=NULL;p1=p1->next)    //判断单词在连表中是否存在
    {
        if(!strcmp(p1->w,w1))
        {
            p1->count++;   //存在就个数加1
            return;
        }
    }

    p1=(struct word *)malloc(sizeof(word));//不存在添加新单词
    strcpy(p1->w,w1);
    p1->count=1;
    p1->next=NULL;
    count++;    //总的单词数加加

    if(head==NULL)
    {
        head=p1;
    }
    else
    {
        for(p2=head;p2->next!=NULL;p2=p2->next);
        p2->next=p1;
    }


}

void wordCount()    //统计单词
{
    int i=0,j=0;
    char word[Word_Max],c;
    while(!feof(fp))
    {
        fscanf(fp,"%c",&c);

        if(isnotWord(c))
        {
            word[j]='\0';
            if(j>0)
            {
                addWord(word);
               // count9(word);
                //count1(word,);
            }
            j=0;
        }
        else
        {

            word[j]=c;
            j++;
        }
        //count9(word);
        i++;
    }
}

void readWord()        //读取文件中的单词
{
    char name[Name_Max];
    printf("请出入要读取的单词文件名[如:test.txt]:");
    scanf("%s",name);
    getchar();
    if((fp=fopen(name,"r+"))==NULL){
        printf("Open the file failure...\n");
        exit(0);
    }
    fp=fopen(name,"r");
    wordCount();

    fclose(fp);
}

void showWord(int a,int b)        //显示单词统计情况
{
    link *p;

    printf("个数\t单词\t频率\n");
    for(p=head;p!=NULL;p=p->next)
    {

        if((p->count > a)&&(p->count < b))
            {
                printf("%s\t  %d\t  %.2f\n",p->w,p->count,(float)(p->count)/count);
            }
    }
     printf("总的单词数:%d\n",count);
     printf("总共有%d行\n",hang_num+1);
     printf("总共有%d字符\n",bigletter+littleletter+space+number+other);
     printf("大写字母个数:%d  小写字母个数:%d  空格个数%d  数字个数%d  其他个数%d\n",bigletter,littleletter,space,number,other);

}


int main()
{
    readWord();
    int a,b;
    printf("请输入阈值a和b[如:2 10]:");
    scanf("%d %d",&a,&b);
    getchar();
    showWord(a,b);
    getchar();
}

 

posted @ 2016-03-22 23:56  saucxs  阅读(3113)  评论(5编辑  收藏  举报