java用户界面项目_结对项目(带图型用户界面)Java实现【柴政-陈起廷】
對(duì)分?jǐn)?shù)及整數(shù)的計(jì)算
/***
* 相加操作
*/
ADD("+") {
@Override
public String calculate(String a, String b) {
boolean flagA = a.contains("/");
boolean flagB = b.contains("/");
//兩個(gè)都是分?jǐn)?shù)
if (flagA && flagB) {
int[] anInt = ResolveUtil.analysis(a);
int[] bnInt = ResolveUtil.analysis(b);
//以AB為分母
int denominator = anInt[1] * bnInt[1];
//相加后的分子
int molecule = anInt[0] * bnInt[1] + anInt[1] * bnInt[0];
return ResolveUtil.createFraction(molecule, denominator);
} else if (flagA) {
int[] anInt = ResolveUtil.analysis(a);
//直接更新分子便可
anInt[0] += Integer.parseInt(b) * anInt[1];
return ResolveUtil.createFraction(anInt[0], anInt[1]);
} else if (flagB) {
int[] bnInt = ResolveUtil.analysis(b);
//直接更新分子便可
bnInt[0] += Integer.parseInt(a) * bnInt[1];
return ResolveUtil.createFraction(bnInt[0], bnInt[1]);
} else {
return String.valueOf(Integer.parseInt(a) + Integer.parseInt(b));
}
}
},
/***
* 相乘操作
*/
MULTIPLY("×") {
@Override
public String calculate(String a, String b) {
boolean flagA = a.contains("/");
boolean flagB = b.contains("/");
if (flagA && flagB) {
int[] anInt = ResolveUtil.analysis(a);
int[] bnInt = ResolveUtil.analysis(b);
//以AB為分母
int denominator = anInt[1] * bnInt[1];
//分子相乘
int molecule = anInt[0] * bnInt[0];
return ResolveUtil.createFraction(molecule, denominator);
} else if (flagA) {
int[] anInt = ResolveUtil.analysis(a);
return ResolveUtil.createFraction(anInt[0] * Integer.parseInt(b), anInt[1]);
} else if (flagB) {
int[] bnInt = ResolveUtil.analysis(b);
return ResolveUtil.createFraction(bnInt[0] * Integer.parseInt(a), bnInt[1]);
} else {
return String.valueOf(Integer.parseInt(a) * Integer.parseInt(b));
}
}
},
/***
* 相除操作
*/
DIVIDE("÷") {
@Override
public String calculate(String a, String b) {
//除法,從另外一種角度來(lái)說(shuō),是乘法的倒轉(zhuǎn),所以,只需要把b分子分母倒過(guò)來(lái)用乘法就行了
boolean flag = b.contains("/");
//新的數(shù)b的字符串
String newB;
//判斷b是否為分?jǐn)?shù)
if (flag) {
int[] bnInt = ResolveUtil.analysis(b);
newB = ResolveUtil.createFraction(bnInt[1], bnInt[0]);
} else {
newB = 1 + "/" + b;
}
return Symbol.MULTIPLY.calculate(a, newB);
}
},
/***
* 相減操作
*/
SUB("-") {
@Override
public String calculate(String a, String b) {
//減是加的特例,把b弄成-就可以了
return Symbol.ADD.calculate(a, "-" + b);
}
},
中綴轉(zhuǎn)后綴表達(dá)式
/***
* 中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式
* @param expression 表達(dá)式
* @return 數(shù)組
*/
private String[] middleToAfter(String expression) {
//用來(lái)轉(zhuǎn)換的棧
Stack stack = new Stack<>();
//表達(dá)式每個(gè)字符前后都會(huì)生成一個(gè)空格
String[] strings = expression.split("\\s");
//返回的list
List stringList = new ArrayList<>(strings.length);
for (int index = 0; index < strings.length; index++) {
if ('0' <= strings[index].charAt(0) && strings[index].charAt(0) <= '9') {
//數(shù)字直接輸出
stringList.add(strings[index]);
} else if (strings[index].equals(Symbol.BEGIN.getSymbol())) {
//開(kāi)始括號(hào)壓進(jìn)棧
stack.push(strings[index]);
} else if (strings[index].equals(Symbol.END.getSymbol())) {
//把所有運(yùn)算符都出棧
while (!stack.peek().equals(Symbol.BEGIN.getSymbol())) {
stringList.add(stack.pop());
}
//出棧開(kāi)始括號(hào)
stack.pop();
} else if (strings[index].equals(Symbol.MULTIPLY.getSymbol())
|| strings[index].equals(Symbol.DIVIDE.getSymbol())) {
//判斷上一級(jí)符號(hào)是什么
boolean flag = !stack.isEmpty() && (stack.peek().equals(Symbol.MULTIPLY.getSymbol())
|| stack.peek().equals(Symbol.DIVIDE.getSymbol()));
if (flag) {
stringList.add(stack.pop());
}
stack.push(strings[index]);
} else if (strings[index].equals(Symbol.SUB.getSymbol())
|| strings[index].equals(Symbol.ADD.getSymbol())) {
//此處應(yīng)該為+,-號(hào)
boolean flag = !stack.isEmpty() && (stack.peek().equals(Symbol.ADD.getSymbol())
|| stack.peek().equals(Symbol.SUB.getSymbol()));
if (flag) {
stringList.add(stack.pop());
}
stack.push(strings[index]);
} else {
//有其他符號(hào),直接跳出,可能是=號(hào)
break;
}
}
while (!stack.isEmpty()) {
stringList.add(stack.pop());
}
//返回?cái)?shù)組
return stringList.toArray(new String[0]);
}
后綴計(jì)算
/***
* 計(jì)算表達(dá)式
* @param expression 表達(dá)式
* @param permit 允許存在負(fù)數(shù)的運(yùn)算過(guò)程
* @return 結(jié)果
*/
public String calculate(String expression, boolean permit) {
if (expression == null) {
return null;
}
//先生成后綴表達(dá)式數(shù)組,然后手動(dòng)控制數(shù)組進(jìn)行操作
String[] afterExp = middleToAfter(expression);
Stack stack = new Stack<>();
try {
for (int index = 0; index < afterExp.length; index++) {
if (afterExp[index].matches("[0-9/']+")) {
stack.push(afterExp[index]);
} else {
String b = stack.pop();
String a = stack.pop();
String result = Symbol.value(afterExp[index]).calculate(a, b);
//計(jì)算過(guò)程中存在負(fù)數(shù),重新生成表達(dá)式
if (result.startsWith("-") && !permit) {
return null;
}
stack.push(result);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("存在表達(dá)式不合法");
}
return stack.pop();
}
生成表達(dá)式
/***
* 生成表達(dá)式
* @return 生成表達(dá)式
*/
private String generateExpression() {
//隨機(jī)運(yùn)算符大小
int operatorSize = (int) (Math.random() * MAX_OPERATOR_SIZE) + 1;
int numberSize = operatorSize + 1;
//判斷是否需要生成括號(hào),1/4的概率
boolean flag = (int) (Math.random() * MAX_OPERATOR_SIZE) == 0;
//標(biāo)記(產(chǎn)生的位置)
int mark = -1;
if (flag) {
//隨機(jī)插入括號(hào)的位置
mark = (int) (Math.random() * operatorSize);
}
StringBuilder expression = new StringBuilder();
//遍歷產(chǎn)生數(shù)字和符號(hào),你一下我一下
for (int i = 0; i < numberSize; i++) {
if (mark == i) {
myAppend(expression, "(");
}
//生成數(shù)字
myAppend(expression, (int) (Math.random() * 2) == 0 ? generateFraction() : generateInt());
//判斷是否加入結(jié)束符號(hào),判斷是否結(jié)尾
if (mark >= 0 && mark < i) {
//已經(jīng)到了表達(dá)式結(jié)尾, 此時(shí)必須結(jié)束
if (i == operatorSize) {
myAppend(expression, ")");
break;
}
//判斷是否需要結(jié)束
flag = (int) (Math.random() * 2) == 0;
if (flag) {
myAppend(expression, ")");
mark = -1;
}
}
if (i < operatorSize) {
//然后生成一個(gè)操作符
myAppend(expression, generateOperator());
}
}
//最后補(bǔ)充等號(hào)
expression.append("=");
return expression.toString();
}
去重校驗(yàn)
/***
* 檢查表達(dá)式是否已經(jīng)存在或者重復(fù)
* @param expression 表達(dá)式
* @param result 結(jié)果
* @return 是否重復(fù)
*/
private boolean checkExpressionExistAndResultIllegal(String expression, String result) {
if (Objects.isNull(result)) {
return true;
}
//當(dāng)前沒(méi)有表達(dá)式
if (nowExpressionSize == 0) {
return false;
}
//API的一些操作也是循環(huán),效率低下,手動(dòng)循環(huán)
for (int i = 0, j = nowExpressionSize - 1; i <= j; i++, j--) {
if (expressionList.get(i).equals(expression) || expressionList.get(j).equals(expression)) {
return true;
}
//查看是否答案有相同的
if (answerList.get(i).equals(result)) {
return checkCharEquals(expressionList.get(i), expression);
} else if (answerList.get(j).equals(result)) {
return checkCharEquals(expressionList.get(j), expression);
}
}
return false;
}
/***
*
* @param oldExpression 存在的表達(dá)式
* @param newExpression 還沒(méi)存進(jìn)去的表達(dá)式
* @return 相同,不相同
*/
private boolean checkCharEquals(String oldExpression, String newExpression) {
String[] oldExpressionArrays = oldExpression.split("\\s+");
String[] newExpressionArrays = newExpression.split("\\s+");
int oldExpressionNumber = 0;
int equalsNumber = 0;
//是否為數(shù)字
boolean flag;
//開(kāi)始遍歷
for (String oldString : oldExpressionArrays) {
flag = oldExpression.matches("[0-9'/]+");
if (flag) {
oldExpressionNumber++;
}
//比對(duì)
for (String newString : newExpressionArrays) {
if (oldString.equals(newString)) {
equalsNumber++;
}
}
}
答案校對(duì)
//保存正確/錯(cuò)誤題號(hào)的隊(duì)列
private List correctList = new ArrayList<>();
private List wrongList = new ArrayList<>();
/**
* 校驗(yàn)待檢測(cè)文件狀態(tài)
* @param exersicesFile
* @param myAnswer
* @Author Naren
*/
public void checkFile(String exersicesFile,String myAnswer) {
//存儲(chǔ)表達(dá)式的文件
File expFile = new File(exersicesFile);//Exercise002.txt
//待校驗(yàn)答案的文件
File myAnsFile = new File(myAnswer);//myAnswers001.txt
//待校驗(yàn)答案文件不存在
if(!myAnsFile.exists()){
//System.out.println("未找到待檢驗(yàn)答案文件。");
new Tips().displayTips("noExpTip.png");
return;
}
//如果表達(dá)式文件不存在
if(!expFile.exists()) {
//System.out.println("未找到指定題目文件。");
new Tips().displayTips("noAnsTip.png");
return;
}
//如果全部文件名都正確,檢測(cè)待校對(duì)題目文件是否存在于系統(tǒng)生成歷史中
String id = exersicesFile.substring(9,12);
String sysAnsFile = "Answers" + id + ".txt"; //Myapp.exe -e Exercises001.txt -a myAnswers001.txt
File ansFile = new File(sysAnsFile);//Answers002.txt(不存在)
//若系統(tǒng)中不存在與題目文件相符合的答案文件
if(!ansFile.exists()){
try {
FileReader fr = new FileReader(expFile);
BufferedReader br = new BufferedReader(fr);
String content = null;
ArrayList questionList = new ArrayList<>();
while((content = br.readLine()) != null){//(?m)^.*$
content = content.split("\\.")[1];
questionList.add(content);
}
//調(diào)用起廷方法獲得答案隊(duì)列
Expression ex = new Expression(new Calculate());
List answerList = ex.getCorrectAnswerList(questionList);
//比對(duì)
checkAnswer(myAnsFile,answerList);
} catch (Exception e) {
System.out.println("Class:AnswerChecking,Method:checkFile(String,String) is wrong!");
}
}else{
//調(diào)用本類(lèi)檢驗(yàn)方法比對(duì)答案文件
checkAnswer(myAnsFile,ansFile);
}
}
/**
* 將待校驗(yàn)答案文件與現(xiàn)場(chǎng)計(jì)算出的答案隊(duì)列進(jìn)行比對(duì)
* @param myAnswer
* @param answerList
* @author Naren
*/
private void checkAnswer(File myAnswer, List answerList){
try {
//待檢測(cè)答案文件
FileReader fr1 = new FileReader(myAnswer);
BufferedReader br1 = new BufferedReader(fr1);
LinkedHashMap map1 = new LinkedHashMap<>();
String content = "";
while((content = br1.readLine()) != null){
content = content.replaceAll(" +", "").replaceAll("\uFEFF", "");
//map1待校驗(yàn)答案:key:序號(hào),value:答案
map1.put(Integer.valueOf(content.split("\\.")[0]),content.split("\\.")[1]);
}
//開(kāi)始比對(duì)
for (int i = 0; i < answerList.size(); i++) {
if(map1.containsKey(i + 1)){
if(map1.get(i + 1).equals(answerList.get(i))) {
correctList.add(i + 1);//正確題號(hào)添加進(jìn)隊(duì)列
}
else{
wrongList.add(i + 1);//錯(cuò)誤題號(hào)添加進(jìn)隊(duì)列
}
}else{
//漏寫(xiě)
wrongList.add(i + 1);
}
}
//將校驗(yàn)結(jié)果寫(xiě)入文件
//System.out.println("檢驗(yàn)信息已寫(xiě)入Grade.txt文件。");
new Tips().displayTips("checkSuccess.png");
new DataStorage().storeCheckInfo(correctList,wrongList);
} catch (Exception e) {
System.out.println("Class:AnswerChecking,Method:checkAnswer(File,List) is wrong!");
}
}
/**
* 【重載】將待校驗(yàn)答案文件與本地答案文件進(jìn)行比對(duì)
* @param myAnswer 待校驗(yàn)答案文件
* @param ansFile 正確答案文件
* @author Naren
*/
private void checkAnswer(File myAnswer, File ansFile) {
try {
FileReader fr1 = new FileReader(myAnswer);
FileReader fr2 = new FileReader(ansFile);
BufferedReader br1 = new BufferedReader(fr1);
BufferedReader br2 = new BufferedReader(fr2);
LinkedHashMap map1 = new LinkedHashMap<>();//待檢測(cè) key:序號(hào),value:答案
LinkedHashMap map2 = new LinkedHashMap<>();//正 確 key:序號(hào),value:答案
//分別按行讀出答案
String content = "";
while((content = br1.readLine()) != null){
content = content.replaceAll(" +", "").replaceAll("\uFEFF", "");
map1.put(Integer.valueOf(content.split("\\.")[0]),content.split("\\.")[1]);
}
while((content = br2.readLine()) != null){
content = content.replaceAll(" +", "").replaceAll("\uFEFF", "");
map2.put(Integer.valueOf(content.split("\\.")[0]),content.split("\\.")[1]);
}
//開(kāi)始比對(duì)
for (int i = 0; i < map2.size(); i++) {
if(map1.containsKey(i + 1)){
if(map1.get(i + 1).equals(map2.get(i + 1))) {
correctList.add(i + 1);//正確題號(hào)添加進(jìn)隊(duì)列
}
else{
wrongList.add(i + 1);//錯(cuò)誤題號(hào)添加進(jìn)隊(duì)列
}
}else{
//漏寫(xiě)
wrongList.add(i + 1);
}
}
//將校驗(yàn)結(jié)果寫(xiě)入文件
//System.out.println("檢驗(yàn)信息已寫(xiě)入Grade.txt文件。");
new Tips().displayTips("checkSuccess.png");
new DataStorage().storeCheckInfo(correctList,wrongList);
} catch (Exception e) {
System.out.println("Class:AnswerChecking,Method:checkAnswer(File,File) is wrong!");
}
}
總結(jié)
以上是生活随笔為你收集整理的java用户界面项目_结对项目(带图型用户界面)Java实现【柴政-陈起廷】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux远程计算,如何使用Linux应
- 下一篇: java美元兑换,(Java实现) 美元