结对对象
- 评价:不配合工作,技术又菜,要不是分数不是我负责的我都想上了
小组结对编程的照片
项目中自己负责的部分
生成题目 编写主类
个人贡献度划分
20172315胡智韬30%
20172312彭霖30%
20172318陆大岳40%
关键代码解释
- 计算类,实现中缀转后缀,后缀的计算
public class StringToArithmetic {
// 默认构造
public StringToArithmetic() {
}
// 将中缀表达式字符串计算得到结果
public static double stringToArithmetic(String string) {
return suffixToArithmetic(infixToSuffix(string));
}
// 将中缀表达式转换为后缀表达式
public static String infixToSuffix(String exp) {
// 创建操作符堆栈
Stack<Character> s = new Stack<Character>();
// 要输出的后缀表达式字符串
String suffix = "";
int length = exp.length(); // 输入的中缀表达式的长度
for (int i = 0; i < length; i++) {
char temp;// 临时字符变量
// 获取该中缀表达式的每一个字符并进行判断
char ch = exp.charAt(i);
switch (ch) {
// 忽略空格
case ' ':
break;
// 如果是左括号直接压入堆栈
case '(':
s.push(ch);
break;
// 碰到'+' '-',将栈中的所有运算符全部弹出去,直至碰到左括号为止,输出到队列中去
case '+':
case '-':
while (s.size() != 0) {
temp = s.pop();
if (temp == '(') {
// 重新将左括号放回堆栈,终止循环
s.push('(');
break;
}
suffix += temp;
}
// 没有进入循环说明是当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
s.push(ch);
break;
// 如果是乘号或者除号,则弹出所有序列,直到碰到加好、减号、左括号为止,最后将该操作符压入堆栈
case '×':
case '/':
case '÷':
while (s.size() != 0) {
temp = s.pop();
// 只有比当前优先级高的或者相等的才会弹出到输出队列,遇到加减左括号,直接停止当前循环
if (temp == '+' || temp == '-' || temp == '(') {
s.push(temp);
break;
} else {
suffix += temp;
}
}
// 没有进入循环说明是当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
s.push(ch);
break;
// 如果碰到的是右括号,则距离栈顶的第一个左括号上面的所有运算符弹出栈并抛弃左括号
case ')':
// 这里假设一定会遇到左括号了,此为自己改进版,已经验证可以过
// while ((temp = s.pop()) != '(') {
// suffix += temp;
// }
while (!s.isEmpty()) {
temp = s.pop();
if (temp == '(') {
break;
} else {
suffix += temp;
}
}
break;
// 默认情况,如果读取到的是数字,则直接送至输出序列
default:
suffix += ch;
break;
}
}
while (s.size() != 0) {
suffix += s.pop();
}
//
return suffix;
}
public static double suffixToArithmetic(String exp) {
String[] strings = exp.split("");
Stack<Double> stack = new Stack<Double>();
for (int i = 0; i < strings.length; i++) {
Pattern pattern = Pattern.compile("\d+||(\d+\.\d+)");
// 这里最好是进行判断彻底消除空格,在该数组的第一位为一个隐形的空格,这里一定要注意在使用exp.split("")剔除空白""
// 由于使用的是""截取导致在数组第一位上面的值为空白
if (strings[i].equals("")) {
continue;
}
// 如果遇到了数字则直接进栈
if (pattern.matcher(strings[i]).matches()) {
stack.push(Double.parseDouble(strings[i]));
}
// 如果是运算符,则弹出栈顶的两个数进行计算
else {
// !!!这里需要注意,先弹出的那个数其实是第二个计算数值,这里记作y!
// 自己书写的时候出错
double y = stack.pop();
double x = stack.pop();
// 将运算结果重新压栈
stack.push(calculate(x, y, strings[i]));
}
}
// 弹出栈顶元素就是最终结果
return stack.pop();
}
private static Double calculate(double x, double y, String string) {
// TODO Auto-generated method stub
// 其实使用case逻辑也可以
if (string.trim().equals("+")) {
return x + y;
}
if (string.trim().equals("-")) {
return x - y;
}
if (string.trim().equals("×")) {
return x * y;
}
if (string.trim().equals("÷")) {
return x / y;
}
if (string.trim().equals("/")){
return x / y;
}
return (double) 0;
}
}
- 主类,运行主类输入题数和级别,写完后获得正确答案
import java.util.Scanner;
public class calculate{
public static void main(String[] args) {
int z;//分子
int m;//分母
System.out.println("输入你要生成的题数");
Scanner scan = new Scanner(System.in);
int tishu = scan.nextInt();
System.out.println("输入你要生成题目的等级(输入1或2或3)");
int dengji = scan.nextInt();
//调用一个循环
double answer;
int zhengquelv = 0;
double[] daan = new double[tishu];
String[] daan1 = new String[tishu];
switch (dengji) {
case 1:
for (int i = 0; i < tishu; i++) {
String a = createquestions.create(1);
String b = a + "=";
System.out.print(b);
answer = scan.nextDouble();
daan[i] = StringToArithmetic.stringToArithmetic(a);
if (answer == daan[i])
zhengquelv++;
}break;
case 2:
for (int i = 0; i < tishu; i++) {
String a = createquestions.create(2);
String b = a + "=";
System.out.print(b);
answer = scan.nextInt();
daan[i] = StringToArithmetic.stringToArithmetic(a);
if (answer == daan[i])
zhengquelv++;
}break;
case 3:
for (int i = 0; i < tishu; i++) {
int m1 = 1 + (int) (Math.random() * 9 + 1);
int x1 = 1 + (int) (Math.random() * m1);
int m2=1+(int)(Math.random()*9+1);
int x2 = 1 + (int) (Math.random() * m2);
Fen f1 = new Fen(x1, m1);
Fen f2 = new Fen(x2, m2);
int c = (int) (Math.random() * 3);
if (c == 0) {
Fen d = f2.getJia(f1);
String a =f1+"+"+f2+"=";
System.out.print(a);
int fenzi =scan.nextInt();
int fenmu =scan.nextInt();
Fen f3 = new Fen(fenzi, fenmu);
System.out.println("你的答案:"+f3);
if(d==f3){
System.out.println("回答正确");
zhengquelv++;
}
else{
System.out.println("回答错误");
System.out.println("正确答案:"+d);
}
}
if(c==1) {
Fen d = f2.getJian(f1);
String a=f1 + "-" + f2+"=";
System.out.print(a);
int fenzi =scan.nextInt();
int fenmu =scan.nextInt();
Fen f3 = new Fen(fenzi, fenmu);
System.out.println("你的答案:"+f3);
if(d==f3){
System.out.println("回答正确");
zhengquelv++;
}
else{
System.out.println("回答错误");
System.out.println("正确答案:"+d);
}
}
if(c==2){
Fen d=f1.getChen(f2);
String a =f1 + "×" + f2+"=";
System.out.print(a);
int fenzi =scan.nextInt();
int fenmu =scan.nextInt();
Fen f3 = new Fen(fenzi, fenmu);
System.out.println("你的答案:"+f3);
if(d==f3){
System.out.println("回答正确");
zhengquelv++;
}
else{
System.out.println("回答错误");
System.out.println("正确答案:"+d);
}
}
if(c==3){
Fen d=f1.getChu(f2);
String a =f1 + "÷" + f2+"=";
System.out.print(a);
int fenzi =scan.nextInt();
int fenmu =scan.nextInt();
Fen f3 = new Fen(fenzi, fenmu);
System.out.println("你的答案:"+f3);
if(d==f3){
System.out.println("回答正确");
zhengquelv++;
}
else{
System.out.println("回答错误");
System.out.println("正确答案:"+d);
}
}
}break;
}
if(dengji<1||dengji>3)
System.out.println("题目等级输入错误");
if (dengji >= 1&&dengji <= 3) {
System.out.println("答案为");
for (
double daanwei : daan)
System.out.print(daanwei + " ");
System.out.println("正确率为" + zhengquelv + "/" + tishu);
}
}
}
- 生成题目类,有三个级别(一个运算符,两个运算符,分数计算)
public class createquestions {
public static String create(int level){
String add = "+", sub = "-", multi = "×", div = "÷";
String result="";
int r1=(int)(Math.random()*9+1);
int r2=(int)(Math.random()*9+1);
int r3=(int)(Math.random()*9+1);
//三个整数
int fenzi1=(int)(Math.random()*9+1);
int fenmu1=(int)(Math.random()*9+1);
String fenshu1=fenzi1+"/"+fenmu1;
int fenzi2=(int)(Math.random()*9+1);
int fenmu2=(int)(Math.random()*9+1);
String fenshu2=fenzi2+"/"+fenmu2;
int fenzi3=(int)(Math.random()*9+1);
int fenmu3=(int)(Math.random()*9+1);
String fenshu3=fenzi3+"/"+fenmu3;
//三个分数
int suiji1=(int)(Math.random()*4);
int suiji11=(int)(Math.random()*3);
//生成括号
int suiji2=(int)(Math.random()*4);
//第二个运算符
if (level>=1) {
if(suiji11==0&&level==2&&suiji1!=0&&suiji1!=1)
result+="(";
if (level==3)
result+=fenshu1;
else
result+=r1;
if (suiji1 == 0)
result+=add;
if (suiji1 == 1)
result+=sub;
if (suiji1==2)
result+=multi;
if(suiji1==3)
result+=div;
if(suiji11==1&&level>=2&&suiji2!=0&&suiji2!=1)
result+="(";
if (level==3)
result+=fenshu2;
else
result+=r2;
if(suiji11==0&&level==2&&suiji1!=0&&suiji1!=1)
result+=")";
}
if (level>=2){
if (suiji2==0)
result+=add;
if (suiji2 == 1)
result+=sub;
if (suiji2==2)
result+=multi;
if(suiji2==3)
result+=div;
if (level==3)
result+=fenshu3;
else
result+=r3;
if(suiji11==1&&suiji2!=0&&suiji2!=1)
result+=")";
}
return result;
}
}
- 分数类,分数运算
class Fen{
int z;//分子
int m;//分母
public Fen(int z,int m){
this.z=z;
this.m=m;
}
//相加
public Fen getJia(Fen f){
int newfz=f.z*m+z*f.m;
int newfm=f.m*m;
return yueFen(newfz,newfm);
}
//相减
public Fen getJian(Fen f){
int newfz=f.z*m-z*f.m;
int newfm=f.m*m;
return yueFen(newfz,newfm);
}
//相乘
public Fen getChen(Fen f){
int newfz=z*f.z;
int newfm=m*f.m;
return yueFen(newfz,newfm);
}
//相除
public Fen getChu(Fen f){
int newfz=z*f.m;
int newfm=m*f.z;
return yueFen(newfz,newfm);
}
//约分
private Fen yueFen(int newfz, int newfm) {
for(int x=(newfz>newfm?newfz:newfm);x>0;x--){//获取分子或者分母中大的那个数做为公约数的初始值
if(newfz%x==0&&newfm%x==0){//如果分子和分母都能被x模尽,那么x就是公约数
newfz=newfz/x;
newfm=newfm/x;
}
}
return new Fen(newfz,newfm);
}
public String toString(){
return z+"/"+m;
}
}
码云项目链接
感想
大型项目需要结对编程,但是需要在之前就要想好架构,不能边写还要边想架构,不然与其他人意见不合就很难进行