您的位置:首页 > 其它

2.四则运算03

2016-03-26 18:40 197 查看
题目
老师提出了新的要求:
1、学生写的程序必须能判定用户的输入答案是否正确,
例如程序输出:20 – 5 = ?用户输入15,那么程序就会反馈正确,然后继续出题。直到 30 道题目结束,程序最后告诉用户作对了几道题。
2、程序必须能处理四种运算的混合算式;
20 – 5 * 2 =? 正确答案是10.
20– 5 * 2 + 9 / 3 = ? 正确答案是13
注意:
连续的减法和除法,应该遵守左结合的规定。
连续除法要打括号,否则会引起歧义
设计思想:
1. 用二叉树,生成数字和符号(每个叶子节点都是数字,每个父节点都是符号)
2. 正确的优先级'('')'>'*''/'>'+''-'

假设待去括号的表达式为(m1 op1 n1) op (m2 op2 n2)这里m1、n1、m2、m2可能自身就是个表达式,也可能是数字,op、op1、op2为运算符

1、若op'/',则 (m2 op2 n2)的括号必须保留;

2、若op'*''-',如果op2'+''-',则(m2 op2 n2)的括号必须保留;

3、若op'*''/',如果op1'+''-',则(m1 op1 n1)的括号必须保留;

4除此之外,去掉括号不影响表达式的计算顺序。

3. 判断是否正确:(int 输入=String结果)涉及String转换为intint n=Integer.parseInt(结果);输入=n.

4. 完成时间

代码:

package yunsuan04;

import java.util.*;//swing.//JOptionPane;

public class Test

{

public static void main(String args[])

{

System.out.println("欢迎使用本系统,本系统自动产生四则运算表达式.");

//JOptionPane.showMessageDialog(null,"欢迎使用本系统,本系统自动产生四则运算表达式。");

int count1=0;//答对的题目个数

int count2=0;//答错的题目个数

boolean flag;//判断答案的对错*/

double time1=System.currentTimeMillis();

BinaryTree bTree;

for(int i = 0; i < 10; i++)

{

bTree = new BinaryTree(2);

bTree.createBTree();

String result = bTree.CalAndVal();

int n=Integer.parseInt(result);

System.out.println(bTree.toString() + "=" + "答案:");//result);

Scanner in=new Scanner(System.in);

int d=in.nextInt();

if(d==n)

{

flag=true;

System.out.println("恭喜你,答对啦!");

++count1;

}

else{

flag=false;

++count2;

System.out.println("答错啦,再努力!");

}

}

double time2=System.currentTimeMillis();

int time=(int)((time2-time1)/1000);

if(count1>count2){

System.out.println("成绩不错,继续保持!");

}

else{

System.out.println("该努力啦,加油~~!");

}

System.out.println("答对的题有:"+count1+"个"+"\n"+"答错的题有:"+count2+"个"+"\n"+"所用时间为:"+time+"秒");//最后统计答对题数答错的题目的个数

}

}

package yunsuan04;

import java.util.ArrayList;

public class BinaryTree

{

private TreeNode root;

private int num;

private ArrayList<TreeNode> opeList = new ArrayList<TreeNode>();

public BinaryTree(int num){

this.num = num;

}

public int getNum(){

return num;

}

public void setNum(int num){

this.num = num;

}

public void setTreeNode(TreeNode root){

this.root = root;

}

/**

* 获取最终的表达式,必须在CalAndVal()方法后调用

*

* @return str

*/

public String toString(){

String str = root.toString();

str = str.substring(1, str.length()-1);

return str;

}

/**

* 计算并验证表达式

*

* @return result

*/

public String CalAndVal(){

return root.getResult();

}

/**

* 计算二叉树的深度(层数)

*

* @return deep

*/

public int getDeep(){

int i = this.num;

int deep = 2;

while(i/2 > 0){

deep++;

i /= 2;

}

return deep;

}

/**

* 生成二叉树

*

*/

public void createBTree(){

TreeNode lchild, rchild, lnode, rnode;

if(num == 1){

lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

root = new TreeNode(String.valueOf(Ran.getOperator()), lchild, rchild);

}

else{

int num1 = 0;

int n = getDeep() - 3;

boolean[] place = Ran.getChildPlace(num);

root = new TreeNode(String.valueOf(Ran.getOperator()), null, null);

opeList.add(root);

for(int i = 0; i < n; i++){

for(int j = 0; j < (int)Math.pow(2, i); j++, num1++){

lchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);

rchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);

opeList.get(j + num1).setChild(lchild, rchild);

opeList.add(lchild);

opeList.add(rchild);

}

}

for(int i = 0; i < place.length; i++){

if(place[i]){

lnode = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

rnode = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

if(i%2 == 0){

lchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);

opeList.add(lchild);

opeList.get(num1).setLchild(lchild);

}

else{

rchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);

opeList.add(rchild);

opeList.get(num1).setRchild(rchild);

}

}

else{

if(i%2 == 0){

lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

opeList.get(num1).setLchild(lchild);

}

else{

rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);

opeList.get(num1).setRchild(rchild);

}

}

num1 = num1 + i%2;

}

}

}

}

2

package yunsuan04;

import java.util.Random;

public class Ran {

/* 获取随机的符号

* @return operator

*/

public static char getOperator(){

char operator = 0;

Random ran = new Random();

int i = ran.nextInt(4);

switch(i){

case 0:

operator = '+';

break;

case 1:

operator = '-';

break;

case 2:

operator = '*';

break;

case 3:

operator = '/';

break;

}

return operator;

}

/**

* 根据输入的范围获取随机数

*

* @param max

* @return number

*/

public static int getNumber(int max){

int number = 0;

Random ran = new Random();

number = ran.nextInt(max+1);

return number;

}

/**

* 根据运算符的个数随机产生子节点的位置

*

* @param num

* @return childPlace

*/

public static boolean[] getChildPlace(int num){

int d = 0;

int size = 0, j=1;

while(num >= (int)Math.pow(2, j)){

j++;

}

d = (int)Math.pow(2, j) - 1 - num;

size = (int)Math.pow(2, j-1);

boolean[] k = new boolean[size];

for(int i = 0; i < size; i++){

k[i] = true;

}

for(int i = 0; i < d; i++){

Random ran = new Random();

int f = ran.nextInt(size);

while(k[f] == false)

{

f = ran.nextInt(size);

}

k[f] = false;

}

return k;

}

}

3

package yunsuan04;

public class TreeNode {

private String str;

private TreeNode rchild = null;

private TreeNode lchild = null;

public TreeNode(String str){

this.str = str;

}

public TreeNode(String str, TreeNode lchild, TreeNode rchild){

this.str = str;

this.rchild = rchild;

this.lchild = lchild;

}

public void setChild(TreeNode lchild, TreeNode rchild){

this.lchild = lchild;

this.rchild = rchild;

}

public TreeNode getRchild() {

return rchild;

}

public void setRchild(TreeNode rchild) {

this.rchild = rchild;

}

public TreeNode getLchild() {

return lchild;

}

public void setLchild(TreeNode lchild) {

this.lchild = lchild;

}

public String getStr(){

return str;

}

/**

* 获取每个节点的运算结果,并检验除法

* 1)除数为0

* 2)不能整除

* 出现以上两种情况的话将该运算符转换成其他三种运算符

*

* @return result

*/

public String getResult(){

if(hasChild()){

switch(str){

case "+":

return String.valueOf(Integer.parseInt(getLchild().getResult()) + Integer.parseInt(getRchild().getResult()));

case "-":

return String.valueOf(Integer.parseInt(getLchild().getResult()) - Integer.parseInt(getRchild().getResult()));

case "*":

return String.valueOf(Integer.parseInt(getLchild().getResult()) * Integer.parseInt(getRchild().getResult()));

case "/":

if(getRchild().getResult().equals("0")){

while(str.equals("/")){

str = String.valueOf(Ran.getOperator());

}

return this.getResult();

}

else if(Integer.parseInt(getLchild().getResult()) % Integer.parseInt(getRchild().getResult()) != 0){

while(str.equals("/")){

str = String.valueOf(Ran.getOperator());

}

return this.getResult();

}

else

return String.valueOf(Integer.parseInt(getLchild().getResult()) / Integer.parseInt(getRchild().getResult()));

}

}

return str;

}

/**

* 先对每个运算式添加括号,然后根据去括号法则,去掉多余的子式的括号

*

* @return string

*/

public String toString(){

String Lstr = "", Rstr = "", Str = "";

if(hasChild()){

//右子树如果有孩子,说明右子树是一个表达式,而不是数字节点。

if(getRchild().hasChild()){

//判断左邻括号的运算符是否为'/'

if(str.equals("/")){

//获取右子树的表达式,保留括号

Rstr = getRchild().toString();

}

//判断左邻括号的运算符是否为'*'或'-'

else if(str.equals("*") || str.equals("-")){

//判断op是否为'+'或'-'

if(getRchild().str.equals("+") || getRchild().str.equals("-")){

Rstr = getRchild().toString();

}

else{

//获取右子树的表达式,并且去括号

Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);

}

}

else{

//右子树除此之外都是可以去括号的。

Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);

}

}

else{

Rstr = getRchild().str;

}

//左子树的情况同右子树类似

if(getLchild().hasChild()){

if(str.equals("*") || str.equals("/")){

if(getLchild().str.equals("+") || getLchild().str.equals("-")){

Lstr = getLchild().toString();

}

else{

Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);

}

}

else{

Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);

}

}

else{

Lstr = getLchild().str;

}

//获取当前的运算式,并加上括号

Str = "(" + Lstr + str + Rstr + ")";

}

else{

//若没有孩子,说明是数字节点,直接返回数字

Str = str;

}

return Str;

}

public boolean hasChild(){

if(lchild == null && rchild == null)

return false;

else

return true;

}

}

截图:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: