java 四则运算_java实现小学生四则运算
結(jié)對(duì)伙伴:葉文濤
項(xiàng)目要求:
實(shí)現(xiàn)一個(gè)自動(dòng)生成小學(xué)四則運(yùn)算題目的命令行程序.
使用 -n 參數(shù)控制生成題目的個(gè)數(shù)(完成)
使用 -r 參數(shù)控制題目中數(shù)值的范圍, 。該參數(shù)可以設(shè)置為1或其他自然數(shù)。(完成)
生成的題目中計(jì)算過(guò)程不能產(chǎn)生負(fù)數(shù)(完成)
生成的題目中如果存在形如e1?÷ e2的子表達(dá)式,那么其結(jié)果應(yīng)是真分?jǐn)?shù)。(完成)
程序一次運(yùn)行生成的題目不能重復(fù),生成的題目存入執(zhí)行程序的當(dāng)前目錄下的Exercises.txt文件(完成)
每道題目中出現(xiàn)的運(yùn)算符個(gè)數(shù)不超過(guò)3個(gè)(完成)
在生成題目的同時(shí),計(jì)算出所有題目的答案,并存入執(zhí)行程序的當(dāng)前目錄下的Answers.txt文件(完成)
程序應(yīng)能支持一萬(wàn)道題目的生成。(完成)
程序支持對(duì)給定的題目文件和答案文件,判定答案中的對(duì)錯(cuò)并進(jìn)行數(shù)量統(tǒng)計(jì)。(完成)
設(shè)計(jì):
分為兩個(gè)部分,第一是生成題目,生成表達(dá)式及答案后寫(xiě)入當(dāng)前目錄下的文件,第二是判斷答案是否正確,讀取文件后判斷,再將結(jié)果寫(xiě)入當(dāng)前目錄下的文件。
代碼
主函數(shù)
public static voidmain(String[] args){
System.out.println("請(qǐng)選擇功能:");
System.out.println(" 1. 四則運(yùn)算生成器");
System.out.println(" 2. 答案對(duì)比");
System.out.print("請(qǐng)輸入你的選擇[1/2]:");int choose = newScanner(System.in).nextInt();switch(choose){case 1:
ProducerController producerController= newProducerController();
producerController.ConstructProblem();break;case 2:
JudgeAnswerController judgeAnswerController= newJudgeAnswerController();
judgeAnswerController.start();break;default:
System.out.println("輸入不正確,請(qǐng)輸入1或2");main(args);break;
}
}
整數(shù)生成器與真分?jǐn)?shù)生成器函數(shù)
public String[] createProblem(intrange){
Random random= newRandom();int operatorCount = 1 + random.nextInt(3); //隨機(jī)操作符的個(gè)數(shù)(1-3個(gè))
int operand[] = new int[operatorCount + 1]; //操作數(shù)個(gè)數(shù)
int[] operatorIndex = index(operatorCount, 4, random);for(int i = 0; i < operatorCount + 1; i++){
operand[i]=random.nextInt(range);
}
String formula=stitchingFormula(operatorCount, operand, operatorIndex);//計(jì)算結(jié)果
Calculator calculator = newCalculator();int res =calculator.algorithm(formula);
String formulaRes[]= new String[2];if (res > 0){
formulaRes[0] =formula;
formulaRes[1] =String.valueOf(res);
}else{returncreateProblem(range);
}returnformulaRes;
}
public String[] createProblem(intrange){
Random random= newRandom();int operatorCount = 1 + random.nextInt(3); //操作符的個(gè)數(shù)1-3
CreateInteger create= newCreateInteger();int[] operatorIndex = create.index(operatorCount,2, random); //操作符的下標(biāo)//生成第一個(gè)操作數(shù)
int[] coprimeNumber1 =createCoprimeNumbers(range, random);int x = coprimeNumber1[0];int y = coprimeNumber1[1];
String s=shamToProperFraction(x, y);for(int i=0; i < operatorCount; i++){//生成剩下的操作數(shù)
int[] coprimeNumber =createCoprimeNumbers(range, random);int numx = coprimeNumber[0];int numy = coprimeNumber[1];
String currentOpreator=OPERATOR[operatorIndex[i]];if(currentOpreator.equals("+")){ //加法
x = x * numy + y *numx;
y= y *numy;
}else { //減法
int count = 0;while(x * numy - y * numx < 0){ //差為負(fù)數(shù)
coprimeNumber =createCoprimeNumbers(range, random);
numx= coprimeNumber[0];
numy= coprimeNumber[1];
count++;if (count >= 5){
numx= x - 1;
numy=y;
}
}
x= x * numy - y *numx;
y= y *numy;
}
String num=shamToProperFraction(numx, numy);
s+= currentOpreator +num;
}int greatFactor =greatFactor(x,y);
x/= greatFactor; //最終結(jié)果化簡(jiǎn)
y /=greatFactor;
String res=shamToProperFraction(x, y);
s+= "=";
String formulaRes[]={s, res};returnformulaRes;
}/*** 假分?jǐn)?shù)轉(zhuǎn)化為真分?jǐn)?shù)
*@paramx 分子
*@paramy 分母
*@return
*/
public String shamToProperFraction(int x, inty){if (x >y){int n = x /y;
x= (x - n *y);if (x == 0){returnString.valueOf(n);
}return n + "'" + x + "/" +y;
}else if (x ==y){return "1";
}else if (y == 1){returnString.valueOf(x);
}else if (x == 0){return "0";
}return x + "/" +y;
}
}
計(jì)算結(jié)果函數(shù)
public intalgorithm(String s) {
Stack numStack = new Stack<>(); //放數(shù)字
Stack operatorStack = new Stack<>(); //放操作符
HashMap hashMap = new HashMap<>(); //存放運(yùn)算符優(yōu)先級(jí)
hashMap.put("(", 0);
hashMap.put("+", 1);
hashMap.put("-", 1);
hashMap.put("*", 2);
hashMap.put("÷", 2);
String formula= s.replaceAll(" ", "");for (int i = 0; i
StringBuilder digit= new StringBuilder(); //StringBuilder類(lèi)中的方法主要偏重于對(duì)于字符串的變化,例如追加、插入和刪除等,這個(gè)也是StringBuffer和String類(lèi)的主要區(qū)別。
char c = formula.charAt(i); //將式子字符串切割為c字符
while (Character.isDigit(c)) { //判斷字符是否為10進(jìn)制數(shù)字,將一個(gè)數(shù)加入digit
digit.append(c);
i++;if (i
c=formula.charAt(i);
}else{break;
}
}if (digit.length() == 0){ //當(dāng)前digit里面已經(jīng)無(wú)數(shù)字,即當(dāng)前處理符號(hào)
switch(c) {case '(': {
operatorStack.push(String.valueOf(c));//如果是( 轉(zhuǎn)化為字符串壓入字符棧
break;
}case ')': { //遇到右括號(hào)了計(jì)算,因?yàn)?的優(yōu)先級(jí)最高
String stmp = operatorStack.pop(); //如果是),將符號(hào)棧棧頂元素取到
while (!operatorStack.isEmpty() && !stmp.equals("(")) { //當(dāng)前符號(hào)棧里面還有+ - * /
int a = numStack.pop(); //取操作數(shù)a,b
int b =numStack.pop();int result = calculate(b, a, stmp); //計(jì)算
if(result < 0)return -1;
numStack.push(result);//將結(jié)果壓入棧
stmp = operatorStack.pop(); //符號(hào)指向下一個(gè)計(jì)算符號(hào)
}break;
}case '=': { //遇到等號(hào)了計(jì)算
String stmp;while (!operatorStack.isEmpty()) { //當(dāng)前符號(hào)棧里面還有+ - * /,即還沒(méi)有算完
stmp =operatorStack.pop();int a =numStack.pop();int b =numStack.pop();int result =calculate(b, a, stmp);if(result < 0)return -1;
numStack.push(result);
}break;
}default: { //不滿足之前的任何情況
String stmp;while (!operatorStack.isEmpty()) { //如果符號(hào)棧有符號(hào)
stmp = operatorStack.pop(); //當(dāng)前符號(hào)棧,棧頂元素
if (hashMap.get(stmp) >= hashMap.get(String.valueOf(c))) { //比較優(yōu)先級(jí)
int a =numStack.pop();int b =numStack.pop();int result =calculate (b, a, stmp);if(result < 0)return -1;
numStack.push(result);
}else{
operatorStack.push(stmp);break;
}
}
operatorStack.push(String.valueOf(c));//將符號(hào)壓入符號(hào)棧
break;
}
}
}else { //處理數(shù)字,直接壓棧
numStack.push(Integer.valueOf(digit.toString())); //Integer.valueof()返回的是Integer對(duì)象,而Integer.parseInt()返回的是int型
continue; //結(jié)束本次循環(huán),回到for語(yǔ)句進(jìn)行下一次循環(huán),即不執(zhí)行i++(因?yàn)榇藭r(shí)i已經(jīng)指向符號(hào)了)
}
i++;
}return numStack.peek(); //返回棧底數(shù)字即等式的答案。
}
判斷結(jié)果函數(shù)
public voidstart(){
System.out.print("請(qǐng)輸入待驗(yàn)證答案路徑:");
Scanner scanner= newScanner(System.in);
String exerciseFilePath=scanner.next();
System.out.print("請(qǐng)輸入程序生成答案文件路徑:");
String answerFilePath=scanner.next();try{
List exerciseAnswers =exerciseFileReader(exerciseFilePath);
List answers =answerReader(answerFilePath);
List correct = new ArrayList<>();
List wrong = new ArrayList<>();int max =Math.max(exerciseAnswers.size(), answers.size());int num = 1;for (int i = 0; i < max; i++){if(exerciseAnswers.get(i).equals(answers.get(i))){
correct.add(String.valueOf(num++));
}else{
wrong.add(String.valueOf(num++));
}
}
File grade= new File("Grade.txt");if(grade.exists()){
grade.delete();
}if(grade.createNewFile()){
FileOutputStream gradeOutput= newFileOutputStream(grade);
PrintStream gradePrintStream= newPrintStream(gradeOutput);
String corrects= String.join(",", correct);
gradePrintStream.println("Correct:" + correct.size() +
" (" + corrects + ")");
String wrongs= String.join(",", wrong);
gradePrintStream.println("Wrong:" + wrong.size() +
" (" + wrongs + ")");
}
System.out.println("判定完成");
}catch(FileNotFoundException e) {
System.out.println("文件不存在");
}catch(IOException e) {
System.out.println("文件讀入異常");
}
}public List exerciseFileReader(String path) throwsIOException {
BufferedReader exerciseReader= new BufferedReader(newFileReader(path));
String exerciseAnswer= "";
List exerciseAnswers = new ArrayList<>();while ((exerciseAnswer = exerciseReader.readLine()) != null){
String[] split= exerciseAnswer.split("=");if (split[1] != null){
exerciseAnswers.add(split[1]);
}else{
exerciseAnswers.add(" ");
}
}returnexerciseAnswers;
}
測(cè)試
1.隨機(jī)生成10道10以?xún)?nèi)的四則運(yùn)算
2.判斷題目的正確與否
3.支持生成一萬(wàn)道題目
由于題目過(guò)多,因此直接在連接中打開(kāi)
以上就是所有功能的測(cè)試
PSP表格
PSP2.1
Personal Software Process Stages
預(yù)估耗時(shí)(分鐘)
實(shí)際耗時(shí)(分鐘)
Planning
計(jì)劃
10
5
· Estimate
· 估計(jì)這個(gè)任務(wù)需要多少時(shí)間
800
1200
Development
開(kāi)發(fā)
480
630
· Analysis
· 需求分析 (包括學(xué)習(xí)新技術(shù))
60
30
· Design Spec
· 生成設(shè)計(jì)文檔
60
80
· Design Review
· 設(shè)計(jì)復(fù)審 (和同事審核設(shè)計(jì)文檔)
30
45
· Coding Standard
· 代碼規(guī)范 (為目前的開(kāi)發(fā)制定合適的規(guī)范)
30
30
· Design
· 具體設(shè)計(jì)
30
60
· Coding
· 具體編碼
120
360
· Code Review
· 代碼復(fù)審
30
45
· Test
· 測(cè)試(自我測(cè)試,修改代碼,提交修改)
120
120
Reporting
報(bào)告
120
120
· Test Report
· 測(cè)試報(bào)告
60
30
· Size Measurement
· 計(jì)算工作量
30
30
· Postmortem & Process Improvement Plan
· 事后總結(jié), 并提出過(guò)程改進(jìn)計(jì)劃
30
30
合計(jì)
1200
1610
總結(jié)
在這次編程作業(yè)中,我和葉文濤同學(xué)一起討論,他主要負(fù)責(zé)編寫(xiě)代碼,后期的測(cè)試和報(bào)告則由我負(fù)責(zé),在這一次的作業(yè)中,我也從伙伴身上學(xué)習(xí)到了很多,認(rèn)識(shí)到自己與他人之間的差距,他在編程過(guò)程中也耐心的解答我的疑惑,在這個(gè)過(guò)程中不斷的完善代碼。兩個(gè)人一起處理問(wèn)題,互相汲取對(duì)方好的想法,有些細(xì)節(jié)沒(méi)有考慮到的,另一個(gè)人可以幫忙補(bǔ)充,這樣使得效率也大大提高。例如在我們進(jìn)行最后測(cè)試的過(guò)程中,我發(fā)現(xiàn)當(dāng)計(jì)算答案時(shí)如果答案為空則會(huì)出錯(cuò),在這個(gè)情況下我們進(jìn)行討論之后也克服了這個(gè)問(wèn)題。
總結(jié)
以上是生活随笔為你收集整理的java 四则运算_java实现小学生四则运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 声音传感器
- 下一篇: c语言四则运算报告,C语言四则运算实验报