福大软工1816 · 第二次作业

福大软工1816 · 第二次作业 - 个人项目

Github传送门

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 30
Estimate 估计这个任务需要多少时间 10 10
Development 开发 60 60
Analysis 需求分析 (包括学习新技术) 120 120
Design Spec 生成设计文档 30 30
Design Review 设计复审 30 30
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 30
Design 具体设计 30 30
Coding 具体编码 240 600
Code Review 代码复审 30 60
Test 测试(自我测试,修改代码,提交修改) 15 15
Reporting 报告 60 60
Test Repor 测试报告 10 10
Size Measurement 计算工作量 5 5
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 20 20
|       | 	合计  | 700|1110

解题思路

1.文件读写

既然是要从文件中读取单词并统计数量,并将它们按要求输出到指定的文件中,肯定要了解文件读写的过程和细节。主要用到的是C++的fstream类。

2.单词的统计

先将文件中的所有内容读入一个字符串,根据要求把他们分成各个单词,并判断单词是否符合要求,再把他们统一小写。如果符合要求,则将他们存入一个字典,如果在文本中重复出现一个单词,则它对应的个数+1。

3.行数的统计

忽略换行符、制表符等空白字符,进行行数统计。

实现过程

为了实现上述功能,我写了5个类

- Ascii    //用于统计字符以及行数
	int countAscii(string pth);			//计算总字符数
	int countLine(string pth);			//计算总行数
- Check    //用于检查字符和单词的有效性
	bool check_isChar(char s1);         //判断是否是字符
	bool check_isVal(char s1);          //判断是否是合法字符
	bool check(string str);             //判断是否是合法单词
	void testfile(string str);          //判断是否能够正确读入文件名并将之打开
- Word     //用于统计单词数量
    unordered_map<string, int> count_Word(string fname, unordered_map<string, int> strMap);        //统计单词并将他们存入字典
- Frequency    //用于统计所有单词的频率
	unordered_map<string, int> count_Frequency(string strTmp, unordered_map<string, int> strMap);        //统计单词频率并将它们存入字典
	void output_Frequency(string fname, unordered_map<string, int> strMap);     //按要求将前10的单词输出至文件
- File     //将结果输出至指定文本
    void file_output(string input_fname, string output_fname);

算法的关键

统计单词

	while (getline(file, str))      //读入文本内容
	{
		strfile.append(str);
		strfile.append(" ");
		str.clear();
	}
	for (int i = 0; i < strfile.length(); i++)
	{
		if (!mycheck.check_isVal(strfile[i]))
			strfile[i] = ' ';			 //符号位替换成为空格
	}
	transform(strfile.begin(), strfile.end(), strfile.begin(), ::tolower);
	istringstream stream(strfile);
	string word;
	while (stream >> word)          //从字节流中读取单词
	{
		if (mycheck.check(word))
		{
			strMap = myfrequence.count_Frequency(word, strMap);
		}
	}

用字典将有效的单词存起来,并根据要求写出排序的判断函数

typedef pair<string, int> PAIR;
unordered_map<string, int> strMap
static bool cmp_my_value(const PAIR& lhs, const PAIR& rhs)
{
	if (lhs.second != rhs.second)       //如果词频不一样,按照词频大优先
	{
		return lhs.second > rhs.second;     
	}
	else                                //如果词频一样,按照字典序优先
	{
		return lhs.first < rhs.first;
	}
}
unordered_map<string, int> Frequence::count_Frequency(string strTmp, unordered_map<string, int> strMap)
{
	unordered_map<string, int>::iterator it = strMap.find(strTmp);
	if (it == strMap.end()) //strMap中如果不存在当前单词则插入一个新键值对,出现频率为1
	{
		strMap.insert(unordered_map<string, int>::value_type(strTmp, 1));
	}
	else                   //如果存在则出现频率+1
		strMap[strTmp]++;
	return strMap;
}

计算模块接口部分的性能

计算模块部分单元测试(部分)

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../WordCount/CountAscii.h"
#include "../WordCount/CountWords.h"
#include "../WordCount/File.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace CountAsciiTest		//用于对字符数量的统计
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestMethod1)
		{
			// TODO: 在此输入测试代码
			Ascii test_ascii;
			int count = test_ascii.countAscii("countascii.txt");
			Assert::IsTrue(count == 28);
		}

	};
}
namespace CountLineTest			//用于测试对空白行的技术
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestMethod1)
		{
			// TODO: 在此输入测试代码
			Ascii test_ascii;
			int count = test_ascii.countLine("countline.txt");
			Assert::IsTrue(count == 0);
		}

	};
}

namespace FileTest		//用于对空文件名的测试
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestMethod1)
		{
			// TODO: 在此输入测试代码
			Ascii test_ascii;
			int count = test_ascii.countAscii("1.txt");
			Assert::IsTrue(count == 0);
		}

	};
}

代码覆盖率


代码覆盖率为87%

异常处理说明

在文件读入失败的时候,会出现提示。

	if (!file)
	{
		cout << "不存在这个文件或者文件未打开,请重新输入!" << endl;
		exit(0);
	}

作业心得

  • 由于上半年都在使用python编程,对C++的编程已经有些生疏,有时甚至会忘记定义变量类型。导致编码速度较慢。
  • 没有比较合理安排项目时间,导致时间有些紧张,以至于有些代码可读性不是很好。
  • 在编码之前仔细地构想该如何实现,确实可以提高编码效率。
原文地址:https://www.cnblogs.com/leolkx/p/9637801.html