軟工實踐第二次做業--思索

Github項目地址 :https://github.com/1195653643ios


PSP 表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 60 40
· Estimate · 估計這個任務須要多少時間 60 40
Development 開發 900 670
· Analysis · 需求分析 (包括學習新技術) 200 150
· Design Spec · 生成設計文檔 40 20
· Design Review · 設計複審 30 10
· Coding Standard · 代碼規範 (爲目前的開發制定合適的規範) 20 20
· Design · 具體設計 30 30
· Coding · 具體編碼 400 420
· Code Review · 代碼複審 100 20
· Test · 測試(自我測試,修改代碼,提交修改) 100 120
Reporting 報告 150 150
· Test Repor · 測試報告 60 20
· Size Measurement · 計算工做量 30 30
· Postmortem & Process Improvement Plan · 過後總結, 並提出過程改進計劃 60 100
合計 1110 980

環境

  • 操做系統 :Windows 10
  • IDE : Visual Studio Community 2017
  • 開發語言 :C++

解題思路

​ 提及來有意思,還沒開始作題,就能聽到各類同窗對題目的討論。題目是關於文本詞頻的統計,最先聽到他們用有窮自動機來實現,還以爲奇怪,這玩意不是遍歷就行了嗎?記得之前看Python的時候,好像有一個簡單的函數,就能夠實現相關的操做。認真看完題目後發現:第一,語言只能用JAVA或C++;第二,對單詞的判斷,並不像我想的那麼簡單,結合題目所給的要求,正則表達式的確是很好的選擇。題目關於單詞的定義,用正則表達式寫出就是:git

​ abcd(E*);github

​ 這裏的a,b,c,d是字母表中任取的元素,E是字母表或數字集合的並集。正則表達式

​ 用有窮自動機畫出來就是:app

​ 其中,4爲終結狀態,e表示E中任取的元素。(依稀能看到柯逍老師說這圖太low的表情)函數

​ 代碼實現也很簡單,用flag來表示狀態,當flag爲4時表示出現一個合法的單詞,單詞數加一。在寫代碼的過程當中,看了不少同窗的博客,也詢問告終隊隊友楊喜源同窗,由於喜源同窗的博客還沒寫好,這裏先不給出網址。性能

關鍵代碼

判別單詞及統計單詞頻率(模擬有窮自動機)

while((ch = fgetc(file)) != EOF)
    {
        if ('A' <= ch && ch <= 'Z')
            ch = ch + 32;
        switch (flag) {
            case 0:
            if (ch >= 'a'&&ch <= 'z') { flag++; }
            break;
            case 1:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 2:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 3:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 4:
            if (ch >= 'a'&&ch <= 'z' || (ch >= '0'&&ch <= '9')) { }
            else 
            {
                flag = 0;
                count++;
            }
            break;
        }
    }            /*flag */
    if (flag == 4) 
    {
        count++;
    }

性能分析

計算模塊部分異常處理說明

/*當要輸入的文件不存在時*/
      FILE *fp;
    fp = fopen(filename,"rt"); 
    if(fp==NULL)
    {
      printf("The file is wrong. \n");
    }

總體運行結果

總結和感想

  • 在碰到一個新問題的時候,焦慮和煩躁不能解決任何事情。靜下心來,定一份合理的計劃,循序地去學習新知識,最後完成任務的那一刻,你會頗有成就感,發現本身學到不少。
  • 計劃與實踐不能一律而論,但能夠做爲一個很好的參照。此次做業,原先制定的計劃與最後實際完成的結果有許多差異。照本宣科,是不可能很好地完成任務的。
  • 要熟練地運用搜索引擎,此次詢問同窗獲得的最多的答覆就是:百度啊。許多知識在互聯網上都能尋找到,而查閱資料和學習新事物的本領對咱們來講是必不可少的。要養成天天學習新東西的習慣。
  • 作事情,不能畏懼困難,在獲得比失去更多的狀況下,徹底能夠迎難而上。

附錄

剛剛發現我沒有git push,只是git add,所以代碼沒有上傳到倉庫裏面。
git push密碼輸錯,如今,,,
把代碼黏貼到這,證實趕過做業。學習

include "CharCount.h"
include<fstream>
include<iostream>

int CharCount(char * filename)
{
    int num = 0;
    char c;
    FILE *file;
    fopen_s(&file,filename, "rt");
    while (fgetc(file) != EOF) 
    {
        num++;
    }
    fclose(file);
    return num;

    
}
include "LineCount.h"
int LineCount(char * filename)
{
    FILE *file;
    fopen_s(&file,filename, "rt");
    int num = 0;
    char c;
    int flag = 0;

    while((c = fgetc(file)) != EOF) 
    {
        if (!isspace(c))   
        {
            flag = 1;
        }
        if (flag && c == '\n') 
        {
            flag = 0;
            num++;
        }
    }
    if (flag == 1) 
    {
        num++;
    }
    fclose(file);
    return num;
}
include"Word_Fre.h"


typedef pair<string, double> PAIR;
struct CmpByValue {
    bool operator()(const PAIR& lhs, const PAIR& rhs) {
        return lhs.second > rhs.second;
    }
};

int Word_Fre(char * filename)
{
    map<string, int> Word_Num_map;
    char ch;
    FILE *file;
    fopen_s(&file, filename, "rt");
    int flag = 0;           // 有窮自動機的斷定

    string word;
    while ((ch = fgetc(file)) != EOF)
    {
        if ('A' <= ch && ch <= 'Z')
            ch = ch + 32;
        switch (flag)
        {
        case 0: if (ch >= 'a'&&ch <= 'z') { flag++; word = word + ch; } break;
        case 1:
            if (ch >= 'a'&&ch <= 'z') { flag++; word = word + ch; }
            else { flag = 0; word = ""; }
            break;
        case 2:
            if (ch >= 'a'&&ch <= 'z') { flag++; word = word + ch; }
            else { flag = 0; word = ""; }
            break;
        case 3:
            if (ch >= 'a'&&ch <= 'z') { flag++; word = word + ch; }
            else { flag = 0; word = ""; }
            break;
        case 4:
            if (ch >= 'a'&&ch <= 'z' || (ch >= '0'&&ch <= '9')) { word = word + ch; }
            else {
                Word_Num_map[word]++;
                word = "";
                flag = 0;
            }
            break;
        }
    }

    if (flag == 4) {
        Word_Num_map[word]++;

    }


    if (flag == 4) {
        Word_Num_map[word]++;

    }


    vector <PAIR> Word_Num_vec(Word_Num_map.begin(), Word_Num_map.end());
    sort(Word_Num_vec.begin(), Word_Num_vec.end(), CmpByValue());
    /*
    for (int i = 0; i != Word_Num_vec.size(); ++i) {
        const char *ss = Word_Num_vec[i].first.c_str();

        cout << ss << ":" << Word_Num_vec[i].second << endl;
    }
    */
    ofstream outfile("result.txt", ios::app);
    if (Word_Num_vec.size() < 10)
        for (int i = 0; i != Word_Num_vec.size(); ++i)
        {
            const char *ss = Word_Num_vec[i].first.c_str();
            cout << "<" << ss << ">" << ": " << Word_Num_vec[i].second << endl;
            outfile << "<" << ss << ">" << ": " << Word_Num_vec[i].second << endl;
        }
    else
        for (int i = 0; i != 10; ++i)
        {
            const char *ss = Word_Num_vec[i].first.c_str();
            cout << "<" << ss << ">" << ": " << Word_Num_vec[i].second << endl;
            outfile << "<" << ss << ">" << ": " << Word_Num_vec[i].second << endl;
        }
    return 0;
}
// WordCount.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
include<string>
include<stdio.h>
include <iostream>
include <fstream>
include "CharCount.h"
include "LineCount.h"
include "Word_Fre.h"
include "WordNum.h"
using namespace std;

//int argc, char *argv[]
int main(int argc, char *argv[])
{
    if (argv[1] == NULL)
    {
        printf("The file is null");
        return -1;
    }
    
    int Char_Count = CharCount(argv[1]);
    int Lines_Count = LineCount(argv[1]);
    int Words_Count = WordNum(argv[1]);
    ofstream outfile("result.txt", ios::out);
    printf("characters: %d\n", Char_Count);
    printf("words: %d\n", Words_Count);
    printf("lines: %d\n", Lines_Count);
    outfile << "characters: " << Char_Count << endl;
    outfile << "words: " << Words_Count << endl;
    outfile << "lines: " << Lines_Count << endl;
    Word_Fre(argv[1]);

    
    return 0;
}
include"WordNum.h"


int WordNum(char * filename)
{
    map<string, int> Word_Num_map;
    char ch;
    FILE *file;
    fopen_s(&file, filename, "rt");
    int flag = 0;           // 有窮自動機的五個狀態是  0 1 2 3 4,其中4是終結狀態,0爲初始狀態
    int count = 0;
    
    while((ch = fgetc(file)) != EOF)
    {
        if ('A' <= ch && ch <= 'Z')
            ch = ch + 32;
        switch (flag) {
            case 0:
            if (ch >= 'a'&&ch <= 'z') { flag++; }
            break;
            case 1:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 2:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 3:
            if (ch >= 'a'&&ch <= 'z') { flag++;  }
            else { flag = 0;  }
            break;
            case 4:
            if (ch >= 'a'&&ch <= 'z' || (ch >= '0'&&ch <= '9')) { }
            else 
            {
                flag = 0;
                count++;
            }
            break;
        }
    }            /*flag */
    if (flag == 4) 
    {
        count++;
    }

    return count;
}
// pch.cpp: 與預編譯標頭對應的源文件;編譯成功所必需的

include "pch.h"

// 通常狀況下,忽略此文件,但若是你使用的是預編譯標頭,請保留它。
相關文章
相關標籤/搜索