一、需求分析
二、功能设计
三、设计实现
四、代码说明
//生成Number Number GenerateNumber(int numMax){ int isInt, RealNumerator, IntNumber; Number num; num.sign = 1; isInt = rand() % 2; if (isInt){ num.denominator = 1; num.numerator = rand() % numMax + 1; } else{ num.denominator = rand() % numMax + 2; RealNumerator = rand() % (num.denominator - 1) + 1; //约分 int common = CommonDivisor(num.denominator, RealNumerator); num.denominator = num.denominator / common; RealNumerator = RealNumerator / common; IntNumber = rand() % (numMax - 1); num.numerator = IntNumber*num.denominator + RealNumerator; } return num; }
//将字符串转为Number Number Str2Num(string str){ Number num; int optPosi[2] = { 0, 0 }; for (int i = 0; i < str.size(); i++){ if (str[i] == 39){ optPosi[0] = i; } else if (str[i] == 47){ optPosi[1] = i; } } if (optPosi[0] == 0 && optPosi[1] == 0){ int tem = 0; for (int i = str.size(), j = 0; i > 0; i--, j++){ tem = tem + (str[j] - 48) * pow(10, i - 1); } num.numerator = tem; num.denominator = 1; num.sign = 1; return num; } else if (optPosi[0] == 0 && optPosi[1] != 0){ //有 真分数 1/2 int tem = 0; for (int i = optPosi[1], j = 0; i > 0; i--, j++){ tem = tem + (str[j] - 48) * pow(10, optPosi[1] - j - 1); } num.numerator = tem; tem = 0; for (int i = str.size(), j = optPosi[1] + 1; i > j; i--, j++){ tem = tem + (str[j] - 48) * pow(10, str.size() - j - 1); } num.denominator = tem; num.sign = 1; } else{ //有带分数 1‘2/3 int tem1 = 0, tem2 = 0, temInt = 0; for (int i = optPosi[0], j = 0; i > 0; i--, j++){ temInt = temInt + (str[j] - 48) * pow(10, i - 1); } temInt = temInt; for (int i = optPosi[1], j = optPosi[0] + 1; i >= j; i--, j++){ tem1 = tem1 + (str[j] - 48) * pow(10, optPosi[1] - j - 1); } for (int i = str.size(), j = optPosi[1] + 1; i >= j; i--, j++){ tem2 = tem2 + (str[j] - 48) * pow(10, str.size() - j - 1); } num.denominator = tem2; num.numerator = temInt * tem2 + tem1; num.sign = 1; } return num; }
//校验时查重 bool Check(string que, string queStr, map<string, int> &queList, map<string, Question> &QueList, int posi, Question &Que){ Question queStruct; sort(que.begin(), que.begin() + que.size()); if (queList.empty() || queList[que] == NULL){ queList[que] = 1; queStruct.no = posi; queStruct.queStr = queStr; QueList[que] = queStruct; return false; } else{ Que = QueList[que]; return true; } } //生成时查重 bool Check(string que, map<string, int> &queList){ sort(que.begin(), que.begin() + que.size()); if (queList.empty() || queList[que] != 1){ queList[que] = 1; return false; } else{ return true; } }
//生成后缀表达式 void GeneratePostfix(string que, list<string> &quePostfix, stack<char> &optStack){ map<char, int> isp, icp; isp[‘+‘] = 3; isp[‘-‘] = 3; isp[‘*‘] = 5; isp[‘/‘] = 5; isp[‘(‘] = 1; isp[‘)‘] = 6; icp[‘+‘] = 2; icp[‘-‘] = 2; icp[‘*‘] = 4; icp[‘/‘] = 4; icp[‘(‘] = 6; icp[‘)‘] = 1; isp[‘#‘] = 0; icp[‘#‘] = 0; string temPostfix; char optNow; que = que + ‘#‘; optStack.push(‘#‘); for (int i = 0; i < que.size(); i++){ if (que[i] > 47 && que[i] < 58){ temPostfix = temPostfix + que[i]; if (que[i + 1] == 39){ temPostfix = temPostfix + que[i + 1] + que[i + 2] + que[i + 3] + que[i + 4]; i = i + 4; } else if (que[i + 1] == 47){ temPostfix = temPostfix + que[i + 1] + que[i + 2]; i = i + 2; } if (que[i + 1] < 48){ temPostfix = temPostfix + " "; } continue; } else if (que[i] < 0){ optNow = ‘/‘; i++; } else{ optNow = que[i]; } while (isp[optStack.top()] > icp[optNow]){ if (optStack.top() == 47){ temPostfix = temPostfix + "÷ "; } else{ temPostfix = temPostfix + optStack.top() + " "; } optStack.pop(); } if (isp[optStack.top()] == icp[optNow]){ optStack.pop(); } else if (isp[optStack.top()] < icp[optNow]){ optStack.push(optNow); } } quePostfix.push_back(temPostfix); }
//计算表达式 void Calculate(string que, list<string> &ans, stack<Number> &ansStack, bool isError){ Number num; string temStr; char optNow; for (int i = 0; i < que.size(); i++){ while (que[i] != ‘ ‘){ temStr = temStr + que[i]; i++; } if (que[i] = ‘ ‘){ if (temStr[0] > 47 && temStr[0] < 58){ num = Str2Num(temStr); ansStack.push(num); temStr = ""; continue; } else if (temStr[0] < 0){ Number num1, num2; //除法 num2 = ansStack.top(); ansStack.pop(); num1 = ansStack.top(); ansStack.pop(); num = Division(num1, num2); ansStack.push(num); temStr = ""; } else if (temStr[0] == 42){ //乘法 Number num1, num2; num2 = ansStack.top(); ansStack.pop(); num1 = ansStack.top(); ansStack.pop(); num = Multiplication(num1, num2); ansStack.push(num); temStr = ""; } else if (temStr[0] == 43){ //加法 Number num1, num2; num2 = ansStack.top(); ansStack.pop(); num1 = ansStack.top(); ansStack.pop(); num = Addition(num1, num2); ansStack.push(num); temStr = ""; } else if (temStr[0] == 45){ //减法 Number num1, num2; num2 = ansStack.top(); ansStack.pop(); num1 = ansStack.top(); ansStack.pop(); num = Subtraction(num1, num2); ansStack.push(num); temStr = ""; } } } if (ansStack.top().denominator == 0){ isError = true; } else{ string a = Num2Str(ansStack.top()); ans.push_back(a); ansStack.pop(); } }
五、测试运行
进行出题
六、PSP展示
PSP2.1 |
Personal Software Process Stages |
Time Senior Student |
Time |
|
Planning |
计划 |
10 |
7 |
|
· Estimate |
估计这个任务需要多少时间 |
10 |
7 |
|
Development |
开发 |
325 |
903 |
|
· Analysis |
需求分析 (包括学习新技术) |
10 |
20 |
|
· Design Spec |
生成设计文档 |
5 |
0 |
|
· Design Review |
设计复审 |
5 |
0 |
|
· Coding Standard |
代码规范 |
5 |
3 |
|
· Design |
具体设计 |
60 |
30 |
|
· Coding |
具体编码 |
300 |
655 |
|
· Code Review |
代码复审 |
10 |
5 |
|
· Test |
测试(自我测试,修改代码,提交修改) |
30 |
190 |
|
Reporting |
报告 |
60 |
60 |
|
· |
测试报告 |
40 |
Nah |
|
· |
计算工作量 |
10 |
Nah |
|
· |
并提出过程改进计划 |
10 |
Nah |
|
|
|
|
|
|
七、小结
这次作业第一次开始接触到PSP来管理项目开发,让我在开发过程中效率提高了不少,虽然预估和实际差的还是挺大,但是相对自己之前而言,效率已经提高了不少,之后我会尽可能把这种方式运用到其实事情上来提高自己效率。
此外这次作业的内容看起来并不是很难,但是真正做起来的时候还是很花时间的,尤其是在一些细节的地方,其实有一大部分时间都是在调试、debug,还好最终问题都得到了解决,最后的效果也算是比较完整,个人感觉比较有缺陷的还是代码的质量上,感觉自己写的代码质量不高,一些东西没有设计好,希望以后可以不断提高自己的代码质量。
最后附上代码地址:https://coding.net/u/DaleAG/p/Calculator/git/tree/master/
原文:http://www.cnblogs.com/daleag/p/7585144.html