结对编程总结
个人项目的复用:
我的个人项目是用c++写的,而队友的则是用java写的,这次要做UI,自然java做UI比用QT要方便简单得多,因此这次是以队友的个人项目作为本次结对编程的主要参考。但是队友的个人项目没有实现模块化,即从头到尾只有一个main函数,可扩展性很差,导致增加了很多工作量。
我和队友的分工是我做后台出题计算结果部分,队友做前台UI部分。因此我的任务是将小学、初中和高中出题部分模块化成类,方便前台调用其方法。然后就是要实现一个计算字符串算式结果的功能,封装成类以便前台调用。
以下是计算结果代码:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.Stack; 4 5 class InfixToSuffix 6 { 7 //遍历集合,是数字则入栈,碰到操作符,将数字出栈,判断操作符,并执行相应的操作 8 public static Float getResult(ArrayList<String> suffix) 9 { 10 Stack<Float> stack = new Stack<Float>(); 11 for(String element_suffix:suffix) 12 { 13 //如果是数字,入栈 14 if(Character.isDigit(element_suffix.charAt(0))) 15 { 16 stack.push(Float.parseFloat(element_suffix)); 17 }else{ 18 //如果遇到运算符,取出元素,并判断操作符,执行相应的计算 19 Float ANumber; 20 Float BNumber; 21 Float result = null; 22 switch (element_suffix) { 23 case "+": 24 ANumber = stack.pop();//取出第一个元素 25 BNumber = stack.pop();//取出第二个元素 26 result = ANumber+BNumber; 27 stack.push(result); 28 break; 29 case "-": 30 ANumber = stack.pop(); 31 BNumber = stack.pop(); 32 result = BNumber-ANumber; 33 stack.push(result); 34 break; 35 case "*": 36 ANumber = stack.pop(); 37 BNumber = stack.pop(); 38 result = ANumber*BNumber; 39 stack.push(result); 40 break; 41 case "/": 42 ANumber = stack.pop(); 43 BNumber = stack.pop(); 44 result = BNumber/ANumber; 45 stack.push(result); 46 break; 47 case "√": 48 ANumber = stack.pop(); 49 result = (float)Math.sqrt(ANumber); 50 stack.push(result); 51 break; 52 case "^2": 53 ANumber = stack.pop(); 54 result = ANumber*ANumber; 55 stack.push(result); 56 break; 57 case "sin": 58 ANumber = stack.pop(); 59 result = (float)Math.sin(ANumber*Math.PI/180); 60 stack.push(result); 61 break; 62 case "cos": 63 ANumber = stack.pop(); 64 result = (float)Math.cos(ANumber*Math.PI/180); 65 stack.push(result); 66 break; 67 case "tan": 68 ANumber = stack.pop(); 69 result = (float)Math.tan(ANumber*Math.PI/180); 70 stack.push(result); 71 break; 72 default: 73 break; 74 } 75 } 76 } 77 return stack.pop(); 78 } 79 //将字符串转成集合 80 public static ArrayList<String> getArrayList(String str) 81 { 82 ArrayList<String> stringList = new ArrayList<String>();//用于存储字符串集合 83 int i = 0; 84 for(int x = 0; x < str.length(); x++) 85 { 86 if(i > 0) 87 { 88 i--; 89 continue; 90 } 91 char chs = str.charAt(x); 92 if(chs == '^') 93 { 94 stringList.add("^2"); 95 i = 1; 96 continue; 97 } 98 else if(chs == 's') 99 { 100 stringList.add("sin"); 101 i = 2; 102 continue; 103 } 104 else if(chs == 'c') 105 { 106 stringList.add("cos"); 107 i = 2; 108 continue; 109 } 110 else if(chs == 't') 111 { 112 stringList.add("tan"); 113 i = 2; 114 continue; 115 } 116 else if(chs>=48 && chs<=57) 117 { 118 int y = x+1; 119 String temp = chs+""; 120 while(y<str.length() && str.charAt(y)>=48 && str.charAt(y)<=57) 121 { 122 temp += str.charAt(y); 123 y++; 124 } 125 stringList.add(temp); 126 i = y-x-1; 127 continue; 128 } 129 else 130 { 131 stringList.add(chs+""); 132 } 133 } 134 //System.out.println("将字符串存入集合:"+stringList); 135 return stringList; 136 } 137 //比较当前运算符和栈顶运算符的优先级(ture为低) 138 public static boolean getPriority(String stackPeek,String current) 139 { 140 if(stackPeek.equals("^2")||stackPeek.equals("√")||stackPeek.equals("sin")||stackPeek.equals("cos")||stackPeek.equals("tan")) 141 { 142 return true; 143 } 144 else if(stackPeek.equals("*")||stackPeek.equals("/")) 145 { 146 if(current.equals("*")||current.equals("/")||current.equals("+")||current.equals("-")) 147 { 148 return true; 149 } 150 } 151 else if(stackPeek.equals("+")||stackPeek.equals("-")) 152 { 153 if(current.equals("+")||current.equals("-")) 154 { 155 return true; 156 } 157 } 158 return false; 159 } 160 //获得后缀表达式 161 public static ArrayList<String> getSuffix(ArrayList<String> infix) 162 { 163 ArrayList<String> suffix = new ArrayList<String>();//用于存储最后的后缀式 164 Stack<String> operator = new Stack<String>();//用于比较运算符优先级 165 //第一步:分离数字和运算符 166 for(String chs:infix) 167 if(Character.isDigit(chs.charAt(0))) 168 {//如果是数字,加入集合 169 suffix.add(chs); 170 }else{ 171 //如果不是数字,分离括号和运算符 172 switch (chs.charAt(0)) { 173 //左括号直接入栈 174 case '(': 175 operator.push(chs); 176 break; 177 //右括号,出栈,直到左括号出栈 178 case ')': 179 while(!"(".equals(operator.peek())) 180 suffix.add(operator.pop()); 181 operator.pop();//左括号出栈 182 break; 183 default: 184 //原则是保证栈顶元素的优先级最高 185 while(!operator.isEmpty() && getPriority(operator.peek(),chs)) 186 suffix.add(operator.pop()); 187 operator.push(chs);//优先级高的栈顶元素出栈后,加入优先级更低的元素 188 break; 189 } 190 } 191 192 while(!operator.isEmpty()) 193 suffix.add(operator.pop()); 194 //System.out.println("后缀式是:"+suffix); 195 return suffix; 196 } 197 public static String calculate(String str) 198 { 199 Float a = getResult(getSuffix(getArrayList(str))); 200 String b = a+""; 201 return b; 202 } 203 }
通过调用 InfixToSuffix.calculate(str) 便能得到字符串算式str的计算结果(也是String类)。
思路是先将字符串转成集合,然后处理该集合得到最终的后缀表达式。处理集合的方法:遍历集合,分离数字和运算符,数字直接加入后缀表达式,运算符则压栈,比较优先级,优先级高的加入后缀表达式。保证栈顶元素优先级最高。
经验及教训:
要实现1+1>2的效果,必须分工明确,保证两人的工作不重复,避免浪费时间;其次是要写可扩展性好的代码,即方便修改的代码,因为一个项目不是你一个人完成的,可能有很多人要使用或者是稍作修改后使用你的代码,因此把各功能模块化、写注释可以很大程度上减少团队的总工作量;最后是要有良好的沟通,一个是相互讨论,可以更有效地解决问题,少走很多弯路。另一个是两个人的代码整合的时候,可能会有很多接口对不上,这时候需要静下心来讨论,谁去修改自己代码去适应对方的参数类型,做出让步是必要的。
最后感谢我的队友!合作愉快!
浙公网安备 33010602011771号