这个作业属于哪个课程 | 软件工程2024 |
---|---|
这个作业要求在哪里 | 结对项目 |
这个作业的目标 | 通过合作完成一个随机生成四则运算程序 |
姓名 | 学号 |
---|---|
张佳伟 | 3122004413 |
韩乐阳 | 3122004390 |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 920 |
Development | 开发 | 860 | 1100 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 150 |
· Design Spec | · 生成设计文档 | 20 | 30 |
· Design Review | · 设计复审 | 40 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 60 | 30 |
· Coding | · 具体编码 | 520 | 800 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 50 |
Reporting | 报告 | 60 | 60 |
· Test Repor | · 测试报告 | 20 | 25 |
· Size Measurement | · 计算工作量 | 20 | 15 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
· 合计 | 960 | 1260 |
一.设计思路
程序主要有随机生成表达式模块,中缀表达式转为后缀表达式并计算模块,文件的读写等主要模块。分好模块后进行代码设计
程序流程大概如图
二.代码说明
- 将生成的表达式由中缀表达式转为后缀表达式
主要运用栈的特性进行转化
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class InfixToPostfix {
public static String InfixToPostfixExp(String infixExpression) {
// 将中缀表达式转换成list集合存储,方便对数据遍历和操作
List<String> infixListExpression = toInfixListExpression(infixExpression);
// 根据中缀转后缀规则进行转换
Stack<String> operStack = new Stack<>(); // 符号栈
List<String> suffixExpression = new ArrayList<>(); // 存储后缀表达式
// 遍历list集合中的每一个元素
for(String item : infixListExpression){
if(item.matches("\\d+")){ // 如果为数字,直接加入到suffixExpression中
suffixExpression.add(item);
}else if (item.equals("(")){ // 如果为左括号,直接加入到suffixExpression中
operStack.push(item);
}else if (item.equals(")")){ // 如果为右括号,将左括号之前的符号都加入到suffixExpression中
if(!operStack.peek().equals("(")){
suffixExpression.add(operStack.pop());
}
operStack.pop(); // 遇到左括号后,将其pop出
}else if (!operStack.empty() && operStack.peek().equals("(")){
// 如果栈不为空,并且栈顶是左括号,运算符号直接入栈
operStack.push(item);
}else {
while (true){
// 如果符号栈不为空,并且栈顶不是左括号,就比较运算符优先级,
// 如果小于等于栈顶优先级,就将符号取出,再次判断栈是否为空,
// 新的栈顶是否为左括号
if(!operStack.empty()){
if (operStack.peek().equals("(")){
break;
}else if(operationPriority(item) <= operationPriority(operStack.peek()) ){
suffixExpression.add(operStack.pop());
}else {
break;
}
}else {
break;
}
}
operStack.push(item);
}
}
// 将栈中剩下的符号依次取出,并加入到suffixExpression中
while (true){
if(!operStack.empty()){
suffixExpression.add(operStack.pop());
}else {
break;
}
}
System.out.println("中缀表达式:"+infixExpression);
System.out.println("后缀表达式:"+suffixExpression);
StringBuilder result=new StringBuilder();
for(String string:suffixExpression)
result.append(string).append(" ");
return result.toString();
}
public static List<String> toInfixListExpression(String infix){
List<String> list = new ArrayList<>();
int index = 0;
String val = "";
while (index < infix.length()){
val = infix.substring(index,index+1);
// 如果num是数字,那么就判断下一位是否还是数字,是就继续追加,不是就退出
while (val.matches("\\d+") && index+1 < infix.length()){
if(infix.substring(index+1,index+2).matches("\\d+")){
val += infix.substring(index+1,index+2);
index++;
}else {
break;
}
}
list.add(val);
index++;
}
return list;
}
public static int operationPriority(String oper){
int result;
switch (oper){
case "+":
case "-":
result = 1;
break;
case "*":
case "÷":
result = 2;
break;
default:
throw new RuntimeException("运算符有误...");
}
return result;
}
}
- 后缀表达式的计算
public static Fraction calculator(String[] rpn){
//Fraction res = new Fraction(0, 1);
Stack<Fraction> fracStack = new Stack();
//Stack<String> stack = new Stack<>();
// 遍历数组
for (String item : rpn) {
// 如果为数字直接入栈,如果为运算符,直接取出栈中元素进行运算
if(item.matches("\\d+")){
//stack.push(item);
Fraction f = new Fraction(Integer.parseInt(item),1);
fracStack.push(f);
}else {
char c = item.charAt(0);
Fraction f = (Fraction)fracStack.pop();
Fraction f1 = new Fraction(f.numerator, f.denominator);
f = (Fraction)fracStack.pop();
Fraction f2 = new Fraction(f.numerator, f.denominator);
switch (c){
case '+':
fracStack.push(f2.add(f1));
break;
case '-':
fracStack.push(f2.subtract(f1));// 注意先出栈为被减数
break;
case '*':
fracStack.push(f2.multiply(f1));
break;
case '÷':
fracStack.push(f2.divide(f1));
break;
default:
throw new RuntimeException("运算符有误...");
}
// stack.push(String.valueOf(res));
}
}
//return Integer.parseInt(stack.pop());
if (!fracStack.isEmpty()) {
return (Fraction)fracStack.pop();
}else{
Fraction f = new Fraction(-1,1);
return f;
}
}
}
三.测试运行
总结
在实现要求的刚开试我们两人都不怎么有思路,但是经过合作思考,共同讨论设计思路慢慢的找到了设计方向,在这次项目中我们的都收获很多,知道了如合作去完成一个项目。过程中虽然遇到了困难但是还是合力解决了
标签:index,结对,operStack,项目,item,fracStack,Fraction,new From: https://www.cnblogs.com/jw30018/p/18096555