软件工程(2018)结对编程第二次作业

目录
  • 二.角色分工
  • 三.代码及代码地址
  • 四.运行结果截图
  • 五.参考资料
  • 六.工作照片
  • 七.评价及总结
  • 我们在刚开始上课的时候介绍过一个小学四则运算自动生成程序的例子,请实现它,要求:

    • 能够自动生成四则运算练习题
    • 可以定制题目数量
    • 用户可以选择运算符
    • 用户设置最大数(如十以内、百以内等)
    • 用户选择是否有括号、是否有小数
    • 用户选择输出方式(如输出到文件、打印机等)
    • 最好能提供图形用户界面(根据自己能力选做,以完成上述功能为主)

二.角色分工

驾驶员:杨浩(本人)
领航员:冯俊鹏 博客地址

三.代码及代码地址

代码地址

题目生成

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;
}
}
}
}

 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;
max=test.maxNum;

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;
}
}

 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;
    }
}

图形界面生成及输出

public static void InitUI()
    {
    JFrame frame =new JFrame();
    frame.setTitle("四则运算");
    frame.setSize(500, 500);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(3);

    FlowLayout f1=new FlowLayout(FlowLayout.LEFT);
    frame.setLayout(f1);

    JLabel name1=new JLabel("请输入题目个数:");
    frame.add(name1);

    JTextField name1text=new JTextField();//文本框
    name1text.setPreferredSize(new Dimension(50, 30));
    frame.add(name1text);

    JLabel name=new JLabel();//空
    name.setPreferredSize(new Dimension(110,30));
    frame.add(name);

    JLabel name2=new JLabel("请输入最大值:");
    frame.add(name2);

    JTextField name2text=new JTextField();//文本框
    name2text.setPreferredSize(new Dimension(50, 30));
    frame.add(name2text);

    JLabel name4=new JLabel("是否输出到文件:");
    frame.add(name4);

    JRadioButton jrb1, jrb2;
    jrb1 = new JRadioButton("是");
        jrb2 = new JRadioButton("否");
        frame.add(jrb1);
        frame.add(jrb2);

        JLabel name5=new JLabel();//空
    name5.setPreferredSize(new Dimension(110,30));
    frame.add(name5);

        JButton bu=new JButton("生成");
        bu.setPreferredSize(new Dimension(80,30));
        frame.add(bu);

    JLabel name3=new JLabel();//空
    name3.setPreferredSize(new Dimension(50,30));
    frame.add(name3);

    JLabel name7=new JLabel("题目:");
    frame.add(name7);

    JLabel name6=new JLabel();//空
    name6.setPreferredSize(new Dimension(250,30));
    frame.add(name6);

        JTextField Titletext=new JTextField();//文本框
    Titletext.setPreferredSize(new Dimension(450, 300));
    frame.add(Titletext);

/**
 * 事件监听器
 */
    bu.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
    String a=name1text.getText();
    int Title_Num = Integer.parseInt(a);  //string转换为int
    String b=name2text.getText();
    maxNum = Integer.parseInt(b);  //string转换为int
    String[] Title=new String[Title_Num];
String[] result1=new String[Title_Num];
    for(int i = 0; i < Title_Num; i++){
    BinaryTree bTree;
    bTree = new BinaryTree(2);
    bTree.createBTree();
    String result = bTree.CalAndVal();
    Title[i]=bTree.toString();
    result1[i]=result;
    System.out.println(Title[i]+"="+result1[i]);
    }

    Titletext.setText(getStringByArray(Title,result1));

    /**
     * 文件输出
     */
    if(jrb1.isSelected()) {
    try{
PrintStream mytxt=new PrintStream("./test.txt");
PrintStream out=System.out;
System.setOut(mytxt);
for(int i = 0; i < Title_Num; i++){
System.out.println(Title[i] + "=" + result1[i]);
}
System.setOut(out);
}catch(FileNotFoundException e1){
e1.printStackTrace();
}
    }

    }
    });

    frame.setVisible(true);
    }
/**
 *
 * @将题目整和成一个字符串,方便setText输出
 * @param b
 * @return str
 */
public static String getStringByArray(String[] a,String[] b) {
    String str = "";
    for(int i=0;i<a.length;i++) {
        str += a[i];
        str += '=';
        str += b[i];
        str += ' ';
        str += ' ';
        str += ' ';
        str += ' ';
    }
    return str;
}

四.运行结果截图

图形框架截图

输出到文本框

输出到文件

五.参考资料

随机生成四则运算式及答案(含括号)
如何将java的输出保存到文件中作为程序日志
Java实现图形界面
Java 图形化界面设计(GUI)实战练习(代码)
Java如何画图形用户界面
java按钮的监听事件
java图形界面中怎么用settext输出一个数组

六.工作照片

七.评价及总结

 在这次的作业中,我的领航员是冯俊鹏同学,他在过程中给了我很大的帮助,不断地督促我尽快完成,遇到不会的问题和我一起解决,是使我的代码更加完善,没有他的话我很难完成这次的作业。
 通过这次作业,我完成了我的第一个拥有图形界面的作品,在这之前一直都是用黑框进行操作,编写代码的过程是非常困难的,有许许多多的问题根本不知道如何解决,例如图形化界面的实现、界面的输入和输出和事件监听器的编写等等,碰到这些问题只能去网上搜索 ,找了很多的参考文章,上面列举出的仅仅只是其中一小部分,程序实现了一部分功能,但还有几个功能没有实现,例如选择小数和选择括号,图形界面的编写也比较混乱,但是,在这次的代码编写过程中,我学到了很多以前根本不会的知识,收获了很多。

(0)

相关推荐

  • JavaScript:数据类型

    JavaScript中有6种数据类型,其中包含了5种基本数据类型和1种复杂数据类型. ·       基本数据类型:undefined.null.boolean.number和String ·     ...

  • UG编程第二讲_型腔铣讲解

    从零基础学习软件,会建模画图,2D转3D,优化模型结构,出图技巧,到软件基础加工,刀具设置,工序参数设置,加工模板定制以及后处理的安装与制作,加上工厂的各类产品零件的实际加工技巧,经验,加上工厂的各类 ...

  • 全局个体,缺一不可——从完美的结对编程搭档说起

    结对编程是极限编程的最佳实践之一. 结对编程活动是由两个人一起完成的,其中的一个坐在前面操作键盘,称为操作手:另外一个在坐在操作手的后面审查敲击出来的代码,称为领航员. 完美的结对编程要求操作手能够更 ...

  • 【乐府课堂】曲研教学第二阶段第二次作业

    曲研教学第二阶段第二课程 导师:弘灵 主教:卓群(雅淡) 助教:党新库(守心) 王晓瑞 编辑:卓群(雅淡) ******************************* 第二节课主要掌握带过曲体式暨 ...

  • 《应用回归分析》第二章作业答案(何晓群版)

    回复关键词:应用回归分析 即可获取资源答案 第二,第三,第四,第五版课后答案类似,可以参考. <应用回归分析>部分课后习题答案-何晓群版 <应用回归分析>第一章作业题参考答案( ...

  • 四川蓉城名校联盟2018级高三第二次联考

    一.选择题:本题共35小题,每小题4分,140分.在每小题给出的四个选项中,只有一项是符合题目要求的. 表l示意我国2019年部分省级行政区人口统计资料,据此完成1-3题. 1.据材料可知,上述四个省 ...

  • 今日养生提醒2018~1~10, 第二候鹊喜巢,残月,冬日吹风的危害

    养生日历 今日养生提醒   过冬时家里保存的大葱现在大部分葱叶已经干枯了,但是这些干枯的葱叶不要扔掉可以剥下用来煮水泡脚.这一周不仅死最寒冷的一周,也是风最大的一周,北京地区已经发布了大风蓝色预警,各 ...

  • (禁闲聊)绘画讨论群1/2第二十次作业展示

    这是一个只发作品,聊作品.绘画知识的群(群内禁止闲聊.发广告).一周一画一论群,你的作品不会只供欣赏,有问题可以提出来大家一起帮你解答这仅仅是一个平台,给大家有一个绘画气氛,打造一个有养分的群,下面我 ...

  • 郭新貌2018秋季班第二周20181215中枢的递归B

    郭新貌2018秋季班第二周20181215中枢的递归B

  • 刀石留痕|河南大学民生学院书法专业2018级篆刻结课作业展

    刀石留痕 方寸之间,亦有大千世界. 篆刻之于我们,是从相识,慢慢相熟继而结下缘分.此次展览的作品浸透着同学们的心力和汗水.篆刻语言.边款形式.印屏制作,一丝不苟.笔墨见情,刀石留意,虽有付出,但都有难 ...