软工1816 · 团队现场编程实战(抽奖系统)
队名:起床一起肝活队
组长博客:博客链接
作业博客:班级博客本次作业的链接
一、组员职责分工
组员 | 职责 |
---|---|
白晨曦 | 任务分配,过滤算法 |
乐忠豪 | 完成抽奖功能 |
蔡子阳 | 完成文案生成与qqbot |
黄培鑫 | 完成抽奖结果图片生成 |
李麒 | 完成界面制作与功能对接 |
王焕仁 | 协助完成过滤算法 |
陈德斌 | 协助完成界面的制作,博客书写 |
林志华 | 过滤算法设计 |
何裕捷 | 抽奖结果的图片显示 |
二、github 的提交日志截图
三、程序运行截图
1.程序界面
2.抽奖系统
输入文本:
输出结果:
3.高级过滤功能
4.发送通知
四、程序运行环境
环境 | 名称 |
---|---|
操作系统 | windows10 |
编译器 | visual studio |
五、GUI界面
六、基础功能实现
抽奖系统
基本思路:
对每条记录进行词条化处理,赋予每个参与抽奖的人一定范围的中奖码(如:10-20是张三中奖),通过控制范围改变一些参与者的中奖概率,再通过产生随机数的方式获得中奖号码,输出相应参与者的信息
代码实现:
// Dll1.cpp: 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include <stdexcept>
#include<iostream>
#include<stdlib.h>
#include<ctime>
#include<fstream>
#include <cstdlib>
#include<string>
#include <sstream>
#include<vector>
#include "DLL1.h"
using namespace std;
class people1 {
public:
string name;
string QQ;
int cs;
int zongzishu;
int zhongjiangdown;
int zhongjiangup;
};
people1 p[2000];
void choujiang(string filename,int pnum)
{
char word[1000];
string a;
ifstream in(filename);
int num = 0;
int k = 0;
while (in.getline(word, 1000))
{
a = word;
string b = "";
vector<string> res;
//暂存从word中读取的字符串
string result;
//将字符串读到input中
stringstream input(a);
//依次输出到result中,并存入res中
while (input >> result)
res.push_back(result);
//输出res
p[k].name = res[0];
p[k].QQ = res[1];
if (k <= 30 && k != 0)
{
p[k].zhongjiangdown = p[k - 1].zhongjiangup + 1;
p[k].zhongjiangup = p[k].zhongjiangdown + 9;
}
else if (k == 0)
{
p[k].zhongjiangdown = 0;
p[k].zhongjiangup = p[k].zhongjiangdown + 9;
}
else {
p[k].zhongjiangdown = p[k - 1].zhongjiangup + 1;
p[k].zhongjiangup = p[k].zhongjiangdown + 1;
}
k++;
}
int jieguo = 0;
int ss = 0;
srand(time(0));
ofstream fout("final.txt");
for (int s = 0; s < pnum; )
{
if (k <= 30)
jieguo = rand() % (k * 10 - 1);
else
jieguo = rand() % (k + 269);
for (int i = 0; i < k; i++)
{
if (jieguo <= p[i].zhongjiangup && jieguo >= p[i].zhongjiangdown)
{
fout << "恭喜 " << p[i].name << " (" << p[i].QQ << ") " << "中奖!" << endl;
p[i].zhongjiangup = 65535;
p[i].zhongjiangdown = 65535;
s++;
}
}
}
fout.close();
}
过滤系统
代码实现:
#include "pch.h"
bool QWE_fenxi::cmp(qwe a,qwe b){
return a.zs>b.zs;
}
string QWE_fenxi::UTF8ToGB(const char* str) {
string result;
WCHAR *strSrc;
LPSTR szRes;
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
bool QWE_fenxi::qgetline(char s[]){
if( fgets(s,1024,fp) ){
return true;
}
return false;
}
void QWE_fenxi::getfayan(int i){
string name="",qq="";
int zs=0,len=strlen(qLine[1]);
for(int j=len-1;j>=0&&qLine[1][j]!='#';j--){
zs++;
}
for(i=i+1;qLine[0][i]!='('&&qLine[0][i]!='<';i++){
name+=qLine[0][i];
}
for(i=i+1;qLine[0][i]!=')'&&qLine[0][i]!='>';i++){
qq+=qLine[0][i];
}
if (name == "系统消息")return;
qq_name[qq]=name;
qq_cs[qq]++;
qq_zs[qq]+=zs;
}
bool QWE_fenxi::chanyucoujiang( char s[],string gjc){
int i=0,j,len=strlen(s);
string tmp;
while(i<len){
if(s[i]=='#'){
tmp="";
for( j=i+1;s[j]!='#';j++){
tmp+=s[j];
}
if(tmp==gjc){
return true;
}i=j+1;
}else i++;
}
return false;
}
bool QWE_fenxi::between_time(char s[]) {
int len = strlen(s);
if (len < 19)return false;
for (int i = 0; i < 19;i++) {
if ( s[i]!=' '&& s[i] != '-'&&s[i] != ':' && !(s[i] >= '0'&&s[i] <= '9'))return false;
}
for (int i = 0;i < 19;i++) {
if (s[i] < time1[i])return false;
else if (s[i] > time1[i])break;
}
for (int i = 0;i < 19;i++) {
if (s[i] > time2[i])return false;
else if (s[i] < time2[i])break;
}
return true;
}
bool QWE_fenxi::getperson(string gjc){
gjc=UTF8ToGB(gjc.c_str());
string str;
if(!qgetline(qLine[0]) )return false;
if (!between_time(qLine[0])) {
return true;
}
if(!qgetline(qLine[1]) )return false;
str=UTF8ToGB(qLine[1]);
int j;
for( j=0;j<str.size();j++){
qLine[1][j]=str[j];
}
qLine[1][j]='\0';
//de(qLine[1]);
if(!qgetline(qLine[2]) )return false;
if( !chanyucoujiang(qLine[1],gjc) ){
return true;
}
int i,t=0;
for(i=0;;i++){
if(qLine[0][i]==' '){
t++;
if(t==2)break;
}
}
getfayan(i);
return true;
}
void QWE_fenxi::getresult(string mgjc,string time11,string time22){
de("begin");
time1 = time11;
time2 = time22;
FILE *ffp;
fopen_s(&fp,"record.txt","rt");
fopen_s(&ffp,"gjc.txt","rt");
string gjc;
char ss[1024];
fgets(ss,1024,ffp);
gjc=ss;
gjc = mgjc;
gjc=UTF8ToGB(gjc.c_str());
while(getperson(gjc) ){
}
//de("-----------------------");
int cnt=0;
int zs,cs;
for( it1=qq_name.begin();it1!=qq_name.end();it1++){
a[cnt].name=it1->second;
a[cnt].qq=it1->first;
a[cnt].zs=qq_zs[ a[cnt].qq ];
a[cnt].cs=qq_cs[a[cnt].qq];
cnt++;
}
sort(a,a+cnt, & cmp );
freopen("result.txt","w",stdout);
for(int j=0;j<cnt;j++){
cout<<a[j].name<<" "<<a[j].qq<<" "<<a[j].cs<<" "<<a[j].zs<<endl;
}
}
七、附加功能实现
附加功能方面只制作了抽奖结果的海报,还没有连接上前面的代码。所以只贴出海报截图。
八、遇到的困难及解决方法
1.乐忠豪
遇到困难:
封装Dll
解决办法:
疯狂百度!
2.林志华
遇到困难:
1.遇到最烦的就是当时读取record文件当中的汉字会产生乱码,以前没有遇到过这种情况,还以为是因为读取的方式错了,弄了一个上午。
2.作业提供的record文件里面关于聊天记录的爬取很令人不满,人发的内容爬取的时候并没有压缩成一行,很乱。
解决方法:
1.当时百度了好久,用了很多方法都没用,最后灵机一动,发现可能是txt编码错了,果然,把utf-8改成ANSI就不会出现乱码了。
2.自己的事情自己做。
吐槽:要不是作业提供的文件编码格式不对,内容格式不整齐,那就不用花费怎么多时间浪费在这里了,还能多做一些其他东西,晦气。
3.李麒
遇到困难:
1.界面要调用其他组员的DLL,需要等待其他组员封装,并且每次出问题都需要重新来过。
2.使用C#制作界面并调用C++的DLL,没有经验
3.成功接入,但在内存上报错,无法确定是DLL的问题还是C#的问题
解决方法:
1.及时的沟通、调试
2.不断的摸索,看其他优秀博客的教程等
3.尝试过各种方法,均失败,造成界面的制作失败。
4.黄培鑫
遇到困难:
C++实现获奖名单生成海报存在困难,没有取得成功。
解决方法:
转而使用C#
吐槽:如果可以重来,那么我不会选软工实践(哭)
5.蔡子阳
遇到的困难:如何自动生成一个优美的文案
解决方法:暂时没有解决方法(可以等京东的莎士比亚系统正式出后再试试)
6.王焕仁
遇到的困难:汉字在c++编程中的处理,编码之前没有清晰思路。
解决方法:多亏了有人帮忙和百度搜索引擎的帮忙。
7.陈德斌
遇到的困难:一开始大家为了统一语言选择软件讨论了很久。
解决方法:大家统一选择c++实现。
8.何裕捷
遇到的困难:
1.没接触过生成图片的知识,需要百度很多知识,百度到的知识很多又是用不上的。
2.网上代码copy下来会有很多bug。
解决方法:百度解决。
九、评估每位组员的贡献比例
组员 | 得分 |
---|---|
白晨曦 | 5 |
乐忠豪 | 15 |
蔡子阳 | 10 |
黄培鑫 | 10 |
李麒 | 10 |
王焕仁 | 10 |
陈德斌 | 10 |
林志华 | 20 |
何裕捷 | 10 |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 180 | 190 |
· Estimate | · 估计这个任务需要多少时间 | 5 | 5 |
Development | 开发 | 90 | 120 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 60 |
· Design Spec | · 生成设计文档 | 30 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
· Design | · 具体设计 | 60 | 70 |
· Coding | · 具体编码 | 60 | 80 |
· Code Review | · 代码复审 | 10 | 10 |
· Test | · 测试(自我测试,修改代码,提交修改) | 10 | 10 |
Reporting | 报告 | 30 | 30 |
· Test Report | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 300 | 330 |
学习进度表
第N周 | 新增代码(行) | 累计代码(行) | 学习小时数(小时) | 累计学习小时数(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 100 | 100 | 15 | 15 | Axure的使用,设计文档的书写,复习了数据库的基本操作 |
3 | 1000 | 1100 | 25 | 40 | Java基本语法,STL容器的使用 |
11 | 1568 | 2768 | 30 | 70 | html,css,js学习,实战项目编写修改,sql server操作 |