20165310java_teamExp1_week1
Posted atbaoi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20165310java_teamExp1_week1相关的知识,希望对你有一定的参考价值。
结对编程项目-四则运算-week1
需求分析
- 第一周达成
- 支持真分数的四则运算
- 支持多运算符
- 能手动输入n道题目,n由使用者输入
- 后续拓展的可能
- 能随机生成n道题目,n由使用者输入
- 能够判断正误,错误时能提醒并输出正确答案
- 能计算出正确率
- 能多次生成题目,直到使用者选择退出
- 题目去重
- 处理生成题目并输出到文件
- 完成题目后从文件读入并判题
多语言支持:
简体中文
,繁體中文
,English
设计思路
将带括号的四则运算式的字符串转化为逆波兰式,具体思路在[2016-2017-2 《Java 程序设计》课堂实践项目]中有明确的说明:
1.设立一个栈,存放运算符,首先栈为空;
2.从左到右扫描中缀式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;
3.若遇到运算符,则与栈顶比较,比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;
4.若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。
5.当栈变成空时,输出的结果即为后缀表达式。
根据上述思路,完成代码ChangeExpress.java
,将前缀式改为后缀式,并且完成分析括号匹配的功能,若左右括号不匹配,输出错误并退出程序运行:
import java.util.*;
public class ChangeExpress{
String originalExpression;
String changedExpression= "";
int countLeft=0,countRight=0;
public void setOriginalExpression(String str){
originalExpression=str;
}
public void changedWay(){
Stack stackChange=new Stack();//创立栈
int opValue []=new int[100];
for (int i=0;i<originalExpression.length() ;i++) {
char chi=originalExpression.charAt(i);
if (chi>=‘0‘&&chi<=‘9‘){
changedExpression=changedExpression+chi;
}
else if (chi==‘+‘||chi==‘-‘||chi==‘*‘||chi==‘÷‘||chi==‘/‘) {
changedExpression=changedExpression+" ";//有运算符,数字之间就要有空格,否则是一个整体
if (stackChange.empty()){//栈为空直接压栈
stackChange.push(chi);
}
else if (judgeValue(chi)>=judgeValue((char)stackChange.peek())) {//运算级别高或者相等压入栈
stackChange.push(chi);
}
else{
changedExpression=changedExpression+ String.valueOf(stackChange.pop())+" ";//否则直接进入字符串,空格分割运算符
i--;
}
}
else if(chi==‘(‘){
countLeft++;
stackChange.push(chi);//左括号压栈
}
else if(chi==‘)‘){
changedExpression+=" ";
countRight++;
while((char)stackChange.peek()!=‘(‘){//直到(为止
changedExpression=changedExpression+ String.valueOf(stackChange.pop())+" ";//弹出栈内东西,空格分割
}
stackChange.pop();
}
}
changedExpression+=" ";
while(!stackChange.empty()){
changedExpression=changedExpression+String.valueOf(stackChange.pop())+" ";
}
/*int size = stackChange.size();
for (int i=0;i<size;i++){
changedExpression=changedExpression+String.valueOf(stackChange.pop())+" ";
}*/
if (countLeft!=countRight) {
System.out.println("括号不匹配");
System.exit(0);
}
}
public int judgeValue(char c){
int value=0;
switch(c){
case ‘(‘:
value=1;
break;
case ‘+‘:
case ‘-‘:
value=2;
break;
case ‘*‘:
case ‘÷‘:
value=3;
break;
case ‘/‘:
value=4;
break;
case ‘)‘:
value=5;
default:
value=0;
}
return value;
}
}
- 进行后缀式计算:学习了[2016-2017-2 《Java 程序设计》课堂实践项目]之后,发现老师的参考代码MyDC.java,原理是:利用空格作为分隔符将后缀式表达的字符串进行分割,遇到操作数就压栈,遇到操作符就弹出栈顶的两位操作数进行运算,再将运行结果压栈,直到没有下一个分割好的字符串,输出结果:
import java.util.StringTokenizer;
import java.util.Stack;
public class MyDcRational
{
/** constant for addition symbol */
private final char ADD = ‘+‘;
/** constant for subtraction symbol */
private final char SUBTRACT = ‘-‘;
/** constant for multiplication symbol */
private final char MULTIPLY = ‘*‘;
/** constant for division symbol */
private final char DIVIDE1 = ‘÷‘;
private final char DIVIDE2=‘/‘;
/** the stack */
private Stack stack;//存放操作数的栈
public MyDcRational()
{
stack = new Stack();
}
public Rational evaluate (String expr)
{
Rational op1=new Rational();
Rational op2=new Rational();
Rational result=new Rational();
result.setNumerator(0);
String token;
StringTokenizer tokenizer = new StringTokenizer (expr);//划分表达式
while (tokenizer.hasMoreTokens())
{
token = tokenizer.nextToken();//将算数表达式分解的
if (isOperator(token))//见下方isOperateor方法,当是运算符的时候进入if语句
{
op2 = (Rational) stack.pop();
op1 = (Rational)stack.pop();//弹出最上面两个操作数
result = evalSingleOp (token.charAt(0), op1, op2);//见下方evaSingleOp方法
stack.push (result);//将计算结果压栈
}
else{
Rational num=new Rational();
num.setNumerator(Integer.parseInt(token));//将操作数由string转变为Rational
stack.push (num);//操作数入栈
}
}
return result;//输出结果
}
private boolean isOperator (String token)//判断是否为运算符,注意用equal语句比较字符串
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("÷")||token.equals("/"));
}
private Rational evalSingleOp (char operation, Rational op1, Rational op2)
{
Rational result=new Rational();
result.setNumerator(0);
switch (operation)
{
case ADD:
result = op1.add(op2);
break;
case SUBTRACT:
result = op1.sub(op2);
break;
case MULTIPLY:
result = op1.muti(op2);
break;
case DIVIDE1:
case DIVIDE2:
result = op1.div(op2);
break;
default:
System.out.println("Error!");
}
return result;
}
}
- 最后编写主函数代码Calculation.java,实现功能有:运算式输入、运算、结果输出:
import java.util.*;
public class Calculation {
public static void main(String[] args) {
System.out.println("请输入要生成的题目数:");
Scanner number = new Scanner(System.in);
int n = number.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println("题目" + i + ":");
Scanner reader = new Scanner(System.in);
Rational result = new Rational();
String str = reader.nextLine();
ChangeExpress change = new ChangeExpress();
change.setOriginalExpression(str);
//System.out.println(change.originalExpression);
change.changedWay();//后缀式化
//System.out.println(change.changedExpression);
MyDcRational calculate = new MyDcRational();//后缀式计算
result = calculate.evaluate(change.changedExpression);
int a = result.getNumerator();
int b = result.getDenominator();
if (b == 1) {
System.out.println("result=" + a);
} else {
System.out.println("result=" + a + "/" + b);
}
}
}
}
以上是关于20165310java_teamExp1_week1的主要内容,如果未能解决你的问题,请参考以下文章
2018-2019-120165226_20165310_20165315 实验四 外设驱动程序设计