• 第一次个人作业总结


    要求

    1. 对源文件(*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等)统计字符数、单词数、行数、词频,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。
    2. 使用性能测试工具进行分析,找到性能的瓶颈并改进
    3. 对代码进行质量分析,消除所有警告
    4. 设计10个测试样例用于测试,确保程序正常运行(例如:空文件,只包含一个词的文件,只有一行的文件,典型文件等等)
    5. 使用Github进行代码管理
    6. 撰写博客

    基本功能

    1. 统计文件的字符数
    2. 统计文件的单词总数
    3. 统计文件的总行数
    4. 统计文件中各单词的出现次数
    5. 对给定文件夹及其递归子文件夹下的所有文件进行统计
    6. 统计两个单词(词组)在一起的频率,输出频率最高的前10个。

    在Linux系统下,进行性能分析,过程写到blog中

    首先给出PSP表格:

    项目进度                                                           预计耗时       实际耗时

    分析题目,确定大体思路                                    1h                    2.5h

    (包括编程工具,语言等)

    实现单个文件中字符,行数,单词的读取              1h                    3h

    由于vs2017临时崩盘,改换vs2013并                 0h                    2.5h

    重新配置开发环境

    实现遍历根目录下所有文件                              3h                    7h

    实现对单词数目的统计                                     3h                    10h

    实现对词组的统计                                            5h                    6h

    整体测试                                                          10h                   …

    总计                                                                  23h                  31h

    由于周末一直在忙着写作业,直到周一晚上才开始着手进行代码的实现,首先来分析一下各部分的完成情况:

    1、         对单个文件字符,行数,单词数的统计。

    这个应该是最容易完成的项目了,直接通过对文件的单个字符进行读取和判断,即可实现,由于秉承单元测试的想法,在完成和测试上一共花费约2.5h。(周一晚)

    2、         由于以前一直使用devil C 进行编程,首次使用vs十分不习惯,由于电脑是windows 7系统,无法进行预处理命令,于是悲摧的又下载了vs2013,而vs2013居然没有汉化包,只能通过英文版进行调试。在网上查了很久才搞清楚预处理命令在哪里改。

    3、         接下来要实现的是遍历所有文件,花了2个多小时在网上搜了四五种代码,却发现没有一个是可以真正拿来用的,不是文件打开失败就是只能读取目录下的第一个文件。

    只知道使用 firstfile函数打开,在经历了数小时尝试无果的情况下问了同小组的成员,于是得到了一下模板:

    void GetAllFiles(string path, vector<string>& files)
    {
    long  handle = 0;  // File Handle
    struct _finddata_t fileinfo;  // File Information
    string p;
    char * location;  // location converts char * into string

    if ((handle = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
    {
    do
    {
    if ((fileinfo.attrib & _A_SUBDIR))  // to check whether it is a folder or a file
    {
    if (strcmp(                         fileinfo.name, ".") != 0 && strcmp( fileinfo.name, "..") != 0)
    {
    files.push_back(p.assign(path).append("\\").append( fileinfo.name));
    GetAllFiles(p.assign(path).append("\\").append( fileinfo.name), files);
    }
    }
    else
    {
    files.push_back(p.assign(path).append("\\").append( fileinfo.name));
    location = (char *)p.data();
    //printf("%s\n",  fileinfo.name);
    //OpenFile(location);
    //getchar();
    }
    } while (_findnext(handle, &fileinfo) == 0);
    _findclose(handle);
    }
    }

    看了一下之后发现基本没有会用的,百度之后才明白vector是一个存放文件名的容器。在此函数的基础上进行改动最终实现文件夹的遍历。

    4、         满心欢喜的写完了文件遍历的代码,将老师给的测试集打开进行整个文件夹的字符数,行数,单词数的统计,结果运行到一半时就崩了,一脸无奈的进行调试后发现是由于某些文件打开失败,大概有二十个左右。最后同组的同学告诉我可能是上面的那个函数有一行写的不合理,将那一行注释掉了之后问题依然没有完全解决,然而时间以经过去两天了。

    5、         心情复杂的开始写单词的统计,刚开始的时候居然毫无思路,自己最初的想法是遍历所有字符,遇到连着4个以上的单词就存入结构体中,并创建链表。而实际操作过程中却发现一是这样遍历不好统计没个单词的数目,二是时间消耗非常严重。经同组同学提醒,应当使用哈希表来进行存储。而哈希表的知识我已经基本遗忘,于是花了大约1.5h补一下哈希表的内容。

    6、         发现C本身自带的map根本不会使用,于是自己开始写哈希表,而此时DDL只有不到半天,勉强写好了哈希函数,放到全是文本文件的文件夹中测试时直接崩掉。由于对VS的DEBUG功能极其不熟悉,导致很久也没能找出问题所在。于是不得已进行逐行调试,在经历大约2小时的测试过程后终于发现是由于部分文件打开失败造成的,在全部换成可打开的文件后却发现统计的单词和数目根本不对,而DDL只剩下2个小时了,于是心态爆炸的写了命令行参数和输出文件后提交了。

    7、         由于基本功能中的词组统计依然没有实现,因此没有进行性能分析和优化处理,也没有进行Linux系统下的分析。

    经验总结:

    1、         对VS开发环境极其不熟悉,不知道如何进行有效的DEBUG

    2、         对于基本的数据结构知识有所遗忘,比如在创建链表的过程中出现了很多BUG,在打开文件时出现了打开失败的情况。

    3、         不能及时的于其他人进行交流,一味的埋头苦弄,导致效率极其低下,比如说其实只需2小时就可以解决的文件遍历问题居然做了整整一天。

    最后,附上已经实现功能的代码:

     

     

    // ConsoleApplication4.cpp : Defines the entry point for the console application.

    #include "stdafx.h"

    #include<stdio.h>

    #include<stdlib.h>

    #include<math.h>

    #include<string>

    #include<io.h>

    #include"targetver.h"

    #include<fstream>

    #include<vector>

    #include<iostream>

    #include<tchar.h>

    #include<numeric>

    #include<functional>

    #include<unordered_map>

    using namespace std;

    int  char_num = 0, line_num = 1, word_num = 0;

    #define lnode struct node

    struct node {

        int num;

        char word[200];

        struct node* next;

    };

     

    void GetAllFiles(string path, vector<string>& files,int &char_num,int &line_num,int &word_num)

    {

        FILE *f1 =NULL;

        int count = 0, i = 0;

        long  handle = 0;  // File Handle

        struct _finddata_t fileinfo;  // File Information

        string p;

        char * location;  // location converts char * into string

        char code;

        if ((handle = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)

        {

            do

            {

                if ((fileinfo.attrib & _A_SUBDIR))  // to check whether it is a folder or a file

                {

                    if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)

                    {

                        //files.push_back(p.assign(path).append("\\").append(fileinfo.name));

                        GetAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, char_num, line_num, word_num);

                    }

                }

                else

                {

                    files.push_back(p.assign(path).append("\\").append(fileinfo.name));

                    location = (char *)p.data();

                    f1 = fopen(location, "r");

                    if (!f1) printf("%s\n", location);

                    if (f1) {

                        while ((code = fgetc(f1)) != EOF){

                            if (code >= 32 && code <= 126) char_num++;

                            if (code == '\n')

                                line_num++;

                            if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)){

                                count++;

                            }

     

                            else {

                                if (count >= 4){

                                    word_num++;

                                    count = 0;

                                }

                                else count = 0;

                            }

     

                        }

                    }

     

                }

            } while (_findnext(handle, &fileinfo) == 0);

            _findclose(handle);

        }

    }

    int main(){

       

        FILE  *f2;

        char * DATA_DIR = __argv[1], *s1 = "characters:",*s2="lines:",*s3="words:";

        vector < string > files;

        GetAllFiles(DATA_DIR, files, char_num, line_num, word_num);

        printf("%d %d %d\n", char_num, line_num, word_num);

        f2 = fopen("result.txt", "w");

        if (!f2) printf("ERROR");

        if (f2) {

            fputs(s1, f2);

            fprintf(f2,"%d",char_num);

            fputc('\n', f2);

            fputs(s2, f2);

            fprintf(f2, "%d", line_num);

            fputc('\n', f2);

            fputs(s3, f2);

            fprintf(f2, "%d", word_num);

        }

        system("pause");

        return 0;

    }

  • 相关阅读:
    [asp.net] 网页自动刷新总结
    内容页中修改母版页内容
    [asp.net] 页面传值方法小记
    [VSS2005] 源代码管理bin文件夹里的.dll总是被签出,不能同时编译解决办法
    [asp.net] 设置与获取CheckBoxList多选的值
    [转] asp.net中repeater按钮传值与分页
    [asp.net] 验证控件的属性及用法
    [asp.net] 格式化repeater字段显示
    VPS绑定中文域名方法
    M/T法测速经典解析(转)
  • 原文地址:https://www.cnblogs.com/wokeqty/p/8678058.html
Copyright © 2020-2023  润新知