软件工程

---恢复内容开始---

我的github  https://github.com/lcxyj1231/WordCount
合作伙伴 吕东
合作伙伴学号 201831061228
合作伙伴博客地址  
 https://www.cnblogs.com/aaddvvaanntteezz/ 

1.预计时间PSP

一、PSP表格 

(1)PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 

 

· Estimate

· 估计这个任务需要多少时间

 600

 670

Development

开发

 150

 180

· Analysis

· 需求分析 (包括学习新技术)

 60

 90

· Design Spec

· 生成设计文档

 30

 30

· Design Review

· 设计复审 (和同事审核设计文档)

 30

 30

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 30

 30

· Design

· 具体设计

 30

 20

· Coding

· 具体编码

 120

 180

· Code Review

· 代码复审

 30

 30

· Test

· 测试(自我测试,修改代码,提交修改)

 60

 40

Reporting

报告

 20

 20

· Test Report

· 测试报告

 10

 10

· Size Measurement

· 计算工作量

 20

 20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10

 10

 

合计

 600

 670

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 二.代码设计思路及工作分配

我们两个人采用C++来完成

 

初始版本:

刚开始写一些,代码开胃,并熟悉了一下项目需求,初始版本只完成了 字符统计,单词数量统计,有效行数统计,单词的词频统计。

 

代码分工:同伴敲代码,我提供设计思路和检查错误。

初始版本:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
char s[maxn][maxn];
bool judge(string a)
{
    if(a.size()<4)return false;
    for(int i = 0;i < 4;++i)
    {
        if(a[i]>='0'&&a[i]<='9')return false;
    }
    return true;
}
int main()
{
    vector<string>v;
    map<string,int>mp;
    freopen("Test.txt","r",stdin);
    int now=0;
    int cntword=0;
    int cntline=0;
    while(gets(s[now++]));
    for(int i = 0;i < now;++i)
    {
        int m=strlen(s[now]);
        for(int j = 0;s[i][j];++j)
        if(0<=s[i][j]&&s[i][j]<=127)cntword++;
    }
    string tmp;
    for(int i = 0;i < now;++i)
    {
        bool ok=false;
        for(int j = 0;s[i][j];++j)
        {
            if(s[i][j]!=' ')ok=true;
            if('0'<=s[i][j]&&s[i][j]<='9'||'A'<=s[i][j]&&s[i][j]<='Z'||'a'<=s[i][j]&&s[i][j]<='z')
            tmp+=s[i][j];
            else{
                if(tmp.size())
                v.push_back(tmp);
                tmp.clear();
            }
        }
        cntline+=ok;
    }
    for(int i = 0;i<v.size();++i)
    {
        if(judge(v[i]))
            mp[v[i]]++;
    }
    printf("        characters: %d\n",cntword);
    printf("        words: %d\n",mp.size());
    printf("        lines: %d\n",cntline);
    map<string,int>::iterator ite;
    for(ite=mp.begin();ite!=mp.end();++ite)
    cout<<"        "<<ite->first<<':'<<ite->second<<endl;
    return 0;
}

核心技术主要是map。

 

接口封装:

 

一共分三大类:

1.功能实现类

  完成该工作的主流功能

    (1)统计字符数

    (2)统计单词输

    (3)统计各个单词出现的频率

    (4)排序后写入文件的功能

    (5)统计有效行数

2.命令语句转化类

    (1)-m操作:统计的词组长度

    (2) -n操作:参数设定输出的单词数量

    (3) -i操作:参数设定读入的文件路径

    (4) -o操作:参数设定生成文件的存储路径

    (5)多功能的混合使用

3.测试类

    (1)完成单元测试,已检测函数的正确性

    (2) 特例测试,以排除一些异常

 

 

思维导图:

 

 

代码分工:我主要完成命令语句转化类,同伴主要完成功能实现类。

 

我们的核心技术:

1.

class Function
{
    public:
    void Inputstring(char *ss);//获取读入文件的数据
    int Countcharactor();//字符统计
    int Countline();//行数统计
    map<string,int> cntwords();//词频统计
    bool judge(string a);//判断单词
    map<string,int> Countwords2(int m) ;//存放词组数量
    private:
    char s[1005][1005];//存放文件内容
    int realine;
};
  • Information Hiding 
  • Interface Design
  • Loose Coupling     

  其实这三者的共同目的或诉求就是:通过对接口进行设计,来保证类与类之间的隐私性、独立性,使属性不会过度共享(暴露),使对象的信息不可直接访问,

而是要调用方法,从而保证对象的安全性

  我们的核心技术还是map,因为map是一个非常强大的stl用法,既可以统计单词总数,还可以分开统计各个单词的词频,还能直接找出wordsize,非常的方便,

在类和类的交互过程中,map直接作为参数传递,使得程序简洁完善。信息也会得到安全的保障和传递,外部也不可以直接访问map。我的搭档C++应用也非常熟

练,我们功能设计完成的很快。

 

 

代码互审:


我们的代码写完开始交互,发现了许多问题,但是很快就将他们解决了:

1.文件错误

 freopen(ss,"r",stdin);

这个打开文件读取的函数,参数文件名必须是char *类型,而我传递的是string类,产生了未知错误,最后调试了一番得到解决。

 

2.我的命令读取和识别与他的功能函数产生冲突,最后我们不得制定了统一的输入标准,这样一来,命令转化类也可以轻松找到功能函数

这就是我们统一制定的规范

   //wordcnt -m 3 -i [filename] -o [filename]为统计文本出现次数前3的单词,并且按字典序输出到文件,也可以输出到控制台。
    //wordscnt -m 3 -i [filename] -o [filename]为为统计文本词组长度为3的词组及个数,并且输出到文件,也可以输出到控制台。
    //cntcharacter -i [filename] 为统计文本出现字符个数
    //cntline -i [filename] 为统计文本真实行数
    //输入exit结束交互

 

虽然有些局限性,但是效率也得到了提高

 

三:性能测试及改进,单元测试及异常处理

 单元测试和异常处理:

对每个函数进行单元测试,发现以下几个问题:

1.读取文件的函数 

 

 使用fgets读入字符串时会读入换行符,产生错误,于是将函数改为使用fgets读入字符串时会读入换行
正确代码:
void Inputstring(char* ss)
    {
        FILE* stream1;
        freopen_s(&stream1,ss, "r", stdin);
        realine = 0;
        while (fgets(s[realine ++], 1000, stdin))
        {
            int n = strlen(s[realine - 1]);
            s[realine - 1][n - 1] = '\0';
        }
        fclose(stdin);
        freopen_s(&stream1,"CON", "r", stdin);
};

 

2.getsize()函数发生错误:

getsize的功能是获取“-m”后面的数字

由于在计算个数时没有对两位及以上的数进行处理于是出现了以上错误,然后添加了修改了getsize函数

错误结果:

 

修改代码后:

int getsize(string a)
    {
        int pos = a.find("-m");
        int ans = 0;
        for (int j = pos + 3;; ++j)
        {
            if (a[j] == ' ')
                break;
            ans = ans * 10 + a[j] - '0';
        }
        return ans;
    }

 

 

性能测试:

 

 

分析性能:主要是由于fgets函数效率极低,引起读取文件速度缓慢,由于所学知识有限,无法修改

 

所有功能运行截图:

 

四:结对过程

 

 

这次的结对编程我初期遇到很大的困难,主要是因为我是学java的,但我找不到队友,最后只能用C++,而我的C++水平属于半调子。好在我的搭档C++水平还不

错,最后难题得到了解决,这次作业我还是主要负责的设计工作,而我的搭档主要负责代码,我们共同努力,知识互补,C++里面许多新的知识我们也在边做作业学

习。面向对象的设计方式也得到一系列的锻炼。虽然这个作业很烧脑筋,但我也感觉学到了很多东西,由于我的搭档是为室友,我们也能很好地随时交流。出现的问

题也解决得很快。

结对照片:

 

posted @ 2019-10-12 21:00  ****l****  阅读(162)  评论(0编辑  收藏  举报