四则运算三

一、程序的设计思想

1)查重

   每三个元素划分为一组,来进行子表达式之间的查重,进行判断是否相同。

2)数据库连接、释放  

   获取数据库连接的方法是将注册数据库驱动,获得一个数据库的连接进行封装,返回一个数据库连接对象;另外,释放资源的方法是将释放查询数据库结果集对象、数据库操作对象和数据库连接对象进行封装。

二、源程序代码

package hh;

 

import java.util.Random;

import java.util.Scanner;

import java.util.Stack;

 

//分数类

class fraction {

    public int fenMu,fenZi;

 

    public int getFenMu() {

        return fenMu;

    }

 

    public void setFenMu(int fenMu) {

        this.fenMu = fenMu;

    }

 

    public int getFenZi() {

        return fenZi;

    }

 

    public void setFenZi(int fenZi) {

        this.fenZi = fenZi;

    }

 

    public fraction(int fenMu, int fenZi) {

        this.fenMu = fenMu;

        this.fenZi = fenZi;

        yueFen();

    }

     

    public fraction(){}

     

  //找出两数的最大公约数

    public int MaxCommon(int a,int b){

        //保证第一个参数大于第二个参数

        if(a<b)

        {

            int temp;

            temp=a;

            a=b;

            b=temp;

        }

        while(a%b!=0)   //在余数不为零时循环

        {

            int temp=a%b;

            a=b;

            b=temp;

        }

        return b;  //返回最大公约数

    }

     

    //找出两数的最小公倍数

    public int MinCommon(int a,int b){

        return a*b/MaxCommon(a,b);

    }

     

    //约分化简

    public void yueFen(){

        int y = 1;

        for(int i = fenZi;i > 1;i--){

            if(fenZi % i == 0 && fenMu % i == 0){

                y = i;

                break;

            }

        }

            fenZi /= y;

            fenMu /= y;

         

    }

     

    //计算(加)

    public fraction add(fraction b){

        fraction c = null;

        int newFenZi = this.fenZi * b.getFenMu() + this.fenMu * b.getFenMu();

        int newFenMu = this.fenMu * b.getFenMu();

        c = new fraction(newFenMu,newFenZi);

        return c;

    }

     

    //计算(减)

    public fraction subtract(fraction b){

        fraction c = null;

        int newFenZi = this.fenZi * b.getFenMu() - this.fenMu * b.getFenZi();

        int newFenMu = this.fenMu * b.getFenMu();

        c = new fraction(newFenMu,newFenZi);

        return c;

    }

     

    //计算(乘)

    public fraction multiply(fraction b){

        fraction c = null;

        int newFenZi = this.fenZi * b.getFenZi();

        int newFenMu = this.fenMu * b.getFenMu();

        c = new fraction(newFenMu,newFenZi);

        return c;

    }

     

    //计算(除)

    public fraction divide(fraction b){

        fraction c = null;

        int newFenZi = this.fenZi * b.getFenMu();

        int newFenMu = this.fenMu * b.getFenZi();

        c = new fraction(newFenMu,newFenZi);

        return c;

    }

     

    //输出分数形式

    public String toString(){

        if(fenZi != 0){

            return fenZi + "/" + fenMu;

        }

        return "0";

    }

     

}

 

public class kk {

    public static String[] Answer=new String[100];

    //生成整数计算式添加限制条件,type为运算式类型  0代表整数式,1代表真分数式

    public static String[] createYunSuanShi(int hasChengChu,int hasKuoHao,int hasFuShu,int hasYuShu,int minNum,int maxNum,int n,int type) {

        int i = 0;

        int z = 0;

        String yunSuanShiTemp;

        String[] yunSuanShiArray = new String[n];

        int operatorScope = 2 + 2 * hasChengChu;//运算符范围,242代表只有加减,4代表有加减乘除

        int length;

        String[] operatorArray = {"+","-","*","/"};

        String[] operatorNum = null;//存储运算数

        int num_index;//运算数下标

        String[] operatorSymbol = null;//存储运算符

        int symbol_index;//运算符下标

        int[] brackets = null;//存储括号个数

         

        while(i < n) {

            length = Integer.parseInt(getOperatorNumber(0, 0,9)) + 2;//计算式运算数长度

            operatorNum = new String[length];

            operatorSymbol = new String[length - 1];

            num_index = 0;

            symbol_index = 0;

            operatorNum[num_index++] = getOperatorNumber(type,minNum, maxNum);//随机生成操作数

            for(int j = 0;j < length - 1;j++){

                operatorSymbol[symbol_index++] = operatorArray[Integer.parseInt(getOperatorNumber(0,0,operatorScope-1))];//随机生成操作符

                operatorNum[num_index++] = getOperatorNumber(type, minNum,maxNum);//随机生成操作数

            }       

            if(hasKuoHao == 1){

                brackets = randomAddBracket(length);//生成括号数组

            }

            //构造运算式

            yunSuanShiTemp = "";

            for(int j = 0;j < length;j++){

                //添加左括号

                if(hasKuoHao == 1){

                    for(int k = 0;k < brackets[j];k++){

                        yunSuanShiTemp += "(";

                    }

                }

                yunSuanShiTemp += " " + operatorNum[j] + " ";//加上运算数

                 

                //添加右括号

                if(hasKuoHao == 1){

                    for(int k = 0;k > brackets[j];k--){

                        yunSuanShiTemp += ")";

                    }

                }

                //如果不是最后一个运算数则要加上运算符

                if(j != length - 1){

                    yunSuanShiTemp += operatorSymbol[j];

                }

            }

             

            //计算结果

            String answer = expressCalculate(yunSuanShiTemp, hasFuShu, hasYuShu, type, length - 1);

            if((answer.equals("ERROR"))){

                continue;

            }

            yunSuanShiTemp += "=" /*+ answer*/;

            Answer[z]=answer;

            z++;

            //检验重复

            boolean chongFu = false;

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

                if((yunSuanShiArray[j].equals(yunSuanShiTemp))){

                    chongFu = true;

                    break;

                }

            }

            if(chongFu == false){

                yunSuanShiArray[i++] = yunSuanShiTemp;

            }

        }

        return yunSuanShiArray;

    }

     

    //表达式计算,参数为字符串类型的运算式

    public static String expressCalculate(String express,int hasFuShu,int hasYuShu,int type,int symbolNum){

        Stack<String> num = new Stack<String>();

        Stack<String> symbolS = new Stack<String>();

        symbolS.push("#");

        express += "#";

        char ch;

        int i = 0;

        int s = 0;

        ch = express.charAt(i);

        while(s < symbolNum){

            if(ch == ' '){//读到空格,说明开始读运算数

                String readNumStr = "";

                while(true){

                    ch = express.charAt(++i);

                    if(ch == ' '){

                        break;

                    }

                    readNumStr += ch;

                     

                }

                if((i + 1) < express.length()){

                    ch = express.charAt(++i);

                }

                num.push(readNumStr);

            }else{//读到的是运算符

                char compare = priorityCompare(symbolS.peek(),ch + "");

                 

                if(compare == '='){//如果是右括号

                    symbolS.pop();

                    ch = express.charAt(++i);

                }else if(compare == '>'){//ch的优先级小于栈顶的优先级     比栈顶的优先级高就不算,入栈,低就弹栈运算

                    //弹出两个运算数,弹出一个运算符

                    String bStr = num.pop();

                    String aStr = num.pop();

                    String symbolT = symbolS.pop();

                    String c = yunSuan(aStr,bStr,symbolT,hasFuShu,hasYuShu,type);

                    if(c.equals("ERROR")){

                        return "ERROR";

                    }else if(c.indexOf("") >= 0 && s != symbolNum - 1){//有余数

                        return "ERROR";

                    }else{

                        num.push(c);

                    }

                    s++;

                }else{

                    symbolS.push(ch + "");

                    if((i + 1) < express.length()){

                        ch = express.charAt(++i);

                    }

                }

             

            }

        }

        return num.pop();

    }

     

    public static String yunSuan(String aStr,String bStr,String symbol,int hasFuShu,int hasYuShu,int type){

        if(type == 0){//整数

            int a = Integer.parseInt(aStr);

            int b = Integer.parseInt(bStr);

            if(symbol.equals("+")){

                return "" + (a + b);

            }else if(symbol.equals("-")){

                if(a - b < 0 && hasFuShu == 0){

                    return "ERROR";

                }else{

                    return "" + (a - b);

                }

            }else if(symbol.equals("*")){

                return "" + (a * b);

            }else{

                if(b == 0){

                    return "ERROR";

                }

                if(a % b == 0){

                    return "" + (a / b);

                }else{

                    if(hasYuShu == 1){

                        return (a / b) + "" + (a % b);

                    }else{

                        return "ERROR";

                    }

                }

            }

        }else{//分数

            String[] af = aStr.split("/");

            String[] bf = bStr.split("/");

            if(af[0].equals("0") || bf[0].equals("0")){

                return "ERROR";

            }

            fraction a = new fraction(Integer.parseInt(af[1]),Integer.parseInt(af[0]));

            fraction b = new fraction(Integer.parseInt(bf[1]),Integer.parseInt(bf[0]));

            if(symbol.equals("+")){

                return a.add(b).toString();

            }else if(symbol.equals("-")){

                fraction c = a.subtract(b);

                if(hasFuShu == 1 && c.getFenZi() < 0){

                    return "ERROR";

                }

                return c.toString();

            }else if(symbol.equals("*")){

                return a.multiply(b).toString();

            }else{

                return a.divide(b).toString();

            }

        }

    }   

 

    //判断优先级

    public static char priorityCompare(String a,String b){

        char[][] priority = {

                {'>','>','<','<','<','>','>'},

                {'>','>','<','<','<','>','>'},

                {'>','>','>','>','<','>','>'},

                {'>','>','>','>','<','>','>'},

                {'<','<','<','<','<','=','>'},

                {'>','>','>','>',' ','>','>'},

                {'<','<','<','<','<',' ','='}

        };

        int a_index = index_symbol(a);

        int b_index = index_symbol(b);

        return priority[a_index][b_index];

    }

     

    public static int index_symbol(String a){

        String p = "+-*/()#";

        return p.indexOf(a);

    }

     

    //随机生成括号,参数为运算式的运算数的个数

    public static int[] randomAddBracket(int length){

        int[] brackets = new int[length];

        for(int i = 0;i < brackets.length;i++)   brackets[i] = 0;

        Random rd = new Random();

        for(int i = 2;i < length;i++){//添加的括号长度(括号包围的运算数的个数)

            for(int j = 0;j < length - i + 1;j++){

                int t = rd.nextInt(2);//随机生成010代表不加括号,1代表加括号

                if(t == 1){

                    if(brackets[j] >= 0 && brackets[j + i - 1] <= 0){//要加的括号的第一个运算数周围没有右括号,且 最后一个运算数周围没有左括号

                        int counteract = 0;

                        for(int k = j;k < j + i;k++){//将要加的括号之间的所有运算数对应的brackets相加,

                                                        //如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象

                            counteract += brackets[k];

                        }

                        if(counteract == 0){

                            brackets[j]++;

                            brackets[j + i - 1]--;

                        }

                    }

                }

            }

        }

        return brackets;

    }

     

    //随机生成一个运算数(                type==0代表生成整数,type==1代表生成真分数,maxNum代表数值范围 0-(maxNum-1)               )

    public static String getOperatorNumber(int type,int minNum,int maxNum){

        Random rd = new Random();

        int a,b;

        while(true){

            a = rd.nextInt(maxNum-minNum+1)+minNum;

            if(type == 0){//随机生成一个整数

                return "" + a;

            }else{//随机生成一个真分数

                if(a == 0){

                    continue;

                }

                b = rd.nextInt(maxNum-minNum+1)+minNum;

                System.out.println(b);

                while(b>=a)

                {

                    b = rd.nextInt(maxNum-minNum+1)+minNum;

                    if(a>b)

                    {

                        break;

                    }

                }

                System.out.println(b);

                fraction c = new fraction(a,b);

                return c.toString();

            }

        }

    }

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        Scanner sc = new Scanner(System.in);

        System.out.print("请输入所要生成题目的数目:");

        int n = sc.nextInt();

        System.out.print("请输入: 0、整数式 ; 1、分数式:");

        int type = sc.nextInt();

        System.out.print("是否有乘除法?(1,0没有):");

        int hasChengChu = sc.nextInt();

        System.out.print("是否有括号?(1,0没有):");

        int hasKuoHao = sc.nextInt();

        System.out.print("加减有无负数?(1,0没有):");

        int hasFuShu = sc.nextInt();

        System.out.print("除法有无余数?(1,0没有):");

        int hasYuShu = sc.nextInt();

        System.out.print("数值范围(最小数):");

        int minNum = sc.nextInt();

        System.out.print("数值范围(最大数):");

        int maxNum = sc.nextInt();

        String[] yunSuanShiArray = createYunSuanShi(hasChengChu, hasKuoHao, hasFuShu, hasYuShu,minNum, maxNum, n, type);

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

            System.out.print(yunSuanShiArray[i]);

            String result=sc.next();

            if(result.equals(Answer[i])){

                System.out.print(" 回答正确!");

            }

            else{

                System.out.print(" 回答错误!"+"正确答案为:"+Answer[i]);

            }

            System.out.println();

        }

        sc.close();

    }

}

三、运行结果截图

 

四、编程总结分析

下星期的编程任务应该是改为web版,这一星期的编程时间并不是特别长,所以下个星期应该更加努力去完善程序,争取早日完成这个程序!数据库之前连接的不太顺利,是由于列名与程序中的sql语句不对应导致。

五、个人收获

     通过此次程序的编写,使得我掌握了数据库的创建,以及在程序中对数据库的使用,将四则运算加减乘除的算法得以编译,掌握了乘除中所得结果的约简算法,css简单样式的设计。

posted on 2017-03-16 21:50  田会  阅读(141)  评论(0编辑  收藏  举报