軟件工程-構建之法 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();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM