zoukankan      html  css  js  c++  java
  • # 2019-2020-4 《Java 程序设计》结对项目总结

    2019-2020-4 《Java 程序设计》结对项目阶段总结---《四则运算——整数》

    一、需求分析

    实现一个命令行程序

    要求:

    1. 自动生成小学四则运算题目(加,减,乘,除);
    2. 支持整数;
    3. 支持多运算符(例如生成包含n个运算符的题目);
    4. 支持真分数(后续实现);
    5. 统计正确率。

    扩展需求

    1. 文件:
      (1) 处理生成题目并输出到文件;
      (2) 完成题目后从文件读入并判断。
    2. 多语言支持:简体中文,繁體中文,English;
    3. 生成题目去重。

    二、设计思路以及代码解释

    刚拿到结对项目

    刚拿到结对项目时,感觉不是很难,是因为没有考虑到括号、运算优先级以及多个数字运算的问题,所以只是简单设计了一个两个数字简单的四则运算,具体程序如下:

    //生成随机整数的运算

    public class Zheng {
            int a=0,b=0,c=0;
    	int result=0,g=0;
    	String s=null;
    	public void Zheng(){
    		a = (int)(Math.random()*100);//生成0-99的随机数
    		b = (int)(Math.random()*100);
    		c = (int)(Math.random()*4);//生成0-3的随机数,用来随机产生运算符
    		 if(c==0){
    			 System.out.println(a+"+"+b+"=");
    			 result = a + b;
    		 }
    		 if(c==1){
                             System.out.println(a+"-"+b+"=");
    			 result = a - b;
    		 }
                     if(c==2){
                             System.out.println(a+"*"+b+"=");
    			 result = a * b;
    		}
                     if(c==3){
                          if(b==0){
                                 while(b==0) 
                                 b=(int)(Math.random()*10);//防止分母为0
                }
                          else{ 
                             System.out.println(a+"/"+b+"=");
                             int smaller = a > b ? b : a;//将a与b中的最小值赋给变量
                             for (int i = 1; i <= smaller; i++) {
    				 if (a % i == 0 && b % i == 0) {
    					 g = i;
    				 }//求a与b的最大公因子
    			 }
    			 a = a/g;
    			 b = b/g;
    			 s = a+"/"+b;
            }   
        }
      } 
    }
    

    //实现四则运算

    import java.util.*;
    public class YunSuan {
    	public static void main (String args[]){
    		int x,z=0;
    		Zheng zheng = new Zheng();
    		System.out.print("请输入要生成的题目数:");
    		Scanner reader = new Scanner(System.in);
    		int n = reader.nextInt();
    		Random random = new Random();
    		for(int i=1;i<n+1;i++){
    		for(;;){
    			System.out.println("题目"+i+":");
    			zheng.Zheng();
    			System.out.print("请输入结果:");
    			if(zheng.c==3){
    				Scanner sc=new Scanner(System.in);
    				String s =new String();
    			        s =sc.nextLine();
    				if(s.equals(zheng.s)){
    					z++;
    					System.out.println("此题正确");
    			}
    		        	else
    			        	System.out.println("此题错误,正确答案为:"+zheng.s);
    			}
    			else{
    			x =reader.nextInt();
    			if(x==zheng.result){
    				z++;
    			        System.out.println("此题正确");
    			}
    			else
    				System.out.println("此题错误,正确答案为:"+zheng.result);
    			
    			}
    		        break;
                  }
                }
    	    int o =(int)(((double)z/(double)n)*100);//计算正确率
                System.out.print("完成"+n+"道题,正确数目为:"+z+",正确率为:");
    	    System.out.printf("%d",o);
    	    System.out.println("%");
    	}
    }
    

    简单四则运算码云链接:链接

    考虑到多种因素后

    当发现需要考虑括号、运算优先级以及多个数字计算的因素时,发现事情没那么简单,然后疯狂脑阔疼.........,在看到栈以及中缀转后缀等问题后,陷入了沉思,在通过长时间的学习和理解后才知道如何解决括号与计算问题,之前没有这些知识前,根本无从下手,通过最终地艰苦奋斗还是设计出代码,但是还是有些问题,代码如下:

    //生成随机数

    import java.util.*;
    public class RandomNum {
    	int RandomNum(int x){
    		int num =(int)(Math.random()*x);
    		return num;
    	}
    }
    
    //生成随机运算符
    import java.util.*;
    public class RandomChar {
    	 char RandomChar(){
            int num = (int)(Math.random()*4);
            switch (num){
                case 0:return'+';
                case 1:return'-';
                case 2:return'*';
                case 3:return'÷';
                default:return 0;
            }
        }
    }
    

    //生成中缀表达式以及产生题目

    import java.util.*;
    public class Produce {
    	void Produce(int n){
    		RandomNum num = new RandomNum();
    		RandomChar c = new RandomChar();
    		Scanner reader = new Scanner(System.in);
    		String s = "";
    		String d = "";
    		String g = "";
    		String out = "";//最终的中缀表达式
    		String end = "";//转化后的后缀表达式
    		int count = 0;//记录做对的题目个数
    	        for(int i=1;i<n+1;i++){
    			System.out.println("题目"+i+":");
    			int a = (int)(Math.random()*5+1);
    		        int amount = num.RandomNum(a)+1;//记录随机产生运算符的个数
    			for(int j=0;j<amount;j++){
    			s = s+c.RandomChar()+" ";
    			}
    			String str[] = s.split(" ");//将字符串转化成字符串数组
    			for(int z=0;z<str.length;z++){
    				d = d+num.RandomNum(50)+str[z];
    			}
    			d = d + num.RandomNum(50);
    			switch((num.RandomNum(2))){
    				case 0:
    					System.out.println(d+" = ");//输出不带括号的中缀表达式
    					break;
    				case 1:
    				        for(int k=0;k<str.length;k++){
    					       g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k];
    					}//在中缀表达式中加入括号
    					g = g + num.RandomNum(50);
    					System.out.println(g+" = ");//输出不带括号的中缀表达式
                                            break;
    
    			}
    			out = g;
    			out = d;
    			int p = 0;//初始化最终得到的答案
    			infixToSuffix in = new infixToSuffix();
    			end = in.infixToSuffix(out);//将中缀表达式转化为后缀表达式
    			suffixToArithmetic ex = new suffixToArithmetic();
    			p = (int) ex.suffixToArithmetic(end);//计算后缀表达式的结果
    		        System.out.print("请输入结果:");
    			int x = reader.nextInt();
    			if(x==p){
    				System.out.println("结果正确!");
    				count++;
    			}
    			else{
    				System.out.println("结果错误,正确结果是:"+p);
    			}
    			s="";
    			g="";
    			d="";
    		}
    		int result = (int)(((double)count/(double)n)*100);//计算正确率
    		System.out.println("总共答题"+n+"道,正确率为:"+result+"%");
    	}
    	
    }
    

    //将中缀表达式转化为后缀表达式

    import java.util.*;
    public class infixToSuffix {
    public static String infixToSuffix(String infix) {
            Stack<Character> stack = new Stack<Character>();
            String suffix = "";
            int length = infix.length();
            for (int i = 0; i < length; i++) {
                Character temp;
                char c = infix.charAt(i);
                switch (c) {
                    // 忽略空格
                    case ' ':
                        break;
                    // 碰到'(',push到栈
                    case '(':
                        stack.push(c);
                        break;
                    // 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
                    case '+':
                    case '-':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(') {
                                stack.push('(');
                                break;
                            }
                            suffix += " " + temp;
                        }
                        stack.push(c);
                        suffix += " ";
                        break;
                    // 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
                    case '*':
                    case '/':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(' || temp == '+' || temp == '-') {
                                stack.push(temp);
                                break;
                            } else {
                                suffix += " " + temp;
                            }
                        }
                        stack.push(c);
                        suffix += " ";
                        break;
                    // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
                    case ')':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(')
                                break;
                            else
                                suffix += " " + temp;
                        }
                        // suffix += " ";
                        break;
                    //如果是数字,直接送至输出序列
                    default:
                        suffix += c;
                }
            }
    
            //如果栈不为空,把剩余的运算符依次弹出,送至输出序列。
            while (stack.size() != 0) {
                suffix += " " + stack.pop();
            }
            return suffix;
        }
    }
    
    

    //计算后缀表达式的值

    import java.util.*;
    public class suffixToArithmetic{
    	int suffixToArithmetic(String h) {
    		Stack<Integer>stack = new Stack<Integer>();
    		String b[] = h.split(" ");//将字符串转化为字符串数组
    		for(int i=0;i<b.length;i++){
    			String c = b[i];
    			if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){
    				int y = stack.pop();
    				int x = stack.pop();
    				Caculate z = new Caculate();
                                    stack.push(z.Caculate(x,y,c));//将运算结果重新压入栈
    			}//是运算符,弹出运算数,计算结果
    			else{
    				stack.push(Integer.valueOf(c));
    			}
    		}
    		return stack.pop();//弹出栈顶元素就是运算最终结果
    	}
    }
    

    //判定运算符并进行运算

    class Caculate{
    	int Caculate(int x,int y,String c) {
            if (c.equals("+"))
                return x + y;
            if (c.equals("-"))
                return x - y;
            if (c.equals("*"))
                return x * y;
            if (c.equals("/")){
    		if(x<=y||x==0) return 1;
    		else return x / y;
    	}
    	return 0;
        }
    }
    

    完善后四则运算码云链接:链接

    三、总结分析与运行截图

    结对项目总结与分析

    开始以为项目应该很快就能完成,发现缺少好多知识后就很难完成这个项目,不得不将新知识学习后再进行编程,在编程中遇到往中缀表达式加入括号的问题,以及除法计算的问题,遇到左右括号数量不等的情况,遇到括号只括住一个数字或者一个运算符的问题,遇到遇见除法无法输出的问题,遇到无法计算出结果的问题,这些问题都在最后与同伴的讨论中得到部分解决,还是有些问题没有得到解决。程序的UML图将在完善程序后的博客中体现。
    除法计算问题的截图:

    运行截图体现

    简单四则运算的运行截图:

    部分完善后的运行截图:

    四、结对同伴的评价

    结对同伴陈敬勇在完成此次项目中的表现非常出色,我们在遇到问题后都能认真讨论得出答案,避免了一个人完成任务时的思维定式的问题,我们相互鼓励支持,相信在下来的完善代码问题的过程中,我们会做的更好。

    五、代码托管

    代码托管

  • 相关阅读:
    java。equal()和== 的区别
    java。封装
    java。OOA,OOD,OOR
    java。类和对象
    java、数组;堆区,栈区
    java。 break和continue区别
    NYOJ 228 士兵杀敌(五)【差分标记裸题】
    2017CCPC 杭州 J. Master of GCD【差分标记/线段树/GCD】
    CF1025B Weakened Common Divisor【数论/GCD/思维】
    网络流算法笔记
  • 原文地址:https://www.cnblogs.com/zzmzcc/p/10651666.html
Copyright © 2011-2022 走看看