GitHub地址
https://github.com/onecatzyg/sizeyunsuan
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 20 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 1080 | 1410 |
· Analysis | · 需求分析 (包括学习新技术) | 40 | 120 |
· Design Spec | · 生成设计文档 | 40 | 40 |
· Design Review | · 设计复审 (和同事审核设计文档) | 20 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 10 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 800 | 1080 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 40 | 120 |
Reporting | 报告 | 120 | 120 |
· Test Report | · 测试报告 | 50 | 50 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 50 | 50 |
合计 | 1320 | 1560 |
解题思路
刚开始拿到题目之后想的是将操作符存于数组中,然后利用随机生成数的值除以4取余来确定运算符,但是在动手真正写代码的过程中却发现没那么简单,自己的基础很差,以前学的数据结构中的一些东西都忘了,虽然知道可以将运算式变换为后缀表达式然后进行运算,但是实际操作却感觉无从下手,根本不知道该怎么写。后来迫不得已只能,在以确定运算符个数为3的前提下,将所有的运算符的可能性一一枚举出来,运算符的种类有{“+”,“-”,“*”,“/”}这4种,4³=64种,然后利用0~63的随机生成数来确定运算符的组合,写了大概半天(大概是因为心不在焉,注意力不集中),写到后来发现问题有些严重,如果根据这种类似于枚举法的暴力方法来一直写下去的话,再加上运算数可能为分数,这样整个运算式的种数远远不是64种写的完的,而是4³x(2^4)=1024!!!!这样写下去的话,代码行数完完全全超出预期,可能需要上万行代码,所以后来坚持不下去了(舍友也说这样写可能会被老师骂死),放弃了这种死脑筋的方法。
然后开始看中缀表达式到后缀表达式的转换,看了大概两个小时,弄懂了怎么回事,想起了以前学的一些东西,但是代码还是写不出来(自我反省:动手能力极差!!),然后开始上网找大牛们的写法,然后找到了一位大牛的写法,http://blog.csdn.net/njr465167967/article/details/51969439,中间他虽然有个别文字错误,但是还是可以比较好的理解(主要是他的代码比较全),写出了整个过程,中间好多地方作为不熟悉java语言编程的我看得有点难受,但好在还是熬过来了,看懂了他的想法和其中代码操作,我大部分的关键代码是直接用他的(自己写的有点问题,然后时间来不及了,索性先用他的,然后下来自己再尝试一下)。但是有一个问题我还是没有解决,就是真分数的运算,在java中没有像python中那样的分数运算的包,自己还没有完成,只完成了整数的运算。
设计实现过程
两个类:houzhuiyunsuan.class和transf.class
transf.class中主要是后缀表达式的运算其中包含processInfix、isDigital判断是否为数字、process()转化过程、getParent()匹配、getOperation(String str, int priority)操作函数、getPriority(String str)、getPost()去掉字符串首位空格等
houzhuiyunsuan.class中compute(String str)四则运算的操作
代码说明
由后缀表达式得到四则运算结果的实现过程:
public void operate(){
String[] strArr = post.split(" ");
for(int i = 0; i < strArr.length; i++){
String temp = strArr[i];
if(isDigital(temp)){
stack.push(Integer.valueOf(temp));
}else{
int result = compute(temp);
stack.push(result);
}
}
}
四则运算操作 :
private int compute(String str){
int re = 0;
int m = stack.pop();//出栈第一个元素
int n = stack.pop();//出栈第二个元素
switch(str){
case "+" :
re = n + m;
break;
case "-" :
re = n - m;
break;
case "*" :
re = n * m;
break;
case "/" :
re = n / m;
break;
default :
break;
}
return re;
}
//判断是否为数字
private boolean isDigital(String str){
char[] chArr = str.toCharArray();
int len = chArr.length;
int count = 0;
for(int i = 0; i < len; i++){
if(chArr[i] >= '0' && chArr[i] <= '9')
count++;
}
return count == len;
}
运算式转化为后缀表达式:
private String processInfix(String infix) {
String result = "";
for (int i = 0; i < infix.length() - 1; i++) {
char temp1 = infix.charAt(i);
char temp2 = infix.charAt(i + 1);
if (isDigital(temp1) && isDigital(temp2)) {
result += temp1;
} else {
result += temp1 + " ";
}
}
result += infix.charAt(infix.length() - 1); // 将最后一个元素添加进去
return result;
}
public void process() {//转化过程
String[] strArr = processInfix(infix).split(" ");
for (int i = 0; i < strArr.length; i++) {
String str = strArr[i];
switch (str) {//运算符操作
case "+":
case "-":
getOperation(str, 1);
break;
case "*":
case "/":
getOperation(str, 2);
break;
case "(":
stack.push(str);
break;
case ")":
getParent();
break;
default:
post += " " + str;
break;
}
}
while (!stack.isEmpty()) {//当栈非空则在原有字符串后加上出栈元素
post += " " + stack.pop();
}
}
private void getParent() {
while (!stack.isEmpty()) {
String top = stack.pop();
if (top.equals("(")) {
break;
} else {
post += " " + top;
}
}
}
private void getOperation(String str, int priority) {
while (!stack.isEmpty()) {
String top = stack.pop();
if (top.equals("(")) {
stack.push(top);
break;
} else {
int priTop = getPriority(top);
if (priTop < priority) {
stack.push(top);
break;
} else {
post += " " + top;
}
}
}
stack.push(str);
}
private int getPriority(String str) {
int pri = 0;
if (str.equals("+") || str.equals("-")) {
pri = 1;
} else {
pri = 2;
}
return pri;
}
public String getPost() {
return post.trim();//去掉字符串首位空格
}
测试说明
测试过程中发现还是有些问题,式子算出来的都是整数,没有考虑到分数的情况,有括号的情况也没有考虑到。作业提交之后再找时间改进吧。
项目小结
在实现的过程中,动手能力太重要了,以后要多加练习,自己的能力真的很差,在老师看来很简单的东西,但是对于自己来讲是个不小的挑战。数字和字符的处理看起来简单,但是做起来真的有点难。