20202310 data structure and object oriented programming experiment 8 report

Posted by Mr Chew on Mon, 29 Nov 2021 03:25:17 +0100

twenty million two hundred and two thousand three hundred and ten   Experiment 8 report of data structure and object-oriented programming

Course: programming and data structure
Class:   two thousand and twenty-three
Name: Xiao Yanhao
Student No.: 20202310
Experimental teacher: Wang Zhiqiang
Experiment date: November 18, 2021

Compulsory / elective: compulsory

1, Experimental content

1. Refer to textbook PP16.1 and complete the implementation of the chain tree LinkedBinaryTree (getRight,contains,toString,preorder,postorder)
Use JUnit or write your own driver class to test your LinkedBinaryTree. Submit a screenshot of the test code, with a full screen, including your student number information
Push the code to the code hosting platform after class

2. Based on LinkedBinaryTree, realize the function of constructing a unique binary tree based on (middle order, first order) sequence, such as giving middle order HDIBEMJNAFCKGL and later order ABDHIEJMNCFGKL to construct the tree in the attached figure
Use JUnit or write your own driver class to test the functions you realize, and submit the screenshot of the test code. It should be full screen, including your own student number information
Push the code to the code hosting platform after class

3. Design and implement a decision tree
Submit a screenshot of the test code operation, with a full screen, including your student number information
Push the code to the code hosting platform after class

4. Input infix expression, use tree to convert infix expression into suffix expression, and output suffix expression and calculation results (if tree is not used, score normally. If tree is used, give full score as appropriate even if there are small problems)
Submit a screenshot of the test code operation, with a full screen, including your student number information

2, Experimental process and results

1. Refer to textbook PP16.1 and complete the implementation of the chain tree LinkedBinaryTree (getRight,contains,toString,preorder,postorder)
Use JUnit or write your own driver class to test your LinkedBinaryTree. Submit a screenshot of the test code, with a full screen, including your student number information
Push the code to the code hosting platform after class

(1) Binary tree:

import java.util.ArrayList;

import java.util.List;

 

public class bintree {

    public bintree left;

    public bintree right;

    public bintree root;

//    Data domain

    private Object data;

    //    Storage node

    public List<bintree> datas;

 

    public bintree(bintree left, bintree right, Object data){

        this.left=left;

        this.right=right;

        this.data=data;

    }

//    Leave the initial left and right child values blank

    public bintree(Object data){

        this(null,null,data);

    }

 

    public bintree() {

 

    }

 

    public void creat(Object[] objs){

        datas=new ArrayList<bintree>();

        //        Convert the values of an array to Node node

        for(Object o:objs){

            datas.add(new bintree(o));

        }

//        The first number is the root node

        root=datas.get(0);

//        Establish binary tree

        for (int i = 0; i <objs.length/2; i++) {

//            Left child

            datas.get(i).left=datas.get(i*2+1);

//            Right child

            if(i*2+2<datas.size()){//Avoid subscript out of bounds in even numbers

                datas.get(i).right=datas.get(i*2+2);

            }

 

        }

 

    }

//Preorder traversal 

public void preorder(bintree root){

    if(root!=null){

        System.out.println(root.data);

        preorder(root.left);

        preorder(root.right);

    }

 

}

//Medium order traversal

    public void inorder(bintree root){

        if(root!=null){

            inorder(root.left);

            System.out.println(root.data);

            inorder(root.right);

        }

 

    }

//    Postorder traversal

    public void afterorder(bintree root){

        if(root!=null){

            System.out.println(root.data);

            afterorder(root.left);

            afterorder(root.right);

        }

 

    }

 

    public static void main(String[] args) {

        bintree bintree=new bintree();

        Object []a={2,4,5,7,1,6,12,32,51,22};

        bintree.creat(a);

        bintree.preorder(bintree.root);

    }

}

 

(2) Test results:

 

 

 

 

2. Based on LinkedBinaryTree, realize the function of constructing a unique binary tree based on (middle order, first order) sequence, such as giving middle order HDIBEMJNAFCKGL and later order ABDHIEJMNCFGKL to construct the tree in the attached figure
Use JUnit or write your own driver class to test your implemented functions, submit test code operation screenshots, and use the full screen to include your own student number information.

(1) Binary tree is based on pre order sequence and middle order sequence

package com.mytest.mymain;

 import java.util.Arrays;

 

 

 //Define node

class BinaryTree{

public int value;

public BinaryTree leftNode;

public BinaryTree rightNode;

BinaryTree(int x) { value = x; }

}

 

 

public class ConstrontTree {

 

public static void main(String[] args) throws Exception {

int[] preSort={1,2,4,7,3,5,6,8};

int[] inSort=new int[]{4,7,2,1,5,3,8,6};

BinaryTree root=startBuildTree(preSort,inSort);

}

//01 Recursive spanning tree

private static BinaryTree startBuildTree(int[] preSort,int[] inSort) throws Exception {

//Abnormal judgment

if(preSort==null || inSort==null){

return null;

}

if(preSort.length!=inSort.length){

throw new Exception("Illegal input that does not meet the conditions!");

}

 

BinaryTree root=null;

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

if(inSort[i]==preSort[0]){

root=new BinaryTree(preSort[0]);

System.out.println(preSort[0]);

 

root.leftNode=startBuildTree(

Arrays.copyOfRange(preSort, 1, i+1),

Arrays.copyOfRange(inSort, 0, i));

root.rightNode=startBuildTree(

Arrays.copyOfRange(preSort, i+1, preSort.length),

Arrays.copyOfRange(inSort, i+1, inSort.length));

}

}

 

 

return root;

}

}

 

 

  (2) Test:

import java.util.Scanner;

public class treetext {

    public static void main(String[] args) {

        System.out.println("Please enter a preamble sequence of a binary tree");

        Scanner scan = new Scanner(System.in);

        String a = scan.nextLine();

        String[] a2 = a.split(" ");

        System.out.println("Please enter the middle order sequence of a binary tree");

        String b = scan.nextLine();

        String[] b2 = b.split(" ");

        creattree ct = new creattree();

        System.out.println(ct.buildTree(a2,b2));

    }

}

 

(3) Test screenshot:

 

 

3. Design and implement a decision tree
Submit a screenshot of the test code operation, with a full screen, including your student number information
Push the code to the code hosting platform after class

package demo;

import java.util.HashMap;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

public class DicisionTree {

  public static void main(String[] args) throws Exception {

    System.out.print("Script house test results:");

    String[] attrNames = new String[] { "AGE", "INCOME", "STUDENT",

        "CREDIT_RATING" };

    // Read sample set

    Map<Object, List<Sample>> samples = readSamples(attrNames);

    // Generate decision tree

    Object decisionTree = generateDecisionTree(samples, attrNames);

    // Output decision tree

    outputDecisionTree(decisionTree, 0, null);

  }

  /**

   * Read the classified sample set and return to Map: Classification - > list of samples belonging to the classification

   */

  static Map<Object, List<Sample>> readSamples(String[] attrNames) {

    // Sample attribute and its classification (the last element in the array is the classification to which the sample belongs)

    Object[][] rawData = new Object[][] {

        { "<30 ", "High ", "No ", "Fair   ", "0" },

        { "<30 ", "High ", "No ", "Excellent", "0" },

        { "30-40", "High ", "No ", "Fair   ", "1" },

        { ">40 ", "Medium", "No ", "Fair   ", "1" },

        { ">40 ", "Low  ", "Yes", "Fair   ", "1" },

        { ">40 ", "Low  ", "Yes", "Excellent", "0" },

        { "30-40", "Low  ", "Yes", "Excellent", "1" },

        { "<30 ", "Medium", "No ", "Fair   ", "0" },

        { "<30 ", "Low  ", "Yes", "Fair   ", "1" },

        { ">40 ", "Medium", "Yes", "Fair   ", "1" },

        { "<30 ", "Medium", "Yes", "Excellent", "1" },

        { "30-40", "Medium", "No ", "Excellent", "1" },

        { "30-40", "High ", "Yes", "Fair   ", "1" },

        { ">40 ", "Medium", "No ", "Excellent", "0" } };

    // Read the sample attribute and its classification, and construct a template representing the sample Sample Object, and divide the sample set according to classification

    Map<Object, List<Sample>> ret = new HashMap<Object, List<Sample>>();

    for (Object[] row : rawData) {

      Sample sample = new Sample();

      int i = 0;

      for (int n = row.length - 1; i < n; i++)

        sample.setAttribute(attrNames[i], row[i]);

      sample.setCategory(row[i]);

      List<Sample> samples = ret.get(row[i]);

      if (samples == null) {

        samples = new LinkedList<Sample>();

        ret.put(row[i], samples);

      }

      samples.add(sample);

    }

    return ret;

  }

  static Object generateDecisionTree(

      Map<Object, List<Sample>> categoryToSamples, String[] attrNames) {

    // If there is only one sample, the classification to which the sample belongs is regarded as the classification of the new sample

    if (categoryToSamples.size() == 1)

      return categoryToSamples.keySet().iterator().next();

    // If there are no attributes for decision-making, the classification with the largest number of samples in the sample set is regarded as the classification of new samples, that is, the classification is elected by voting

    if (attrNames.length == 0) {

      int max = 0;

      Object maxCategory = null;

      for (Entry<Object, List<Sample>> entry : categoryToSamples

          .entrySet()) {

        int cur = entry.getValue().size();

        if (cur > max) {

          max = cur;

          maxCategory = entry.getKey();

        }

      }

      return maxCategory;

    }

    // Select test properties

    Object[] rst = chooseBestTestAttribute(categoryToSamples, attrNames);

    // The root node of the decision tree, and the branch attribute is the selected test attribute

    Tree tree = new Tree(attrNames[(Integer) rst[0]]);

    // Used test attributes should not be selected as test attributes again

    String[] subA = new String[attrNames.length - 1];

    for (int i = 0, j = 0; i < attrNames.length; i++)

      if (i != (Integer) rst[0])

        subA[j++] = attrNames[i];

    // Generate branches based on Branch Properties

    @SuppressWarnings("unchecked")

    Map<Object, Map<Object, List<Sample>>> splits =

    /* NEW LINE */(Map<Object, Map<Object, List<Sample>>>) rst[2];

    for (Entry<Object, Map<Object, List<Sample>>> entry : splits.entrySet()) {

      Object attrValue = entry.getKey();

      Map<Object, List<Sample>> split = entry.getValue();

      Object child = generateDecisionTree(split, subA);

      tree.setChild(attrValue, child);

    }

    return tree;

  }

  static Object[] chooseBestTestAttribute(

      Map<Object, List<Sample>> categoryToSamples, String[] attrNames) {

    int minIndex = -1; // Optimal attribute subscript

    double minValue = Double.MAX_VALUE; // Minimum information

    Map<Object, Map<Object, List<Sample>>> minSplits = null; // Optimal branching scheme

    // For each attribute, calculate the sum of the amount of information needed to determine the classification of new samples in each branch when it is used as the test attribute, and select the minimum as the best

    for (int attrIndex = 0; attrIndex < attrNames.length; attrIndex++) {

      int allCount = 0; // Counter for counting the total number of samples

      // Build by current attribute Map: Attribute value->(classification->Sample list)

      Map<Object, Map<Object, List<Sample>>> curSplits =

      /* NEW LINE */new HashMap<Object, Map<Object, List<Sample>>>();

      for (Entry<Object, List<Sample>> entry : categoryToSamples

          .entrySet()) {

        Object category = entry.getKey();

        List<Sample> samples = entry.getValue();

        for (Sample sample : samples) {

          Object attrValue = sample

              .getAttribute(attrNames[attrIndex]);

          Map<Object, List<Sample>> split = curSplits.get(attrValue);

          if (split == null) {

            split = new HashMap<Object, List<Sample>>();

            curSplits.put(attrValue, split);

          }

          List<Sample> splitSamples = split.get(category);

          if (splitSamples == null) {

            splitSamples = new LinkedList<Sample>();

            split.put(category, splitSamples);

          }

          splitSamples.add(sample);

        }

        allCount += samples.size();

      }

      // Calculate the sum of the amount of information required to determine the classification of new samples in each branch when the current attribute is used as the test attribute

      double curValue = 0.0; // Counter: accumulate branches

      for (Map<Object, List<Sample>> splits : curSplits.values()) {

        double perSplitCount = 0;

        for (List<Sample> list : splits.values())

          perSplitCount += list.size(); // Cumulative current branch samples

        double perSplitValue = 0.0; // Counters: current branch

        for (List<Sample> list : splits.values()) {

          double p = list.size() / perSplitCount;

          perSplitValue -= p * (Math.log(p) / Math.log(2));

        }

        curValue += (perSplitCount / allCount) * perSplitValue;

      }

      // Select the smallest as the best

      if (minValue > curValue) {

        minIndex = attrIndex;

        minValue = curValue;

        minSplits = curSplits;

      }

    }

    return new Object[] { minIndex, minValue, minSplits };

  }

 

  static void outputDecisionTree(Object obj, int level, Object from) {

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

      System.out.print("|-----");

    if (from != null)

      System.out.printf("(%s):", from);

    if (obj instanceof Tree) {

      Tree tree = (Tree) obj;

      String attrName = tree.getAttribute();

      System.out.printf("[%s = ?]\n", attrName);

      for (Object attrValue : tree.getAttributeValues()) {

        Object child = tree.getChild(attrValue);

        outputDecisionTree(child, level + 1, attrName + " = "

            + attrValue);

      }

    } else {

      System.out.printf("[CATEGORY = %s]\n", obj);

    }

  }

 

  static class Sample {

    private Map<String, Object> attributes = new HashMap<String, Object>();

    private Object category;

    public Object getAttribute(String name) {

      return attributes.get(name);

    }

    public void setAttribute(String name, Object value) {

      attributes.put(name, value);

    }

    public Object getCategory() {

      return category;

    }

    public void setCategory(Object category) {

      this.category = category;

    }

    public String toString() {

      return attributes.toString();

    }

  }

  static class Tree {

    private String attribute;

    private Map<Object, Object> children = new HashMap<Object, Object>();

    public Tree(String attribute) {

      this.attribute = attribute;

    }

    public String getAttribute() {

      return attribute;

    }

    public Object getChild(Object attrValue) {

      return children.get(attrValue);

    }

    public void setChild(Object attrValue, Object child) {

      children.put(attrValue, child);

    }

    public Set<Object> getAttributeValues() {

      return children.keySet();

    }

  }

}

 

4. Input infix expression, use tree to convert infix expression into suffix expression, and output suffix expression and calculation results (if tree is not used, score normally. If tree is used, give full score as appropriate even if there are small problems)
Submit a screenshot of the test code operation, with a full screen, including your student number information

package com.rf.springboot01.dataStructure.stack.reversePolishNotation;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Stack;

 

public class infixConvertorSuffix {

    public static void main(String[] args) {

       // Define a infix expression, Example: 1+((2+3)×4)-5 =>1 2 3 + 4 × + 5 –

        String expression = "1+((2+3)*4)-5";

        //Infix expression converted to list  Example: 1+((2+3)×4)-5 =>[1, +, (, (, 2, +, 3, ), *, 4, ), -, 5]

        List<String> infixConvertorList = infixConvertorList(expression);

        System.out.println("Infix expression list======"+infixConvertorList);

        List<String> suffixList=infixListConvertorSuffixList(infixConvertorList);

        System.out.println("Corresponding to suffix expression list======"+suffixList);

        int result=computer(suffixList);

        System.out.println("The infix expression evaluates to:"+result);

    }

 

    public static List<String> infixConvertorList(String str){

        List<String> list=new ArrayList();

        String s;//For multi bit splicing

        char c;// Every time a character is traversed, it is put into c

        int i=0;

        do{

            if((c=str.charAt(i))<48 || (c=str.charAt(i))>57 ){//If not numeric

                list.add(c+"");//Byte to string, added to list

                i++;

            }else{//If it is a number, consider multi digit splicing

                s="";

                while(i<str.length() && (c=str.charAt(i))>=48 && (c=str.charAt(i))<=57){

                   s+=c;

                   i++;

                }

                list.add(s);

            }

        }while(i<str.length());

        return list;

    }

    

    public static List<String> infixListConvertorSuffixList(List<String> ls){

        //Define an operator stack

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

        //Define a stack for storing intermediate results s2,because s2 Stack no pop Operation, and then we need to output in reverse order,

        // Therefore, it is used directly List<String> replace stack<String>

        List<String> s2 = new ArrayList<String>();

        for(String item:ls){

            if(item.matches("\\d+")){//If it's a number

                s2.add(item);//Into the stack where intermediate results are stored s2

            }else if(item.equals("(")){//If it is an open parenthesis, it is directly put into the operator stack s1

                s1.push(item);

            }else if(item.equals(")")){//If it is a right parenthesis, it pops up one by one s1 The operator at the top of the stack and press in s2,Until the left parenthesis is encountered, this pair of parentheses is discarded

                while(!s1.peek().equals("(")){

                    s2.add(s1.pop());

                }

                s1.pop();//!!! Pop open parenthesis s1 Stack, eliminating parentheses

            }else{//When item Priority of is less than or equal to s1 Stack top operator, take s1 The operator at the top of the stack pops up and is added to the s2 In,

                while(s1.size() != 0 && Operation.getOperationValue(item)<=Operation.getOperationValue(s1.peek())){

                    s2.add(s1.pop());

                }

                //You also need to item Push into stack

                s1.push(item);

            }

        }

        //take s1 The remaining operators in the pop-up list are added s2

        while(s1.size() != 0) {

            s2.add(s1.pop());

        }

 

        return s2; //Note that it is stored in List, Therefore, the output in order corresponds to the corresponding suffix expression List

    }

    public static int computer(List<String> list){

        // Create stack, Only one stack is needed

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

        //ergodic

        for(String data:list){

            if(data.matches("\\d+")){//The number of multiple bits matches

                stack.push(data);//Push 

            }else{//It's a symbol, first pop Out of two numbers, and operation, and then into the stack

                int num2=Integer.parseInt(stack.pop());

                int num1=Integer.parseInt(stack.pop());

                int result=0;

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

                    result=num1+num2;

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

                    result=num1-num2;

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

                    result=num1*num2;

                }else if(data.equals("/")){

                    result=num1/num2;

                }else{

                    throw new RuntimeException("Incorrect operator");

                }

                //Put the result result Convert string to stack

                stack.push(result+"");

            }

        }

        //Last stay stack The data in is the result of the operation

        return  Integer.parseInt(stack.pop());

    }

}

 

class Operation{

 

    private static int ADD=1;//The default addition priority is 1

    private static int SUB=1;//The default subtraction priority is 1

    private static int MUL=2;//The default priority of multiplication is 2

    private static int DIV=2;//The default division priority is 2

 

    public static int getOperationValue(String oper){

          int result=0;

          switch (oper){

              case "+":

                  result=ADD;

                  break;

              case "-":

                  result=SUB;

                  break;

              case "*":

                  result=MUL;

                  break;

              case "/":

                  result=DIV;

                  break;

              default:

                  System.out.println("The operator does not exist:"+oper);

                  break;

          }

          return result;

    }

 

}