结对小伙伴:张勋 http://www.cnblogs.com/X-knight/
下载地址:http://files.cnblogs.com/files/wangjianly/WangJian.apk
在上次四则运算的基础上,将编写的四则运算发布成安卓版,具体实现功能如下:
1:是否有除数参与运算
2:是否有括号参与运算
3:产生的数值的范围(从1开始)
4:设定出题的数量
解决办法:
这个安卓的程序主要有两个界面,一个是对用户输入的要求进行判断,然后根据要求进行生成随机四则运算。另一个是答题界面。
代码:
第一个布局代码;
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="@drawable/first" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="有无乘除?" tools:ignore="HardcodedText" /> <RadioGroup android:id="@+id/rg_chufa" android:layout_width="fill_parent" android:layout_height="wrap_content" > <RadioButton android:id="@+id/chuafa_yes" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="有" tools:ignore="HardcodedText" /> <RadioButton android:id="@+id/chuafa_no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="无" tools:ignore="HardcodedText" /> </RadioGroup> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="有无括号?" tools:ignore="HardcodedText" /> <RadioGroup android:id="@+id/rg_kuohao" android:layout_width="fill_parent" android:layout_height="wrap_content" > <RadioButton android:id="@+id/kuohao_yes" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="有" tools:ignore="HardcodedText" /> <RadioButton android:id="@+id/kuohao_no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="无" tools:ignore="HardcodedText" /> </RadioGroup> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输入数值范围:" tools:ignore="HardcodedText" /> <EditText android:id="@+id/et_range" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="number" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="产生多少式子:" tools:ignore="HardcodedText" /> <EditText android:id="@+id/et_exp_num" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="number" /> <Button android:id="@+id/btn_next" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="确认" tools:ignore="HardcodedText" /> </LinearLayout>
第二个布局界面:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="@drawable/beijing" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".SolutionActivity" android:orientation="vertical"> <TextView android:id="@+id/tv_num" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_exp" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输入结果:" tools:ignore="HardcodedText" /> <EditText android:id="@+id/et_ans" android:layout_width="fill_parent" android:layout_height="wrap_content" tools:ignore="TextFields" /> <Button android:id="@+id/okBtn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="确认" tools:ignore="HardcodedText" /> <Button android:id="@+id/nextBtn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下一题" tools:ignore="HardcodedText" /> </LinearLayout>
java文件1:
package com.wwwjjj.wangjian; //import java.awt.SystemColor; import java.util.HashMap; import java.util.Map; import java.util.Stack; import java.util.StringTokenizer; import java.util.regex.Pattern; public class Test { public double computeWithStack(String computeExpr) { //把表达式用运算符、括号分割成一段一段的,并且分割后的结果包含分隔符 StringTokenizer tokenizer = new StringTokenizer(computeExpr, "+-*/()", true); Stack<Double> numStack = new Stack<Double>(); //用来存放数字的栈 Stack<Operator> operStack = new Stack<Operator>(); //存放操作符的栈 Map<String, Operator> computeOper = this.getComputeOper(); //获取运算操作符 String currentEle; //当前元素 while (tokenizer.hasMoreTokens()) { currentEle = tokenizer.nextToken().trim(); //去掉前后的空格 if (!"".equals(currentEle)) { //只处理非空字符 if (this.isNum(currentEle)) { //为数字时则加入到数字栈中 numStack.push(Double.valueOf(currentEle)); } else { //操作符 Operator currentOper = computeOper.get(currentEle);//获取当前运算操作符 if (currentOper != null) { //不为空时则为运算操作符 while (!operStack.empty() && operStack.peek().priority() >= currentOper.priority()) { compute(numStack, operStack); } //计算完后把当前操作符加入到操作栈中 operStack.push(currentOper); } else {//括号 if ("(".equals(currentEle)) { //左括号时加入括号操作符到栈顶 operStack.push(Operator.BRACKETS); } else { //右括号时, 把左括号跟右括号之间剩余的运算符都执行了。 while (!operStack.peek().equals(Operator.BRACKETS)) { compute(numStack, operStack); } operStack.pop();//移除栈顶的左括号 } } } } } // 经过上面代码的遍历后最后的应该是nums里面剩两个数或三个数,operators里面剩一个或两个运算操作符 while (!operStack.empty()) { compute(numStack, operStack); } return numStack.pop(); } /** * 判断一个字符串是否是数字类型 * @param str * @return */ private boolean isNum(String str) { String numRegex = "^\\d+(\\.\\d+)?$"; //数字的正则表达式 return Pattern.matches(numRegex, str); } /** * 获取运算操作符 * @return */ private Map<String, Operator> getComputeOper() { return new HashMap<String, Operator>() { // 运算符 private static final long serialVersionUID = 7706718608122369958L; { put("+", Operator.PLUS); put("-", Operator.MINUS); put("*", Operator.MULTIPLY); put("/", Operator.DIVIDE); } }; } private void compute(Stack<Double> numStack, Stack<Operator> operStack) { Double num2 = numStack.pop(); // 弹出数字栈最顶上的数字作为运算的第二个数字 Double num1 = numStack.pop(); // 弹出数字栈最顶上的数字作为运算的第一个数字 Double computeResult = operStack.pop().compute( num1, num2); // 弹出操作栈最顶上的运算符进行计算 numStack.push(computeResult); // 把计算结果重新放到队列的末端 } /** * 运算符 */ private enum Operator { /** * 加 */ PLUS { @Override public int priority() { return 1; } @Override public double compute(double num1, double num2) { return num1 + num2; } }, /** * 减 */ MINUS { @Override public int priority() { return 1; } @Override public double compute(double num1, double num2) { return num1 - num2; } }, /** * 乘 */ MULTIPLY { @Override public int priority() { return 2; } @Override public double compute(double num1, double num2) { return num1 * num2; } }, /** * 除 */ DIVIDE { @Override public int priority() { return 2; } @Override public double compute(double num1, double num2) { return num1 / num2; } }, /** * 括号 */ BRACKETS { @Override public int priority() { return 0; } @Override public double compute(double num1, double num2) { return 0; } }; /** * 对应的优先级 * @return */ public abstract int priority(); /** * 计算两个数对应的运算结果 * @param num1 第一个运算数 * @param num2 第二个运算数 * @return */ public abstract double compute(double num1, double num2); } //符号函数 //------------------------------------------------------------- static String fuhao(int chu) { String fu; int num_3; if (chu == 1) { num_3 = ((int)(Math.random() * 100)) % 4; if (num_3 == 0) fu = "+"; else if (num_3 == 1) fu = "-"; else if (num_3 == 2) fu = "*"; else fu = "/"; return fu; } else { num_3 = ((int)(Math.random()*20)) % 2; if (num_3 == 0) fu = "+"; else fu = "-"; return fu; } } //分数函数 //------------------------------------------------------------- static String fenshu() { int a1 = 0, b1 = 0, a2 = 0, b2 = 0; a1 = ((int)(Math.random()*(97))); b1 = ((int)(Math.random()*100 - a1)) + a1 + 1; a2 = ((int)(Math.random()* (97))); b2 = ((int)(Math.random()* (100 - a2))) + a2 + 1; String first_a1, second_b1; String first_a2, second_b2; first_a1 = String.valueOf(a1); second_b1 = String.valueOf(b1); first_a2 = String.valueOf(a2); second_b2 = String.valueOf(b2); String all1 = ""; //随机产生四则运算符 int fu = 0; fu = ((int)(Math.random()*100)) % 2; if (fu == 0) { all1 = "(" + first_a1 + "/" + second_b1 + ")" + "+" + "(" + first_a2 + "/" + second_b2 + ")" ; } else if (fu == 1) { all1 = "(" + first_a1 + "/" + second_b1 + ")" + "-" + "(" + first_a2 + "/" + second_b2 + ")" ; } else if (fu == 2) { all1 = "(" + first_a1 + "/" + second_b1 + ")" + "*" + "(" + first_a2 + "/" + second_b2 + ")" ; } else { all1 = "(" + first_a1 + "/" + second_b1 + ")" + "/" + "(" + first_a2 + "/" + second_b2 + ")" ; } return all1; } /*private static String to_String(int b1) { // TODO Auto-generated method stub return null; }*/ //运算函数 //------------------------------------------------------------- String shu(int chu, int kuohao, int range) { int num_1, num_2; int geshu; int calculate_kuohao=3; String str_first, str_second; String all = ""; int ch1; geshu = ((int)(Math.random()*(4)) + 2); for (int i = 1; i <= geshu; i++) { num_1 = ((int)(Math.random()* (range))) + 1; str_first = String.valueOf(num_1); num_2 = ((int)(Math.random()*(range))) + 1; str_second = String.valueOf(num_2); if ((kuohao == 1)&&(calculate_kuohao!=0)) { ch1 = ((int)(Math.random()*(4))) + 1; switch (ch1){ case 1: { if (all == "") { all = str_first + fuhao(chu) + str_second; } else { all = str_first + fuhao(chu) + all; } }break; case 2: { if (all == "") { all = str_second + fuhao(chu) + str_first; } else { all = all + fuhao(chu) + str_first; } }break; case 3: { if (all == "") { all = "(" + str_first + fuhao(chu) + str_second + ")"; } else { all = "(" + str_first + fuhao(chu) + all + ")"; } calculate_kuohao = calculate_kuohao - 1; }break; case 4: { if (all == ""){ all = "(" + str_second + fuhao(chu) + str_first + ")"; } else { all = "(" + all + fuhao(chu) + str_first + ")"; } calculate_kuohao = calculate_kuohao - 1; }break; } } else { ch1 = ((int)(Math.random()*(2))) + 1; switch (ch1){ case 1: { if (all == "") { all = str_first + fuhao(chu) + str_second; } else { all = str_first + fuhao(chu) + all; } }break; case 2: { if (all == "") { all = str_second + fuhao(chu) + str_first; } else { all = all + fuhao(chu) + str_first; } }break; } } } return all ; } }
java文件2:
package com.wwwjjj.wangjian; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.RadioGroup; public class MainActivity extends Activity implements OnClickListener { private RadioGroup chufa; private RadioGroup kouhao; private EditText range; private EditText exp_num; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); chufa = (RadioGroup) findViewById(R.id.rg_chufa); kouhao = (RadioGroup) findViewById(R.id.rg_kuohao); range = (EditText) findViewById(R.id.et_range); exp_num = (EditText) findViewById(R.id.et_exp_num); btn = (Button) findViewById(R.id.btn_next); btn.setOnClickListener(this); } @Override public void onClick(View arg0) { // TODO Auto-generated method stub int chufaId = chufa.getCheckedRadioButtonId(); int kuohaoId = kouhao.getCheckedRadioButtonId(); Boolean haveChufa = false, haveKuohao = false; if (chufaId == R.id.chuafa_yes) haveChufa = true; if (kuohaoId == R.id.kuohao_yes) haveKuohao = true; int r = Integer.valueOf(range.getText().toString()); int en = Integer.valueOf(exp_num.getText().toString()); Intent intent =new Intent(MainActivity.this,SolutionActivity.class); Bundle bundle=new Bundle(); bundle.putBoolean("kuohao", haveKuohao); bundle.putBoolean("chufa", haveChufa); bundle.putInt("range", r); bundle.putInt("exp_num", en); intent.putExtras(bundle); startActivity(intent); } }
java文件3
package com.wwwjjj.wangjian; import java.math.BigDecimal; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class SolutionActivity extends Activity implements OnClickListener{ private TextView exp; private TextView tv_num; private EditText tv_ans; private Button okBtn; private Button nextBtn; private String expString; private Test test; private boolean haveChu; private boolean haveKuohao; private int range; private int exp_num; int chu=2,kuohao=2; int dui=0; int cuo=0; double ans; private double result2; private double result; private Integer myans; private int count=1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_solution); haveKuohao=getIntent().getBooleanExtra("kuohao", haveKuohao); haveChu=getIntent().getBooleanExtra("chufa", haveChu); if(haveChu)chu=1; if(haveKuohao)kuohao=1; range=getIntent().getIntExtra("range", range); exp_num=getIntent().getIntExtra("exp_num", exp_num); exp=(TextView)findViewById(R.id.tv_exp); tv_num=(TextView)findViewById(R.id.tv_num); tv_ans=(EditText)findViewById(R.id.et_ans); okBtn=(Button)findViewById(R.id.okBtn); nextBtn=(Button)findViewById(R.id.nextBtn); okBtn.setOnClickListener(this); nextBtn.setOnClickListener(this); //从java类中取出表达式到expString中 tv_num.setText("第"+count+++"题:"); test=new Test(); expString= test.shu(chu,kuohao,range); //将表达式显示到exp (exp.setText(表达式)) exp.setText(expString+"="); result2 = test.computeWithStack(expString); BigDecimal bg2=new BigDecimal(result2); result=bg2.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue(); } @Override public void onClick(View v0) { // TODO Auto-generated method stub if(v0==okBtn){ //从tv_ans中取出答案 //判断答案是否正确 //显示判断结果 myans=Integer.valueOf(tv_ans.getText().toString()); if(myans==result){ dui=dui+1; Toast.makeText(SolutionActivity.this, "回答正确,您已经答对了"+dui+"道题,答错了"+cuo+"道题", 0).show(); }else{ cuo=cuo+1; Toast.makeText(SolutionActivity.this, "回答错误,您已经答对了"+dui+"道题,答错了"+cuo+"道题", 0).show(); } }else if(v0==nextBtn){ tv_ans.setText(""); if(count>exp_num) finish(); //从java类中取出表达式 //将表达式显示到exp (exp.setText(表达式)) tv_num.setText("第"+count+++"题:"); expString= test.shu(chu,kuohao,range); //将表达式显示到exp (exp.setText(表达式)) exp.setText(expString+"="); result2 = test.computeWithStack(expString); BigDecimal bg2=new BigDecimal(result2); result=bg2.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue(); } } }
运行结果;
项目计划总结: | ||||||
日期\任务 | 听课 | 编写程序 | 查阅资料 | 日总计 | ||
星期一 | 4 | 2 | 6 | |||
星期二 | ||||||
星期三 | 3 | 2 | 5 | |||
星期四 | 4 | 2 | 6 | |||
星期五 | 2 | 2 | 4 | |||
星期六 | 1 | 1 | 1 | |||
星期日 | 3 | 0.5 | 3.5 | |||
周总计 | 16 | 9.5 | 25.5 | |||
时间记录日志: | ||||||
日期 | 开始时间 | 结束时间 | 中断时间 | 静时间 | 活动 | 备注 |
4月1日 | 14:00 | 16:10 | 10 | 120 | 查阅资料/编程 | 修改程序 |
4月2日 | 8:20 | 10:40 | 20 | 120 | 编写程序 | 将程序改为JAVA语言 |
4月3日 | 16:30 | 20:30 | 30 | 210 | 查阅资料 | 查资料和修改代码 |
4月4日 | 14:00 | 21:00 | 60 | 3600 | 编程 | 修改和编写代码 |
4月5日 | ||||||
4月6日 | 10:00 | 17:30 | 90 | 3600 | 调试 | 最终调试 |
18:00 | 18:30 | 30 | 博客 | 撰写博客 | ||
缺陷记录日志: | ||||||
日期 | 编号 | 引入阶段 | 排除阶段 | 修复时间&问题描述 | ||
4月1日 | 1 | 编码 | 编译 | 对原先的四则运算进行了修改,优化了代码 | ||
4月2日 | 编码 | 编译 | 将代码转化为JAVA语言 | |||
4月3日 | 2 | 编码 | 编译 | 对JAVA语言中出现的错误进行了修改和排除 | ||
4月4日 | 编码 | 编译 | 对JAVA语言中出现的错误进行了修改和排除 | |||
4月4日 | 编码 | 编译 | 排除错误 | |||
4月6日 | 3 | 编码 | 编译 | 进行最后的修改,对界面进行了美化 |
总结: 这次由于自己是第一次将c++编写的程序发布成Android版本,由于自己对Java语言掌握的额不是很好,所以在过程中,遇到了许多的困难,列入在界面之间进行参数的传递,以及添加监视空间等,通过查阅资料以及寻找相关的例子和询问其他同学,最终还是解决了自己所遇到的问题。