结对项目总结 -- 基于Qt开发的win10桌面应用
担任角色
在这次结对项目中,由于采用了我的个人项目作为参考,所以我继续担任后端开发的角色。
开发环境
前端采用Qt Creator4.13.2 (Community)
后端采用C++
如何复用个人项目
通过对结对项目需求的分析,需要实现的功能大致如下:
注册和登录
修改密码
生成题目
题目作答并统计结果
详细功能需求描述和设计框架见下文 “整体设计框架”。
复用的个人项目的工程框架如下
Headers
User.h
SystemPrompt.h
TreeNode.h
RandomizeTestPaper.h
Sources
main.cpp
User.cpp
SystemPrompt.cpp
TreeNode.cpp
RandomizeTestPaper.cpp
通过了解结对项目的功能需求,经过讨论,决定采用以下复用方式
复用个人项目中随机生成题目的部分,即 TreeNode 和 RandomizeTestPaper 这两部分。小学题目不需要更改,但初中题目中涉及复杂的平方根运算,高中题目的三角函数也都是与 π 无关的弧度角。当这些情况都合在一起的时候,除了利用库函数计算出小数结果(这样对计算机而言都是可行的,但是对用户的使用体验是极不友好的),难以表示表达式的结果,因此需要对这两个难度的题目进行调整,详见下文“表达式求值”部分。初高的题目调整后,在个人项目的基础上增加 “表达式求值” 功能即可。
User 部分与结对项目需求中的 “注册和登录” 有一定的相关度,添加和完善一些功能即可复用。
SystemPrompt 部分主要是用于输出一些系统提示,与结对项目需求基本无关,不考虑复用。
整体设计框架
在清楚如何复用对个人项目的情况下,经过讨论得出结对项目的大致设计框架

表达式求值
添加限制规则的目的:让题目的难度符合正常的小初高试卷难度``
为了避免了平方、开平方、三角函数运算产生的复杂浮点数中间结果对整个表达式求解产生的严重阻碍,我们对小初高运算进行了如下限制:
小学表达式不作任何改变。
初中表达式中,平方内的运算结果一定在[-100, 100]之间,避免计算大数的平方;开平方内的运算结果一定是[1, 400]之间的平方数,保证开平方的结果是整数。
高中表达式中,三角函数全都是与 π 有关的特殊角,计算结果一定是-1, -1/2, 0, 1/2, 1只中的一个。
如此限制,整个表达式的计算结果最多包含一位小数。
构造逆波兰式
问题描述:给出一个名为 infix 的中缀表达式,类型为 string 数组,数组中只包含整数和 "+", "-", "*", "/" , "(", ")". 返回它的逆波兰式,返回类型也是 string 数组。
算法描述:使用一个名为 RPN 的 string 数组存储结果,一个名为 ops 的 string 类型的栈辅助转化,规定 "(" 和 ")".的优先级为 0,"+" 和 "-" 的优先级为 1,"*" 和 "/" 的优先级为 2。
从左至右遍历 infix ,当前位置的字符串记为 str
- 如果 str 是一个数字,直接加入 RPN. 判断下一个 str.
- 否则是操作符,循环执行以下步骤。
- 如果当前栈为空 或 str 是 "(" ,直接入栈,跳出当前循环, 判断下一个 str.
- 否则比较 str 和栈顶操作符的优先级
- 如果 str 的优先级高,直接入栈,跳出当前循环,判断下一个 str.
- 否则 弹出栈顶,非 "(" 的元素全部加入 RPN,直至遇到 "(" 跳出当前循环,判断下一个 str.
遍历完毕后,把 ops 中剩余的元素依次放入 RPN 中即可得到逆波兰式。
参考代码
// 构建逆波兰式
vector<string> RandomizeTestPaper::BuildRPN(string expression)
{
vector<string> infixExpression = BuildInfixExpression(expression); // 中缀表达式
map<string, int> precedence = GetPrecedence(); // 优先级
vector<string> RPN; // 逆波兰式
stack<string> ops; // 用于存储操作符
int infixSize = infixExpression.size();
for (int i = 0; i < infixSize; i++)
{
string s = infixExpression.at(i);
// 是一个数字
if (precedence.find(s) == precedence.end())
{
RPN.push_back(s);
continue;
}
// 是一个操作符
while (true)
{
// 空栈直接入栈
if (ops.empty())
{
ops.push(s);
break;
}
// 左括号 或 优先级比栈顶高 则入栈
map<string, int>::iterator it1 = precedence.find(s);
map<string, int>::iterator it2 = precedence.find(ops.top());
if (s == "(" || (it1->second > it2->second))
{
ops.push(s);
break;
}
// 优先级比栈顶低,要出栈了
string op = ops.top();
ops.pop();
// 左括号作为跳出循环的标志,其他运算符加入 RPN
if (op == "(")
{
break;
}
else
{
RPN.push_back(op);
}
}
}
// 剩余元素加入 RPN
while (!ops.empty())
{
RPN.push_back(ops.top());
ops.pop();
}
return RPN;
}
逆波兰式求值
问题描述:给出一个名为 RPN 的逆波兰表达式,类型为 string 数组,计算这个表达式的结果,返回类型为 int.
算法描述:借助一个名为 stk 的栈,类型为 int.
遍历 RPN 数组,记当前位置的字符串为 str
- 如果 str 是一个数字,直接入栈,判断下一个 str.
- 否则是一个操作符,依次从栈取出两个元素分别作为第二个操作数和第一个操作数,注意先二后一,作当前操作符的运算后,将结果重新入栈,判断下一个 str. 注意除法出现除以 0 要作特殊处理。
参考代码
// 计算逆波兰表达式
int RandomizeTestPaper::calculateRPN(string expression)
{
vector<string> RPN = BuildRPN(expression); // 逆波兰式
stack<int> stk;
int RPNsize = RPN.size();
int operand1 = 0, operand2 = 0;
for (int i = 0; i < RPNsize; i++)
{
if (RPN[i] == "+")
{
operand2 = stk.top();
stk.pop();
operand1 = stk.top();
stk.pop();
stk.push(operand1 + operand2);
}
else if (RPN[i] == "-")
{
operand2 = stk.top();
stk.pop();
operand1 = stk.top();
stk.pop();
stk.push(operand1 - operand2);
}
else if (RPN[i] == "*")
{
operand2 = stk.top();
stk.pop();
operand1 = stk.top();
stk.pop();
stk.push(operand1 * operand2);
}
else if (RPN[i] == "/")
{
operand2 = stk.top();
stk.pop();
operand1 = stk.top();
stk.pop();
if (operand2 == 0)
{
return 0;
}
stk.push(operand1 / operand2);
}
else
{
stk.push(atoi(RPN[i].c_str()));
}
}
int ans = stk.top();
stk.pop();
return ans;
}
运算无效
表达式中出现 "除以0" 或求 "tan(π/2)" 表示运算无效,四个选项中必然包含一个 "无效" 选项。
经验、教训总结
注意版本控制。在开发过程中,实现一个功能并反复测试后,可以整合成一个版本。很多时候觉得在添加功能后,导致整个工程编译不通过而且找不出原因,无奈之下只能重新开始慢慢添加功能并反复测试,这非常浪费时间。
结对编程尽量面对面交流。开发前期两人讨论完设计框架后就采用线上交流的方式开发,作为后端开发,我提供的接口的功能是正常的,但是参数个数和返回值却不是前端伙伴所需要的,而伙伴在线上也难以清楚具体描述需求,来来回回修改一个又一个版本非常浪费时间。而面对面交流,可以清楚明白伙伴需要什么,迅速开发出相应的接口。
帮助伙伴开发。伙伴在开发过程中可以在旁观看,作为旁观者经常能即使发现问题并提醒伙伴修正,不至于让伙伴一个人也许为了一个小问题 debug 很长时间,可以极大提高开发效率。
效果展示
登录注册界面

做题界面


结对项目总结 -- 基于Qt开发的win10桌面应用的更多相关文章
- 基于QT开发的第三方库
基于Qt开发的第三方库 分类: Qt2014-02-12 11:34 1738人阅读 评论(0) 收藏 举报 QT第三方库 目录(?)[+] 文章来源:http://blog.csdn.net ...
- 基于Qt的A*算法可视化分析
代码地址如下:http://www.demodashi.com/demo/13677.html 需求 之前做过一个无人车需要自主寻找最佳路径,所以研究了相关的寻路算法,最终选择A算法,因为其简单易懂, ...
- 基于Qt的开源音乐播放器(CZPlayer)
CZPlayer CZPlayer是基于Qt开发的一款功能强大的音乐播放器,该播放器的论坛地址请点击here,目前CZPlayer已经是第四个版本了,历史版本也分别在我的github上, github ...
- 免费开源数字货币交易所——基于Java开发的比特币交易所 | BTC交易所 | ETH交易所 | 数字货币交易所
本项目是基于Java开发的比特币交易所 | BTC交易所 | ETH交易所 | 数字货币交易所 | 交易平台 | 撮合交易引擎.本项目基于SpringCloud微服务开发,可用来搭建和二次开发数字货币 ...
- 【转贴】-- 基于QT的跨平台应用开发
原帖地址:http://www.cnblogs.com/R0b1n/p/4106613.html 1 Qt简介 Qt是1991年奇趣科技开发的一个跨平台的C++图形用户界面应用程序框架.它提供给应用程 ...
- 基于QT的webkit与ExtJs开发CB/S结构的企业应用管理系统
一:源起 1.何为CB/S的应用程序 C/S结构的应用程序,是客户端/服务端形式的应用程序,这种应用程序要在客户电脑上安装一个程序,客户使用这个程序与服务端通信,完成一定的 ...
- 【Qt编程】基于Qt的词典开发系列--后序
从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点 ...
- 【Qt编程】基于Qt的词典开发系列<六>--界面美化设计
本文讲一讲界面设计,作品要面向用户,界面设计的好坏直接影响到用户的体验.现在的窗口设计基本都是扁平化的,你可以从window XP与window 8的窗口可以明显感觉出来.当然除了窗口本身的效果,窗口 ...
- 【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计
这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3. ...
- 【Qt编程】基于Qt的词典开发系列<一>--词典框架设计及成品展示
去年暑假的时候,作为学习Qt的实战,我写了一个名为<我爱查词典>的词典软件.后来由于导师项目及上课等原因,时间不足,所以该软件的部分功能欠缺,性能有待改善.这学期重新拿出来看时,又有很多东 ...
随机推荐
- Vue router简单配置入门案例
{ 注意驼峰命名法,不然会报错 } 1.在Views文件夹下创建Vue路由文件,例如: <template> </template> <script> </ ...
- sqlmap的安装及使用
前提:安装SQLMap前需安装Python环境!!!(此处不进行描述...) 一.安装 1.在官网(http://sqlmap.org/)进行SQLMap安装包下载: 2.在Python的安装目录下新 ...
- java学习之Servlet
0x00前言 Servlet就是一个接口我们需要写一个类然后去实现Servlet,就可以被服务器识别到.request是用来接受客户端传过来的参数,respone是用来响应客户端的页面.我们所用的容器 ...
- 配置MSTP功能示例
组网需求 在一个复杂的网络中,网络规划者由于冗余备份的需要,一般都倾向于在设备之间部署多条物理链路,其中一条作主用链路,其他链路作备份.这样就难免会形成环形网络,若网络中存在环路,可能会引起广播风暴和 ...
- Selenium4+Python3系列(八) - Cookie、截图、单选框及复选框处理、富文本框、日历控件操作
我所在的城市昨天出了近20+的阳性案例,但这丝毫没有 "影响" 到996的工作时间,当然,也没有影响到我想继续更新文章的决心. 一.cookie常用操作入门 上一篇有写过关于coo ...
- 安装BurpSuite (专业版)
BurpSuite简介: Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTT ...
- 进军东南亚市场,腾讯云数据库 TDSQL 助力印尼 BNC 银行数字化转型
腾讯云数据库在助力金融核心系统分布式替换上,已经辐射到了东南亚市场. 东南亚最大的银行之一印尼BNC银行(Bank Neo Commerce)已正式完成新核心分布式迁移,使用腾讯云数据库TDSQL后, ...
- 【极客时间】大数据概述及HDFS介绍
- java中使用apache poi 读取 doc,docx,ppt,pptx,xls,xlsx,txt,csv格式的文件示例代码
java使用apache poi 读取 doc,docx,ppt,pptx,xls,xlsx,txt,csv格式的文件示例代码 1.maven依赖添加 在 pom 文件中添加如下依赖 <depe ...
- TabControl控件的简单使用-添加tab
1.首先创建一个MFC对话框框架,在对话框资源上从工具箱中添加上一个Tab Control 控件,根据需要修改一下属性,然后右击控件,为这个控件添加一个变量,将此控件跟一个CTabCtrl类变量绑定在 ...