第一次个人作业总结

要求

  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;

}

原文地址:https://www.cnblogs.com/wokeqty/p/8678058.html