作业要求博客地址:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2110

git仓库地址:https://git.coding.net/pipifan/wf.git

PSP阶段:

 

PSP阶段

所花时间百分比(607 / min)

预计所花时间(440/min)

计划

43

40

·明确需求和其他相关因素,估计每段时间成本

43

40

开发

509

360

·需求分析

35

40

·生成设计文档

26

30

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

40

20

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

28

30

·具体设计

功能一

18

10

功能二

18

10

功能三

16

10

·具体编码

功能一

58

40

功能二

90

50

功能三

75

60

·代码复审

47

20

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

50

40

报告

55

40

·测试报告

8

15

·事后总结

47

25

//具体时间已修改,因为有一天的零散时间忘记算了

分析原因:主要的差距在于具体编码技术、写代码的工程习惯和工程思想。

其一、这次写PSP阶段分析是我的第一次尝试,这次让我认识了在项目中,写代码只是众多核心部分之一,文档分析,测试数据都是不可或缺的一部分。

其二、在单元测试方面自己还没有养成良好的习惯,没有做到书中的全路径覆盖等等,这也让我意识到做好一个软件是一个庞大的项目。

改进方法:自己还需多多锻炼代码能力,养成写代码的工程思想。

从项目中获得的经验

  一开始看到这个需求,我感觉最大的难点还是在于对文件路径的操作。做这个项目之前,虽然我已经有一定的编程基础,但仅限于ACM那种即时编写,即时运行,并有给好的输入数据。这次从输入的不同,判断输入的是文件路径还是文件名,对我是一种全新的尝试,我从中学会了很多东西。

  比如:一、通过(struct _finddata_t fileinfo)这个结构,存储有关文件的信息,并通过(fileinfo.attrib & _A_SUBDIR)这种判定方法确定该文件否为目录,还可以通过递归的算法,找到所有的文件名。

     二、通过ifstream读入文件,并以文件中的字符串流形式输入。

重点代码展示

这一段代码是我从网上找到的,虽然不是我自己写的,但我觉得这一段非常值得我学习,这里面有很多我觉得很重要的知识点都是我之前没掌握的

这一段的功能是:已知一个文件路径,读入该路径下的所有文件

void get_all_file(string path , vector<string>& files , string format)//DFS找到该文件下所有文件名并放入VECTOR中
{
    long hFile = 0;//句柄
    struct _finddata_t fileinfo;
    string p;
    if( ( hFile = _findfirst( p.assign( path ).append("\\*" + format).c_str() , &fileinfo ) )  != -1 )
    {
        do
        {
            if( fileinfo.attrib & _A_SUBDIR ){//是否为目录
                if( strcmp( fileinfo.name , "." ) != 0 && strcmp( fileinfo.name , ".."  ) != 0 )//若文件名不是当前文件夹或父文件夹
                    get_all_file( p.assign(path).append("\\").append(fileinfo.name), files , format );//继续迭代搜索所有文件夹名
            }
            else
                files.push_back( p.assign( fileinfo.name ) );

        }while( _findnext( hFile , &fileinfo ) == 0 );//找下一个符合条件的文件夹
        _findclose(hFile);
    }
}

这一段代码是计算单词频率的算法部分,是我认为最精华的一部分,我通过两个map容器,一个结构体,完成了对文件名和文件路径两种不同输入方式的排序。

若单词数目为n,本算法的时间复杂度为O(nlogn)。在时间上这么优化主要多亏了map容器,让我在插入一对pair的时候把时间复杂度缩减到log级别,并且因为最后的sort也是

O(nlogn)级别的,所以整体的时间复杂度为O(nlogn)

void solve( string input_str , string s , bool have_Path , bool have_File )//计算单词频数
{
    map<string , ll> mp,id;
    string str = "" , tmp = "";
    read_txt( s , str );
    int file_num , cnt = 1;
    bool limit = Get_num( input_str , file_num );
    for( auto ch : str ){
        if( ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' ){
            tmp += ch;
            continue;
        }
        if( !tmp.empty() ){
            if( tmp[0] >= 'a' && tmp[0] <= 'z' ){
                mp[tmp]++;//mp存当前字符串出现的频数
                if( !id.count(tmp) )
                    id[tmp] = cnt++;//id存当前字符串出现的顺序
            }
            tmp = "";
        }
    }
    if( !tmp.empty() ){
        if( tmp[0] >= 'a' && tmp[0] <= 'z' )
            mp[tmp]++;
        tmp = "";
    }
    if( !limit ){
        cout<<"total "<<mp.size()<<endl;
        puts("");
        vector<node> v;
        if( have_File ){//若给出的是文件名,则按出现顺序排序
            for( auto it : mp )
                v.push_back( node{ it.first , it.second , id[it.first] } );
            sort( v.begin() , v.end() );
            for( auto it : v ){
                 cout<<left<<setw(30)<<it.word<<it.num<<endl;
            }
        }
        else{//若给出的是文件路径,则按字典序排序
            for( auto it : mp ){
                 cout<<left<<setw(30)<<it.first<<it.second<<endl;
            }
        }
    }
    else{//否则按出现频数从大到小排序
        cout<<"Total words is "<<mp.size()<<endl;
        puts("------------------");
        vector<psl> vec( mp.begin() , mp.end() );
        sort( vec.begin() , vec.end() , cmp() );
        for( auto it : vec ){
            cout<<left<<setw(30)<<it.first<<it.second<<endl;
            file_num--;
            if( !file_num )
                break;
        }
    }
}

测试数据:

功能一:

功能二:

功能三:

不足之处:

  这个代码其实是有BUG的,只不过我没解决:

    第一:当文件路径中含有空格时,我读到一半就会跳出,因为我是利用空格作为文件名的分隔符,因此这里会有漏洞。

    第二:当输入不规范时,我程序会报错,因为我是默认-f的-后第三个字符,为有效字符串的起始点,此时若多加几个空格我的读入就会出错,程序也会因此报错。

 

posted on 2018-09-20 20:13  电竞热干面  阅读(239)  评论(0编辑  收藏  举报