今天是新生周的最后一天,意味着自己班级里的小朋友的接触也要告一段落了。心中也有那么一丝丝的不舍。好在自己终于完成了软工的第二次作业,也算是给自己一个安慰吧。开学的这一周让我知道了,软工实践是如何“充实”自己的大学生活的。在这里也要感谢一下班里的陈俞辛、董钧昊、蔡宇航同学,感谢他们在我遇到问题的时候给予我的帮助!
本次博客的格式也是参考了赵畅同学的博客。
psp2.1 | personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 50 |
Estimate | 估计这个任务需要多少时间 | 1000 | 1680 |
Development | 开发 | 180 | 70 |
Analysis | 需求分析(包括学习新技术) | 180 | 150 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 20 | 15 |
Coding Standrd | 代码规范(为目前的开发制定合适的规范) | 15 | 10 |
Design | 具体设计 | 30 | 25 |
Coding | 具体编辑 | 150 | 250 |
Code Review | 代码复审 | 30 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 40 |
Reporting | 报告 | 60 | 50 |
Test Repor | 测试报告 | 20 | 15 |
Size Measurement | 计算工作量 | 30 | 20 |
Postmortem&Process Improvement Plan | 事后总结,并提出过程改进计划 | 20 | 15 |
- | 合计 | 665 | 710 |
统计字符数:只需要统计Ascii码,汉字不需考虑,
空格,水平制表符,换行符,均算字符。
fstream
对象来打开文件,使用get()
方法来获取字符,用eof()
方法来判断文件是否已经读完。fstream
的使用参见:参考博客一cnt
自增加一,并定义一个string
变量来存储==该文件中的所有字符。==统计文件的有效行数:任何包含非空白字符的行,都需要统计。
\n
,但是==检测到到换行符不代表就是有效行,没有换行符也不代表不是有效行。==flag
变量,检测到有效字符置flag
为1,否则置0,然后对文档的所有字符进行扫描。flag
为1且检测到换行符,行数加一。扫描完整个文件后,检测flag
的值,如果为1,代表最后一行是“没有换行符的”有效行,行数自增加一。统计文件的单词总数,单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。
struct node {
string name;//名
int times;//出现频次
node *next;
node(string n, int number)
{
name = n;
times = number;
next = NULL;
}
};
name
用来存放单词字符,times
用来存放出现次数,next
用来连接节点,实现开散列。int hash = ((w[0] - 96)) + ((w[1] - 96) * 26) + ((w[2] - 96) * 26 * 26);
insert()
,当该单词的哈希值对应的散列单元存在节点,则插入到该单元下的链表中,并使times++
。times
最大的一个节点,并将它删除。得益于散列函数,不必排序。char_counter
:
int char_count();
:负责统计字符数。file
:负责存储文件的相关信息,比如文件名,文件中的所有字符。line_counter
:
int lines_counter();
:统计有效行数word_operater
:
void insert();
:单词插入哈希表。int words_counter();
:统计单词数。void file_rank();
:负责统计词频。031602523
|- src
|-WordCount.sln
|-WordCount
|-Char_counter.cpp
|-Line_counter.cpp
|-Word_operater.cpp
|-main.cpp
|-char_cnt.h
|-file.h
|-line_cnt.h
|-pre.h
|-word_op.h
|-stdafx.h
|-targetver.h
|-stdafx.cpp
|-unittest1.cpp
int Word_operater::words_counter(ifstream &f, Files &fn)
{
int flag = 0;
string thisword = "";
string temp = fn.get_alstring();
int len = temp.length();
int cnt = 0;
for (int i = 0; i < len; i++)
{
if ((temp[i] >= 65 && temp[i] <= 90) || (temp[i] >= 97 && temp[i] <= 122))//找到第一个字母 判断是不是单词
{
flag = 0;
for (int j = i; j <= i + 3; j++)
{
if (temp[j] <= 64 || (temp[j] >= 91 && temp[j] <= 96) || temp[j] >= 123 || len - i < 4)
{
flag = 1;
break;
}
}
if (flag == 0)//如果是单词就提取单词到thisword
{
thisword = "";
for (; i < len && ((temp[i] >= 65 && temp[i] <= 90) || (temp[i] >= 97 && temp[i] <= 122) || (temp[i] >= 48 && temp[i] <= 57)); i++)
{
if (temp[i] >= 65 && temp[i] <= 90)
temp[i] += 32;
thisword += temp[i];
}
cnt++;
insert(thisword);
}
else//如果不是单词就跳到下一个单词的第一个字母
{
for (; (temp[i] >= 65 && temp[i] <= 90) || (temp[i] >= 97 && temp[i] <= 122) || (temp[i] >= 48 && temp[i] <= 57); i++) {}
}
}
else if (temp[i] >= 48 && temp[i] <= 57)
{
for (; (temp[i] >= 65 && temp[i] <= 90) || (temp[i] >= 97 && temp[i] <= 122) || (temp[i] >= 48 && temp[i] <= 57); i++) {}
}
}
fn.set_alstring(temp);
return cnt;
}
void Word_operater::file_rank(Files &fn, Word_operater &wn, ofstream &outfile)//统计词频
{
int num;
int flag = 0;//判断出现次数最大的结点是不是表首 0不是 1是
node *max, *q, *p, *front_max;
front_max = new node("", 0);
for (int j = 0; j < 10 && j < wn.get_wrdcnt(); j++)//遍历10次哈希表
{
max = new node("", 0);//初始化max
for (int i = 0; i <= 18279; i++)
{
if (this->hash_table[i]->next == NULL) continue;//空表跳过
else//非空表
{
q = p = this->hash_table[i];
while (p->next != NULL)
{
if (p->times > max->times || (p->times == max->times&&p->name < max->name))
{
if (p == this->hash_table[i])
{
flag = 1;//表示该单词在表头
num = i;
}
else flag = 0;//表示该单词在表中
max = p;
front_max = q;
}
q = p;
p = p->next;
}
}
}
if (max->times != 0)
{
//cout << "<" << max->name << ">:" << max->times << endl;//输出一个结果
wn.word_times[j] = max->times;
wn.word_str[j] = max->name;
//cout << wn.word_times[j] << " " << wn.word_str[j] << endl;
outfile << "<" << max->name << ">:" << max->times << endl;//输出一个结果
}
else break;//如果max没有被替换,则此时哈希表是空的,不需要输出
if (flag == 1) this->hash_table[num] = max->next;//如果频次最大的单词在表首,替换表首指针
else front_max->next = max->next;//如果频次最大的单词在表中,删除结点
}
return;
}
vs
的一些功能。 TEST_METHOD(TestMethod1)
{
ifstream f;
Files file_input;
int u = 1;
Char_counter cc;
Line_counter lc;
Word_operater wo;
ofstream outfile;
string std[10];
int std1[10];
int a, b, c;
file_input.set_filename("input1.txt");
f.open("input1.txt", ios::in);
if (!f.is_open())
{
cout << "Warning! can‘t open this file!" << endl;
}
a = cc.char_count(f, file_input);
b = lc.lines_counter(f, file_input);
c = wo.words_counter(f, file_input);
cc.set_chrcnt(a);
lc.set_lnecnt(b);
wo.set_wrdcnt(c);
wo.file_rank(file_input, wo, outfile);
Assert::AreEqual(1560, a);
Assert::AreEqual(29, b);
Assert::AreEqual(98, c);
std[0] = "gwsw9c4";
std[1] = "iqbl9b8";
std[2] = "jrim";
std[3] = "bvjb";
std[4] = "dfcmb7";
std[5] = "does9x";
std[6] = "eshwh6";
std[7] = "gkcu";
std[8] = "jawe5jh";
std[9] = "jseb50l";
std1[0] = 9;
std1[1] = 6;
std1[2] = 6;
std1[3] = 5;
std1[4] = 4;
std1[5] = 4;
std1[6] = 4;
std1[7] = 4;
std1[8] = 3;
std1[9] = 3;
//int *p1 = wo.get_w_times();
//string *p2 = wo.get_word_str();
for (int i = 0; i < 10; i++)
{
Assert::AreEqual(std[i],wo.word_str[i]);
Assert::AreEqual(std1[i], wo.word_times[i]);
}
//Assert::AreEqual(1560, a);
//Assert::AreEqual(29, b);
//Assert::AreEqual(98, c);
}
};
95%
.VS
这个“宇宙第一ide”,以前觉得VS
与dev-c++
没事么不同,这样用来才发现其中的不同。原文:https://www.cnblogs.com/031602523liu/p/9637153.html