• 软件工程作业02


      1.设计思想:

                       针对新的要求:是否有乘除法; 是否有括号(最多可以支持十个数参与计算); 数值范围; 加减有无负数; 除法有无余数!在创建新数组根据不同的需求进行选择。利用random随机生成操作数,构造运算式时添加“(”、“)”,创建expressCalculate方法进行计算,创建priorityCompare方法利用栈判断优先级。再创建随机生成括号和运算符的方法,构造Fenshu类,创建约简等方法。最后在main函数里根据创建的数组长度进行循环输出。

     2.源代码:

    import java.util.Random;
    import java.util.Scanner;
    import java.util.Stack;
    
    
    
    public class SiZe1
    {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scan = new Scanner(System.in);
            System.out.println("0、整数式   1、分数式");
            int type = scan.nextInt();
            System.out.println("生成的运算式个数:");
            int n = scan.nextInt();
            System.out.println("是否有乘除法(1有,0没有)");
            int hasChengChu = scan.nextInt();
            System.out.println("是否有括号(1有,0没有)");
            int hasKuoHao = scan.nextInt();
            System.out.println("加减有无负数(1有,0没有)");
            int hasFuShu = scan.nextInt();
            System.out.println("除法有无余数(1有,0没有)");
            int hasYuShu = scan.nextInt();
            System.out.println("数值范围(最大数)");
            int maxNum = scan.nextInt();
            String[] yunSuanShiArray = createYunSuanShi(hasChengChu, hasKuoHao, hasFuShu, hasYuShu, maxNum, n, type);
            for(int i = 0;i < yunSuanShiArray.length;i++){
                System.out.println(yunSuanShiArray[i]);
            }
            scan.close();
        }
        
        
        //生成整数计算式添加限制条件,type为运算式类型  0代表整数式,1代表真分数式
        public static String[] createYunSuanShi(int hasChengChu,int hasKuoHao,int hasFuShu,int hasYuShu,int maxNum,int n,int type) {
            int i = 0;
            String yunSuanShiTemp;
            String[] yunSuanShiArray = new String[n];
            int operatorScope = 2 + 2 * hasChengChu;//运算符范围,2或4,2代表只有加减,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, 9)) + 2;//计算式运算数长度
                operatorNum = new String[length];
                operatorSymbol = new String[length - 1];
                num_index = 0;
                symbol_index = 0;
                operatorNum[num_index++] = getOperatorNumber(type, maxNum);//随机生成操作数
                for(int j = 0;j < length - 1;j++){
                    operatorSymbol[symbol_index++] = operatorArray[Integer.parseInt(getOperatorNumber(0, operatorScope))];//随机生成操作符
                    operatorNum[num_index++] = getOperatorNumber(type, 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;
                //检验重复
                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";
                }
                FenShu a = new FenShu(Integer.parseInt(af[1]),Integer.parseInt(af[0]));
                FenShu b = new FenShu(Integer.parseInt(bf[1]),Integer.parseInt(bf[0]));
                if(symbol.equals("+")){
                    return a.add(b).toString();
                }else if(symbol.equals("-")){
                    FenShu c = a.subtract(b);
                    if(hasFuShu == 1 && c.getNumerator() < 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);//随机生成0或1,0代表不加括号,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 maxNum){
            Random rd = new Random();
            int a;
            while(true){
                a = rd.nextInt(maxNum);
                if(type == 0){//随机生成一个整数
                    return "" + a;
                }else{//随机生成一个真分数
                    if(a == 0){
                        continue;
                    }
                    int b = rd.nextInt(a);
                    FenShu c = new FenShu(a,b);
                    return c.toString();
                }
            }
        }
        
    
    
    }
    
    
    
    
    
    
    
    class FenShu {
        private int denominator,numerator;
    
        public int getDenominator() {
            return denominator;
        }
    
        public void setDenominator(int denominator) {
            this.denominator = denominator;
        }
    
        public int getNumerator() {
            return numerator;
        }
    
        public void setNumerator(int numerator) {
            this.numerator = numerator;
        }
    
        public FenShu(int denominator, int numerator) {
            this.denominator = denominator;
            this.numerator = numerator;
            yueJian();
        }
        
        FenShu(){}
        
        //约简
        public void yueJian(){
            int y = 1;
            for(int i = numerator;i > 1;i--){
                if(numerator % i == 0 && denominator % i == 0){
                    y = i;
                    break;
                }
            }
    //        int nc = numerator,dc = denominator;
    //        if(nc != 0){
    //            while(nc != dc - nc){
    //                y = dc - nc;
    //                if(nc > y){
    //                    dc = nc;
    //                    nc = y;
    //                }else{
    //                    dc = y;
    //                }
    //            }
    //            y = nc;
    //    
                numerator /= y;
                denominator /= y;
            
        }
        
        //
        public FenShu add(FenShu b){
            FenShu c = null;
            int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator();
            int nDenominator = this.denominator * b.getDenominator();
            c = new FenShu(nDenominator,nNumerator);
            return c;
        }
        
        //
        public FenShu subtract(FenShu b){
            FenShu c = null;
            int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator();
            int nDenominator = this.denominator * b.getDenominator();
            c = new FenShu(nDenominator,nNumerator);
            return c;
        }
        
        //
        public FenShu multiply(FenShu b){
            FenShu c = null;
            int nNumerator = this.numerator * b.getNumerator();
            int nDenominator = this.denominator * b.getDenominator();
            c = new FenShu(nDenominator,nNumerator);
            return c;
        }
        
        //
        public FenShu divide(FenShu b){
            FenShu c = null;
            int nNumerator = this.numerator * b.getDenominator();
            int nDenominator = this.denominator * b.getNumerator();
            c = new FenShu(nDenominator,nNumerator);
            return c;
        }
        
        //输出分数形式
        public String toString(){
            if(numerator != 0){
    //            if(numerator % denominator == 0)
    //                return "" + numerator / denominator;
                return numerator + "/" + denominator;
            }
            return "0";
        }
        
    }

      3.运行结果截图

    项目计划总结:

    日期任务 听课 编写程序 查阅资料 日总计
    星期一 2 2 1 4
    星期二     1 1
    星期三   2 1 3
    星期四 2 2   4
    星期五   3 1 4
    星期六   3   5
    星期日        
    周总计 4 12 4

    21

    时间记录日志:

    日期 开始时间 结束时间 中断时间 静时间 活动 备注
    3/7 14:00 15:50 10 100 编写 编写程序
      19:30 21:30 20 100 编写 编写程序
    3/8 19:20 21:30 10 120 编写 编写程序 
    3/9            
      19:20 20:00 0 40 编写  
    3/10 14:00 15:50 10 100 听课 软件工程
      19:20 20:20   60 编写 调试程序
    3/11 18:10 21:30 20 100 编写 调试程序
                 
    3/12            
      16:00 17:00   60 博客 撰写博客

    缺陷记录日志:

    日期 编号 引入阶段 排除阶段 修复时间&问题描述
    3/7 1 编码 编译 30min,理清分数
    3/8        
    3/9        
    3/10-3/11 2 编码 编译 2hour,调试调试
    3/11-3/12 3 编码 编译 2hour,完善括号
             
  • 相关阅读:
    Project2013 界面目录清单
    informix11.7界面入门工具
    informix11.7默认数据库表
    Informix服务器端和客户端配置都用服务器软件配置情况
    RHEL7.1安装后进入X环境
    pluswell on rhel5.4
    vmware10在centos6.5上安装log记录
    LINUX自带多路径详解
    安装win7英文语言包(通用)
    亚信的点滴生活
  • 原文地址:https://www.cnblogs.com/ypbk/p/6544527.html
Copyright © 2020-2023  润新知