《软件工程》课程设计总结
团队名称:起航
成员:
康取 201306114422
陈键 201306114416
罗伟业 201306114446
开发需求;
如同英语有随身记APP,数学也能有随身练,通过简单的四则运算,提高用户的心算速度。
面向对象;
小学生
四则运算功能;
1.产生两个整数的四则运算算式
2.产生带有分数的四则运算算式
3.产生带有括号的四则运算算式
4.答题后匹配正确答案,正确则提示正确,错误则显示正确答案
5.练习模式与考试模式供用户选择
6.练习模式是通过大量的题目练习
7.考试模式是在一定的时间内完成题目,并记录分数,显示正确率
8.美观,简洁的图形用户操作界面
小组成员分工;
康取;负责产生带有分数的四则运算算式及验证答案
陈健;负责图形用户操作界面设计(界面的计时功能,验证答案后弹出正确与否),考试模式统计正确率与考试分数。带括号的四则运算算式及验证答案
罗伟业;负责两个整数间的四则运算算式及验证答案
代码如下;
package com.app.senior_calculator; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Toast; public class APP extends Activity { // 偏好设置 //private SharedPreferences sp; //private SharedPreferences.Editor editor; /** level and mode (index) **/ int selectedLevelIndex = 0; int selectedModeIndex = 0; int chioceItems; Bundle bundle = new Bundle(); /** choices **/ private String iconName1 = "选择难度"; private String[] arrayLevel = new String[] { "加减", "乘除", "四则运算(带分数)", "四则运算(含括号)" }; private String iconName2 = "选择模式"; private String[] arrayModel = new String[] { "Practice", "Examination" }; /** 题目库 **/ private List<Question> source = new ArrayList<Question>(); public void onclick(View v) { switch (v.getId()) { case R.id.StartTest: DialogDifficulty(arrayLevel, iconName1).show(); break; case R.id.Medol: DialogDifficulty(arrayModel, iconName2).show(); break; case R.id.Help: Toast.makeText(APP.this, " Dont know what to do……", Toast.LENGTH_SHORT).show(); break; case R.id.Exit: Toast.makeText(APP.this, " Closing…………", Toast.LENGTH_SHORT).show(); finish(); break; } } /** 定义一个Dialog 展示 level选择 后者为标题 **/ public Dialog DialogDifficulty(final String[] array_data, final String dialogtitle) { chioceItems = selectedLevelIndex; if (dialogtitle.equals("选择难度")) chioceItems = selectedLevelIndex; else if (dialogtitle.equals("选择模式")) chioceItems = selectedModeIndex; Dialog alertDialog; alertDialog = new AlertDialog.Builder(this, R.style.dialog) .setTitle(dialogtitle) .setIcon(R.drawable.diologicon) .setSingleChoiceItems(array_data, chioceItems, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (dialogtitle.equals("选择难度")) selectedLevelIndex = which; else if (dialogtitle.equals("选择模式")) selectedModeIndex = which; /** 模式传递过去TestView根据模式来设置时间长度. */ bundle.putString("difficulty", arrayModel[selectedModeIndex]); } }) .setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { bundle.putString("difficulty", arrayModel[selectedModeIndex]); /* // 确定后保存数据模式跟难度的下标数据.. if (dialogtitle.equals("选择难度")) editor.putInt("selectedLevelIndex", which); if (dialogtitle.equals("选择模式")) editor.putInt("selectedModeIndex", which); editor.commit();// 提交修改 */ /** 在确定难度后跳转出题目 设置模式到时候不跳转. **/ if (dialogtitle.equals("选择难度")) createexercise(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 实现函数- 。- 调用. Toast.makeText(APP.this, " canceling ", Toast.LENGTH_SHORT).show(); } }).create(); return alertDialog; } /** 出题模块 根据选择的模式出先不同数量的题目. **/ public void createexercise() { int totalNumber = 50; if (arrayModel[selectedModeIndex].equals("Examination")) totalNumber = 25; switch (selectedLevelIndex) { case 0: source = new ArrayList<Question>(); Toast.makeText(APP.this, String.valueOf(selectedLevelIndex), Toast.LENGTH_LONG) .show(); /* 在这里产生 totalNumber 条 题目. 出现了问题!!!????? */ new SimpleCreate().simpleExerciseInitation(0, totalNumber, source); for (int i = 0; i < source.size(); i++) Log.i("info", source.get(i).getExercise() + "=" + source.get(i).getAnswer()); bundle.putSerializable("resource", (Serializable) source); Intent MAintent = new Intent(APP.this, TestView.class); MAintent.putExtras(bundle); startActivity(MAintent); break; case 1: source = new ArrayList<Question>(); new SimpleCreate().simpleExerciseInitation(1, totalNumber, source); for (int i = 0; i < source.size(); i++) Log.i("info", source.get(i).getExercise() + "=" + source.get(i).getAnswer()); bundle.putSerializable("resource", (Serializable) source); Intent intent1 = new Intent(APP.this, TestView.class); intent1.putExtras(bundle); startActivity(intent1); break; case 2: source = new ArrayList<Question>(); new MidiumCreate().midiumCreateInitation(totalNumber, source); for (int i = 0; i < source.size(); i++) Log.i("info", source.get(i).getExercise() + "=" + source.get(i).getAnswer()); bundle.putSerializable("resource", (Serializable) source); Intent intent2 = new Intent(APP.this, TestView.class); intent2.putExtras(bundle); startActivity(intent2); break; case 3: source = new ArrayList<Question>(); // 出题目验证. new CreateEFraction().createYouExercisess(2, source); for (int i = 0; i < source.size(); i++) Log.i("info", source.get(i).getExercise() + "=" + source.get(i).getAnswer()); bundle.putSerializable("resource", (Serializable) source); Intent intent3 = new Intent(APP.this, TestView.class); intent3.putExtras(bundle); startActivity(intent3); break; default: Toast.makeText(APP.this, "errors happend ", Toast.LENGTH_LONG) .show(); break; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.app); /*// 获取偏好设置实例 sp = getSharedPreferences("MySP", MODE_PRIVATE); editor = sp.edit(); editor.putInt("selectedLevelIndex",0); editor.putInt("selectedModeIndex", 0); editor.commit();// 提交修改 */ } }
package com.app.senior_calculator; import java.math.BigDecimal; import java.util.List; import java.util.Random; public class SimpleCreate { private MyCalculate calculate = new MyCalculate(); //伟业的生产 private String simpleExercise(int choice) { String practice = ""; int x = (int) (Math.random() * 50); int y = (int) (Math.random() * 50); int Random_Index; Random rad = new Random(); switch (choice) { case 0: String[] fuHao_1 = { "+" + "", "-" + "" }; Random_Index = rad.nextInt(fuHao_1.length); if (Random_Index == 1 && x < y) return y + fuHao_1[Random_Index] + x; practice = x + fuHao_1[Random_Index] + y; break; case 1: String[] fuHao_2 = { "x" + "", "/" + "" }; Random_Index = rad.nextInt(fuHao_2.length); if (Random_Index == 1 && y == 0) y = 1 + (int) (Math.random() * 50); practice = x + fuHao_2[Random_Index] + y; break; default: break; } return practice; } //weiye 生产 public void simpleExerciseInitation(int choice,int number, List<Question> question){ String questiontemp=""; String answertemp=""; for(int i=0;i<number;i++){ questiontemp = simpleExercise(choice); calculate.setExpression(questiontemp); answertemp = calculate.getResult(); answertemp = adjustResult(answertemp); question.add(new Question(questiontemp,answertemp,i+1)); /* Log.i("info", question.get(i).getExercise() + "=" + question.get(i).getAnswer() + " 第" +question.get(i).getCountNumber()+"题");*/ } } /** 比较答案的对错,精度为0.001 **/ public String adjustResult(String CorrectResult) { BigDecimal correctAnswer = new BigDecimal(CorrectResult); double cAnswer; cAnswer = correctAnswer.doubleValue(); int temp = (int) Math.round(cAnswer * 1000); cAnswer = temp / 1000.0; String answer = String.valueOf(cAnswer); return answer; } }
package com.app.senior_calculator; import java.math.BigDecimal; import java.util.List; import java.util.Random; public class MidiumCreate { private MyCalculate calculate = new MyCalculate(); // 康取的生产算法 by kanqu public String midiumCreate() { int a = 0;// 随机数分子 int a2 = 1;// 随机数分母 int b = 0; int b2 = 1; int c = 0; int c2 = 1; int e = 0; int d = 0; int f = 0; String op = ""; String op2 = ""; Random r = new Random(); a = r.nextInt(100) + 1; a2 = r.nextInt(100) + 1; b = r.nextInt(100) + 1; b2 = r.nextInt(100) + 1; c = r.nextInt(100) + 1; c2 = r.nextInt(100) + 1; d = r.nextInt(4) + 1; e = r.nextInt(4) + 5; f = r.nextInt(4) + 9; switch (d) { case 1: { op = "+" + ""; break; } case 2: { op = "-" + ""; break; } case 3: { op = "x" + ""; break; } case 4: { op = "/" + ""; break; } } switch (e) { case 5: { op2 = "+" + ""; break; } case 6: { op2 = "-" + ""; break; } case 7: { op2 = "x" + ""; break; } case 8: { op2 = "/" + ""; break; } } switch (f) { case 9: { return a + op + b + op2 + c; } case 10: { return "("+""+a + "/"+"" + a2 +")"+""+ op + b + op2 + c; } case 11: { return a + op + "("+"" +b + "/"+"" + b2 +")"+""+ op2 + c; } case 12: { return a + op + b + op2 + "(" + "" + c + "/" + "" + c2+")"+""; } } return ""; } // 传参生产 public void midiumCreateInitation(int number, List<Question> question) { String questiontemp = ""; String answertemp = ""; for (int i = 0; i < number; i++) { questiontemp = midiumCreate(); calculate.setExpression(questiontemp); answertemp = calculate.getResult(); answertemp =adjustResult(answertemp); question.add(new Question(questiontemp, answertemp, i + 1)); /* Log.i("info", question.get(i).getExercise() + "=" + question.get(i).getAnswer() + " 第" + question.get(i).getCountNumber() + "题");*/ } } /** 比较答案的对错,精度为0.001 **/ public String adjustResult(String CorrectResult) { BigDecimal correctAnswer = new BigDecimal(CorrectResult); double cAnswer; cAnswer = correctAnswer.doubleValue(); int temp = (int) Math.round(cAnswer * 1000); cAnswer = temp / 1000.0; String answer = String.valueOf(cAnswer); return answer; } }
package com.app.senior_calculator; import android.app.ActionBar; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; public class Score extends Activity{ private TextView right,wrong,score; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.score); ActionBar actionBar = getActionBar(); actionBar.show(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); right = (TextView) findViewById(R.id.rnumber); wrong = (TextView) findViewById(R.id.wnumber); score = (TextView) findViewById(R.id.score); Bundle bundle = new Bundle(); bundle = getIntent().getExtras(); right.setText(bundle.getString("rightnumber").toString()); wrong.setText(bundle.getString("wrongnumber").toString()); String temp =getScroe(bundle.getString("rightnumber").toString() , bundle.getString("wrongnumber").toString()); score.setText(temp); } public void onclick(View v ){ switch (v.getId()) { case R.id.Back: startActivity(new Intent (Score.this,APP.class)); break; case android.R.id.home: startActivity(new Intent(Score.this,TestView.class)); break; } } public String getScroe(String right , String wrong){ double rightnumber = Double.parseDouble(right); double wrongnumber = Double.parseDouble(wrong); double totalScore = (rightnumber/(rightnumber+wrongnumber ))*100; return String.valueOf(totalScore); } }
package com.app.senior_calculator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class TestView extends Activity { private boolean secondSubmit = false; /** 组件 **/ private Button preBtn, nextBtn, subBtn; private TextView CorrectAndWrong; // 对错比例 private TextView wrongNumber; private TextView rightNumber; int total, right = 0, wrong = 0; private TextView noticeText;// 模式提醒. private TextView Explanation;// 错题解析 private double[] userAnswer;// 用户答案记录. private TextView TiHao; private TextView Clock; int recleantime = 60; int minute = 9; /** 答错题目之后显示正确答案 **/ private EditText UserInput; /** 用户输入 **/ private String UserAnswer; /** 用户题目答案 **/ private TextView userquestion; /** 用户题目 **/ /** Counter 题号 兼顾 题目list的下标 **/ private int Counter = 0; private List<Question> TestTitle; boolean judge = false;// 判断输出未做题目的 题号. @SuppressWarnings("unchecked") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.testview); ActionBar actionBar = getActionBar(); actionBar.show(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); preBtn = (Button) findViewById(R.id.previous); nextBtn = (Button) findViewById(R.id.next); subBtn = (Button) findViewById(R.id.submitButton); preBtn.setEnabled(true); nextBtn.setEnabled(true); subBtn.setEnabled(true); CorrectAndWrong = (TextView) findViewById(R.id.CorrectAndWrong); wrongNumber = (TextView) findViewById(R.id.wrongNumber); rightNumber = (TextView) findViewById(R.id.rightNumber); noticeText = (TextView) findViewById(R.id.noticeText); Explanation = (TextView) findViewById(R.id.Explanation); Clock = (TextView) findViewById(R.id.tv_timer); Clock.setVisibility(0); TiHao = (TextView) findViewById(R.id.userQuestionNum); UserInput = (EditText) findViewById(R.id.useranswer); userquestion = (TextView) findViewById(R.id.userquestion); TestTitle = (List<Question>) this.getIntent().getSerializableExtra( "resource"); TiHao.setText("第" + TestTitle.get(Counter).getCountNumber() + "题"); userquestion.setText(TestTitle.get(Counter).getExercise()); Bundle temp = this.getIntent().getExtras(); total = TestTitle.size();// 总的题目数量 CorrectAndWrong.setText(right + "/" + total); userAnswer = new double[total]; for (int j = 0; j < total; j++) userAnswer[j] = 0.0; System.out.println("info" + temp.getString("difficulty")); if (temp.getString("difficulty").equals("Examination")) { noticeText.setText("\n这个模式是考试模式,在这个模式需要在 10 分钟内做完25道题目。\n"); new Thread(new MyThread()).start(); } if (temp.getString("difficulty").equals("Practice")) { minute = 44; noticeText.setText("\n这个模式是练习模式,在这个模式需要在 45 分钟内做完50道题目。\n"); new Thread(new MyThread()).start(); } } @SuppressLint("HandlerLeak") final Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: if (recleantime == 0) { if (minute == 0) { // 处理时间到了之后的跳转 ----一个dialog textView Clock.setText("00:00"); preBtn.setEnabled(false); nextBtn.setEnabled(false); subBtn.setEnabled(false); DialogType(); break; } recleantime = 59; minute--; } recleantime--; if (recleantime < 10)// 时间格式 00:00 { if (minute > 11) Clock.setText("" + minute + ":0" + recleantime); else Clock.setText("" + 0 + minute + ":0" + recleantime); } else { if (minute < 10) Clock.setText("" + 0 + minute + ":" + recleantime); else Clock.setText("" + minute + ":" + recleantime); } } super.handleMessage(msg); } }; class MyThread implements Runnable { @Override public void run() { while (true) { try { Thread.sleep(1000); Message message = new Message(); message.what = 1; handler.sendMessage(message); } catch (InterruptedException e) { e.printStackTrace(); } }// while 的右耳朵. } } /** 处理点击事件 上一题、下一题、以及提交 **/ public void onclick(View v) { switch (v.getId()) { // 注意处理 没填写答案提交的情况. case R.id.submitButton: if (subBtn.getText().equals("Submit")) { // 跳转至一个评分界面! Toast.makeText(this, "finish !", Toast.LENGTH_LONG).show(); Intent intentScore = new Intent(TestView.this, Score.class); Bundle bundleScore = new Bundle(); bundleScore.putString("rightnumber", String.valueOf(right) .toString()); bundleScore.putString("wrongnumber", String.valueOf(wrong) .toString()); intentScore.putExtras(bundleScore); startActivity(intentScore); } else { if (!secondSubmit) { UserAnswer = UserInput.getText().toString(); // 正则表达式来判断输入的格式. Pattern pattern = Pattern .compile("^[-+]?[0-9]+(\\.[0-9]+)?$"); Matcher matcher = pattern.matcher(UserAnswer); while (!matcher.find()) { Toast.makeText(TestView.this, "Wrong format ", Toast.LENGTH_LONG).show(); subBtn.setEnabled(false); } if (matcher.find()) subBtn.setEnabled(true); double t = Double.parseDouble(TestTitle.get(Counter) .getAnswer()); double s = Double.parseDouble(UserAnswer); userAnswer[Counter] = s;// 对错都记录下来. if (t == s) { Toast.makeText(TestView.this, " Right ", Toast.LENGTH_SHORT).show(); right = right + 1; CorrectAndWrong.setText(right + "/" + total); rightNumber.setText("答对" + right + "题"); } else { wrong = wrong + 1; Explanation.setText(TestTitle.get(Counter) .getExercise() + " = " + TestTitle.get(Counter).getAnswer()); Toast.makeText(TestView.this, "Wrong ", Toast.LENGTH_SHORT).show(); wrongNumber.setText("答错" + wrong + "题"); } secondSubmit = true; } else Toast.makeText(TestView.this, "已经提交了", Toast.LENGTH_SHORT) .show(); // 做到最后一题之后才会执行这个地方判断是否可以提交试卷 String lack = "第"; int ifSubmit = 0; for (int j = 0; j < total; j++) if (userAnswer[j] == 0.0) { ifSubmit = j + 1; lack = lack + ifSubmit + "、"; } lack = lack + "题没做."; if (ifSubmit == 0) { subBtn.setText("Submit"); } else if (Counter == TestTitle.size() - 1)// 只要曾经访问过最后一题就开始提示未做完. judge = true; if (judge && ifSubmit != 0) Toast.makeText(this, lack, Toast.LENGTH_LONG).show(); } break; case R.id.next: Counter++; // Log.i("info", "" + Counter); if (Counter > TestTitle.size() - 1) { Toast.makeText(TestView.this, "已经是最后一题了 ", Toast.LENGTH_SHORT) .show(); Counter = Counter - 1; } else {// 在最后一题的时候点击下一题. secondSubmit = true; if (userAnswer[Counter] == 0) { secondSubmit = false; UserInput.setEnabled(true); UserInput.setText(""); } else { UserInput.setText(String.valueOf(userAnswer[Counter])); UserInput.setEnabled(false); } // System.out.println( String.valueOf(userAnswer[Counter]) ); TiHao.setText("第" + TestTitle.get(Counter).getCountNumber() + "题"); userquestion.setText(TestTitle.get(Counter).getExercise()); } Explanation.setText(""); break; case R.id.previous: Counter--; // Log.i("info", "" + Counter);在第一题的时候就点击上一题目 if (Counter < 0) { Toast.makeText(TestView.this, "已经是第一题了 ", Toast.LENGTH_SHORT) .show(); Counter = Counter + 1; } else { secondSubmit = true;// 切换题目时假设已经作答了,把提交按钮置为false. 然后再判断假设为真还是假 if (userAnswer[Counter] == 0) { secondSubmit = false; UserInput.setEnabled(true); UserInput.setText(""); } else { UserInput.setText(String.valueOf(userAnswer[Counter])); UserInput.setEnabled(false); } TiHao.setText("第" + TestTitle.get(Counter).getCountNumber() + "题"); /** 显示题号 **/ userquestion.setText(TestTitle.get(Counter).getExercise()); /** 显示题目 **/ } // UserInput.setText("");// 可以建立一个数据保存用户答案,返回时候可以查看. Explanation.setText(""); break; } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: startActivity(new Intent(TestView.this, APP.class)); break; } return super.onOptionsItemSelected(item); } // 定义一个Dialog 提示时间到 public void DialogType() { Dialog TypeDialog; TypeDialog = new AlertDialog.Builder(this, R.style.dialog) .setTitle("Time out ! ") .setItems(R.array.Choice, new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialoginterface, int select) { switch (select) { case 0: startActivity(new Intent(TestView.this, APP.class)); break; } } }).create(); TypeDialog.show(); } }
package com.app.senior_calculator; import java.math.BigDecimal; import java.util.EmptyStackException; import java.util.Stack; import android.util.Log; // 测试匹配否 // 特殊加减乘除 + - × ÷ // 特殊正负 ﹢﹣ // 普通加减乘除正负 + - * / + - public class MyCalculate { private static String expression; // 后缀式 private String suffix; // 特殊左括号 final static char LEFT_NORMAL = '('; // 特殊右括号 final static char RIGHT_NORMAL = ')'; // 特殊负号 final static char MINUS = '-'; // 特殊加号 final static char ADD = '+'; // 特殊乘法 final static char MUL = 'x'; // 特殊除法 final static char DIV = '/'; // 特殊减法 final static char SUB = '-'; // 特殊等于号 final static char equ = '='; public static String getExpression() { return expression; } // 返回后缀 public String getSuffix() { return suffix; } public void setExpression(String equation) { expression = equation; createSuffix(); } public MyCalculate(String equation) { expression = equation; createSuffix(); } public MyCalculate() { expression = ""; suffix = ""; } /** * 判断括号有没有匹配 * 匹配方法:遇到左括号进栈,遇到右括号出栈并且比对出栈的括号 * */ public boolean isBalanced() { Stack<Character> store = new Stack<Character>(); store.clear(); char c; for(int i=0; i<expression.length(); i++) { c = expression.charAt(i); switch(c) { case LEFT_NORMAL: { store.push(expression.charAt(i)); break; } case RIGHT_NORMAL: { if(store.isEmpty() || store.pop()!= LEFT_NORMAL) { return false; } break; } } } if(store.isEmpty()) { return true; } else { return false; } } // /** // * 判断括号是否合法 ,前提这一步是在括号匹配的情况下才进行 // * 括号合法法则:左括号不能在算式最后一个位置,右括号不能在第一个位置, // * 左括号的位置的下一个位置上的字符不能为运算符, // * 右括号的位置的上一个位置上的字符不能为运算符。 // * @return // */ // public boolean bracketLegal() // { // String[] answer; // if(false == balanced) // { // return false; // } // String str = expression.trim(); // for(int index=0; index<str.length(); index++) // { // // if(str.charAt(index) == LEFT_NORMAL) // 左括号情况 // { // // char c = str.charAt(index+1); // if(!((index<str.length()-1) && // (isNum(c)))) // { // return false; // } // // }else if(str.charAt(index) == RIGHT_NORMAL) // 右括号情况 // { // // char c = str.charAt(index-1); // if(!(index>0 && isNum(c))) // { // return false; // } // // } // // } // return true; // } // // /** // * 运算符不能在第一个位置和最后一个位置 // * 而且运算符不能连着写 例如:+- // * @return // */ // private boolean operatorLegal() // { // String str = expression.trim(); // for(int index=0; index<str.length(); index++) // { // if(isOperator(str.charAt(index))) // { // if(index==0 || index==(str.length()-1)) // { // return false; // } // if( !isNum(str.charAt(index-1)) && !isNum(str.charAt(index+1))) // { // return false; // } // // } // } // return true; // // } // private static boolean isOperator(char ope) { if(ope == ADD || ope==SUB ||ope == MUL || ope == DIV) { return true; } return false; } private static boolean isNum(char c) { if(c>='0' && c<='9') { return true; } return false; } // 中缀式转后缀式 public String createSuffix() { Stack<String> stack = new Stack<String>(); String exp = expression.trim(); String suf = ""; int i = 0; char c; while(i < exp.length()) { c = exp.charAt(i); if(c == LEFT_NORMAL) // 左括号 { stack.push(LEFT_NORMAL+""); } else if(isFit(c)) // 符合数字的一部分 { String num = ""; while(i<exp.length() && isFit(exp.charAt(i)) ) { num+=exp.charAt(i); i++; } suf += (num + " "); //后缀 i--; }else if(c == ADD || c == SUB || c == MUL ||c == DIV) // 运算符 { while(true) { if(stack.isEmpty()) { break; } if(stack.peek().equals(""+LEFT_NORMAL)) { break; } if(compare(stack.peek().charAt(0),c)) { break; } suf += (stack.pop()+" "); // 后缀 } stack.push(c+""); } else if(c == RIGHT_NORMAL) { while(!stack.isEmpty()) { if(stack.peek().equals(""+LEFT_NORMAL)) { stack.pop(); break; } suf += (stack.pop() + " "); // 后缀 } } i++; } while(!stack.isEmpty()) { suf += (stack.pop() + " "); // 后缀 } this.suffix = suf; return suf; } /** * 判断是否符合数字的一部分 * @param digit * @return 符合返回true 否则返回false */ private boolean isFit(char digit) { if(digit>='0' && digit<='9'||digit ==MINUS||digit=='.' ) { return true; } return false; } // 栈中运算符与将要读取的运算符作比较 // 返回true指示栈中运算符优先级大于将要读取运算符 // 其他的低于或等于都返回false private boolean compare(char stackOpe, char nextOpe) { int v1 = value(stackOpe); int v2 = value(nextOpe); if( v1 < v2) { return true; } return false; } // 运算符优先级 private int value(char ope) { if(ope==ADD || ope==SUB) { return 1; } else if(ope==MUL || ope==DIV) { return 2; } else { return 0; } } /** * @param suffix 后缀式 * @return 利用后缀式算出结果 */ public String getResult() { suffix = suffix.replace(MINUS, '-'); String[] str = suffix.split(" "); Stack<String> valueStack = new Stack<String>(); for(int i=0; i<str.length; i++) { // 遇到运算符出栈 if(str[i].equals(ADD+"") || str[i].equals(SUB+"") || str[i].equals(MUL+"") || str[i].equals(DIV+"")) { String rightNum; String leftNum; try { rightNum = valueStack.pop(); leftNum = valueStack.pop(); String result = calc(leftNum,rightNum,str[i]); valueStack.push(result); }catch(EmptyStackException empty) { return "算式出现异常"; } } else { // 遇到数字进栈 valueStack.push(str[i]); } } if(!valueStack.isEmpty()) { return valueStack.pop(); } return "栈为空 ,出现错误!"; } public static String calc(String leftNum, String rightNum, String ope) { BigDecimal bigLeftNum = null; BigDecimal bigRightnum = null; try { bigLeftNum = new BigDecimal(leftNum); bigRightnum = new BigDecimal(rightNum); }catch(NumberFormatException e) { return "算式出现异常"; } switch(ope.charAt(0)) { // 处理加法 case ADD:return bigLeftNum.add(bigRightnum).toString(); // 处理减法 case SUB:return bigLeftNum.subtract(bigRightnum).toString(); // 处理乘法 case MUL:return bigLeftNum.multiply(bigRightnum).toString(); // 处理乘法 case DIV: { if(bigRightnum.doubleValue()==0) { return "除数为零"; } // 20为小数点后的位数 String result = bigLeftNum.divide(bigRightnum,20,BigDecimal.ROUND_DOWN).toString(); int mark = 0; if( (mark = result.indexOf('.'))!=-1) { for(int i=mark; i<result.length(); i++) { if(result.charAt(i)!='0') { mark = i; } } Log.d("mark--1 :", mark+""); if(result.charAt(mark)=='.') { mark -= 1; } Log.d("mark--2 :", mark+""); Log.d("result", result.substring(0,mark+1)); result = result.substring(0,mark+1); return result; } else { return result; } } } return null; } // 测试括号匹配 - — public static void main(String[] s) { String str1 = "﹙5.3+3﹚×﹙3+8﹚"; String str2 = "[{}]{}"; String str3 = "({}{})"; String str4 = "16.2+(6.72-4.25)-3.72"; String str5 = "(((10+7)*(20/30))-(2*40))"; String str6 = "12"; MyCalculate cal = new MyCalculate(str1); System.out.println("匹配:"+cal.isBalanced()); System.out.println("后缀:"+cal.getSuffix()); String reult = cal.getResult(); System.out.println("结果: "+reult); } }
package com.app.senior_calculator; import java.io.Serializable; public class Question implements Serializable{ static final long serialVersionUID = -4320724374354337825L; private String Exercise; private String Answer; private int CountNumber; public Question(String exercise,String answer, int countNumber) { this.Answer=answer; this.Exercise=exercise; this.CountNumber=countNumber; } public Question() { this.Exercise=""; this.Answer=""; this.CountNumber=0; } public String getExercise() { return Exercise; } public void setExercise(String exercise) { this.Exercise = exercise; } public String getAnswer() { return Answer; } public void setAnswer(String answer) { Answer = answer; } public int getCountNumber() { return CountNumber; } public void setCountNumber(int countNumber) { CountNumber = countNumber; } }
package com.app.senior_calculator; import java.math.BigDecimal; import java.util.List; import java.util.Random; public class CreateEFraction { private MyCalculate calculator = new MyCalculate(); public void createYouExercisess(int number, List<Question> question) { for (int i = 0; i < number; i++) { String timu = createOperation(); calculator.setExpression(timu); String daan = calculator.getResult(); daan = adjustResult(daan); question.add(new Question(timu, daan, i + 1)); // Log.i("info", question.get(i).getExercise() + "=" // + question.get(i).getAnswer() + " 第" // +question.get(i).getCountNumber()+"题"); } } /** 比较答案的对错,精度为0.001 **/ public String adjustResult(String CorrectResult) { BigDecimal correctAnswer = new BigDecimal(CorrectResult); double cAnswer; cAnswer = correctAnswer.doubleValue(); int temp = (int) Math.round(cAnswer * 1000); cAnswer = temp / 1000.0; String answer = String.valueOf(cAnswer); return answer; } public String createOperation() { Random seed = new Random(); final String ADD = "+" + ""; final String MINUS = "-" + ""; final String MULTIPLY = "x" + ""; final String DEVIDE = "/" + ""; // 操作数的个数.而且最多为五个,默认三个操作数 int number = 3; String datas[] = new String[5]; String op[] = new String[5]; /** 生成 操作数个数 **/ int numberSeeder = seed.nextInt(4) + 1; if (numberSeeder == 1) number = 3; else if (numberSeeder == 2 || numberSeeder == 4) number = 4; else if (numberSeeder == 3) number = 5; /** 生成 操作数 跟 符号 **/ for (int i = 0; i < number; i++) { int jud = seed.nextInt(100); if (jud < 20) { datas[i] = fraction(); } else if (jud < 100) { datas[i] = integerCreater(); } if (i < number - 1) { /** 操作数的个数都是比符号的个数多一个 **/ int judp = seed.nextInt(4) + 1; if (judp == 1) op[i] = ADD; else if (judp == 2) op[i] = MINUS; else if (judp == 3) op[i] = MULTIPLY; else if (judp == 4) op[i] = DEVIDE; } } return createBrackets(datas, op, number); } /** create an integer **/ public String integerCreater() { Random seed = new Random(); String data; data = String.valueOf(seed.nextInt(100) + 1); return data; } /** create a fraction **/ public String fraction() { final String DEVIDE = "/" + ""; final String leftear = "(" + ""; final String rightear = ")" + ""; int First = 1, second = 1; Random seeder = new Random(); First = seeder.nextInt(10) + 1;// 分子 second = seeder.nextInt(10) + 1;// 分母 return leftear + First + DEVIDE + second + rightear; } /** brackets block 操作数据数组 、 操作符 、 个数 **/ public String createBrackets(String datas[], String operator[], int number) { final String leftear = "(" + ""; final String rightear = ")" + ""; Random seeder = new Random(); String bracketOperation = null; switch (number) { case 3: if (seeder.nextInt() / 2 == 0) bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2]; else bracketOperation = datas[0] + operator[0] + leftear + datas[1] + operator[1] + datas[2] + rightear; break; case 4: int temp = seeder.nextInt(21) + 1; temp = temp % 7 + 1; switch (temp) { case 1:// (a+b)x(a+b) bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + leftear + datas[2] + operator[2] + datas[3] + rightear; break; case 2:// ((a+b)+b)+b bracketOperation = leftear + leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + rightear + operator[2] + datas[3]; break; case 3:// (a+(a+b))+b bracketOperation = leftear + datas[0] + operator[0] + leftear + datas[1] + operator[1] + datas[2] + rightear + rightear + operator[2] + datas[3]; break; case 4:// (a+b)+a+b bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + operator[2] + datas[3]; break; case 5:// a+b+(a+b) bracketOperation = datas[0] + operator[0] + datas[1] + operator[1] + leftear + datas[2] + operator[2] + datas[3] + rightear; break; case 6:// a+(a+b)+b bracketOperation = datas[0] + operator[0] + leftear + datas[1] + operator[1] + datas[2] + rightear + operator[2] + datas[3]; break; case 7:// (a+b+c)+a bracketOperation = leftear + datas[0] + operator[0] + datas[1] + operator[1] + datas[2] + rightear + operator[2] + datas[3]; break; } break; case 5: int dicision = seeder.nextInt(33) + 1; dicision = dicision % 9 + 1; switch (dicision) { case 1:// (a+(a+b))+a+b bracketOperation = leftear + datas[0] + operator[0] + leftear + datas[1] + operator[1] + datas[2] + rightear + rightear + operator[2] + datas[3] + operator[3] + datas[4]; break; case 2:// ((a+b)+a)+a+a bracketOperation = leftear + leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + rightear + operator[2] + datas[3] + operator[3] + datas[4]; break; case 3:// (a+b)x(a+b)+a bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + leftear + datas[2] + operator[2] + datas[3] + rightear + operator[3] + datas[4]; break; case 4:// (a+b)x(a+b+a) bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + leftear + datas[2] + operator[2] + datas[3] + operator[3] + datas[4] + rightear; break; case 5:// (a+b)x(a+b+c) bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + leftear + datas[2] + operator[2] + datas[3] + operator[3] + datas[4] + rightear; break; case 6:// (a+b)+a+(a+b) bracketOperation = leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + operator[2] + leftear + datas[3] + operator[3] + datas[4] + rightear; break; case 7:// ((a+b)+a)X(a+b) bracketOperation = leftear + leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + rightear + operator[2] + leftear + datas[3] + operator[3] + datas[4] + rightear; break; case 8:// (((a+b)+c)+d)+e bracketOperation = leftear + leftear + leftear + datas[0] + operator[0] + datas[1] + rightear + operator[1] + datas[2] + rightear + operator[2] + datas[3] + rightear + operator[3] + datas[4]; break; case 9:// a+(a+b+c)+e bracketOperation = datas[0] + operator[0] + leftear + datas[1] + operator[1] + datas[2] + operator[2] + datas[3] + rightear + operator[3] + datas[4]; break; } break; } return bracketOperation; } }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".APP" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:background="@drawable/b1" android:gravity="center" android:orientation="vertical" > <Button android:id="@+id/Help" android:layout_width="140dp" android:layout_height="55dp" android:background="@drawable/button_selector" android:onClick="onclick" android:text="@string/help_text" android:textSize="30sp" /> <Button android:id="@+id/StartTest" android:layout_width="140dp" android:layout_height="55dp" android:layout_marginTop="15dp" android:background="@drawable/button_selector" android:onClick="onclick" android:text="@string/Start_Text" android:textSize="30sp" /> <Button android:id="@+id/Medol" android:layout_width="140dp" android:layout_height="55dp" android:background="@drawable/button_selector" android:onClick="onclick" android:text="@string/Model_Text" android:textSize="30sp" android:layout_marginTop="15dp"/> <Button android:id="@+id/Exit" android:layout_width="140dp" android:layout_height="55dp" android:layout_marginTop="15dp" android:background="@drawable/button_selector" android:onClick="onclick" android:text="@string/Special_Text" android:textSize="30sp" /> </LinearLayout> </RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="@drawable/tbg"> <Button android:id="@+id/submitButton" style="?android:attr/borderlessButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:onClick="onclick" android:text="@string/userSubmitText" /> <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="35dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="@drawable/button_selector" > <TextView android:id="@+id/tv_timer " android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:drawableLeft="@drawable/clock_gray" android:drawablePadding="2dp" android:gravity="center" android:text="@string/TimeText0000" android:textColor="@color/black" android:textStyle="bold" /> <TextView android:id="@+id/CorrectAndWrong" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/tv_timer " android:layout_alignBottom="@+id/tv_timer " android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:text="@string/rightandwrongText" android:textColor="@color/black" android:textStyle="bold" /> <TextView android:id="@+id/userQuestionNum" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/tv_timer " android:layout_alignParentLeft="true" android:layout_marginLeft="10dp" android:text="@string/questionnumberText" android:textColor="@color/black" android:textStyle="bold" /> </RelativeLayout> <Button android:id="@+id/next" style="?android:attr/borderlessButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:onClick="onclick" android:text="@string/nextButtonText" /> <Button android:id="@+id/previous" style="?android:attr/borderlessButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:onClick="onclick" android:text="@string/previousButtonText" /> <TextView android:id="@+id/noticeText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/relativeLayout1" android:ems="10" android:gravity="center" /> <TextView android:id="@+id/Explanation" android:layout_width="fill_parent" android:layout_height="90dp" android:layout_alignParentLeft="true" android:layout_below="@+id/useranswer" android:layout_marginTop="28dp" android:background="@drawable/button_selector" android:ems="10" android:gravity="center" android:hint="@string/explainationText" /> <TextView android:id="@+id/userquestion" android:layout_width="fill_parent" android:layout_height="60dp" android:layout_alignParentLeft="true" android:layout_below="@+id/noticeText" android:layout_marginTop="14dp" android:ems="10" android:gravity="center" android:hint="@string/questionText" /> <TextView android:id="@+id/wrongNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/next" android:layout_alignLeft="@+id/next" android:text="@string/wrongText" android:textColor="@color/black" android:textStyle="bold" /> <EditText android:id="@+id/useranswer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/userquestion" android:layout_marginTop="46dp" android:background="@drawable/button_selector" android:ems="10" android:gravity="center" android:hint="@string/userInputTips" /> <TextView android:id="@+id/userEqual" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/userquestion" android:layout_centerHorizontal="true" android:text="@string/equalText" android:textSize="30sp" /> <TextView android:id="@+id/rightNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/submitButton" android:layout_toRightOf="@+id/submitButton" android:text="@string/rightText" android:textColor="@color/black" android:textStyle="bold" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg" > <TextView android:id="@+id/wrong" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="72dp" android:layout_marginTop="79dp" android:text="@string/wrongText" /> <TextView android:gravity="center" android:id="@+id/theEndtext" android:layout_width="fill_parent" android:layout_height="40dp" android:text="@string/terminalText" /> <TextView android:id="@+id/rnumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/wrong" android:layout_below="@+id/wrong" android:layout_marginTop="40dp" android:text="@string/rightandwrongText" /> <TextView android:layout_marginLeft="20dp" android:id="@+id/ToatlText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="@string/scoreText" /> <Button android:id="@+id/Back" android:onClick="onclick" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/score" android:layout_centerHorizontal="true" android:layout_marginTop="52dp" android:background="@drawable/button_selector" android:text="@string/userSubmitText" /> <TextView android:id="@+id/wnumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/rnumber" android:layout_alignBottom="@+id/rnumber" android:layout_alignRight="@+id/right" android:text="@string/rightandwrongText" /> <TextView android:id="@+id/right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/wrong" android:layout_alignBottom="@+id/wrong" android:layout_marginRight="24dp" android:layout_toLeftOf="@+id/Back" android:text="@string/rightText" /> <TextView android:id="@+id/score" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/Back" android:layout_below="@+id/ToatlText" android:text="@string/rightandwrongText" /> </RelativeLayout>
APP运行截图;
主界面
选择难度
选择模式
答题界面
答题答对界面
答题答错界面
考试结束界面
计时结束后
团队 github 是:https://github.com/be821/MyCat 里面的little_four_operation就是该项目的代码.
心得总结;
这次的课程设计比上学期的好很多,毕竟这学期有一门专门学习Android的课程,当然基于源头,都是JAVA语言,所以每一门课程之间的联系很紧密。
我们班大部分都是做四则运算APP,我们也有去了解其他组的功能,我们也有我们的考虑,我们侧重于APP的实用性和简洁性,比如背景音乐功能,我觉得用户做题需要思考,背景音乐华而不实。还有错题册功能,四则运算是基础运算,个人觉得没必要弄一个错题本,本身APP是随机出题,锻炼的是用户第一时间的计算逻辑能力,如果反复的做错题,意义不大。
我们团队的APP,解决了助教所说的带有括号的四则运算,判断运算的优先级,感谢我们的队员陈健同学。让我们的APP上升了一个档次。在团队开发的过程中,我也学到了很多。用博客园记录APP开发历程似乎是一种习惯了,感谢杜云梅老师。 github这个也是第一次接触,开阔了视野,长了见识。