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