[Java homework] tree structure (combination)

1. Experimental content

1. Problem

The menu is a one-to-many tree structure. The following figure shows the menu structure of the early TurboC2.0:

According to the given menu data file:

File
Load F3
Pick Alt-F3
New
Save F2
Write to
Diretory
Change Dir
Os Shell
Quit Alx-X Edit Run
Program reset Ctrl-F2
Go To cursor F4
Trace into F7
Step over F8
User Screen Alt-F5 Compile
Compile to OBJ
Make EXE file
Link EXE file
Build all
Primary C file
Get info Project
Project name
Break make on
Auto dependencies
Clear project
Remove messages Break/Watch
Add watch Ctrl-F7
Delete watch
Edit watch
Remove all watches
Toggle breakpoint Ctrl-F8
Clear all breakpoints
View next breakpoint Debug
Evalute Ctrl-F4
Call stack Ctrl-F3
Find function
Refresh display
Display swapping
Source debugging Options
Compiler
Model
Defines
Code generation
Optimization
Source
Errors
Names
Linker
Map file
Initialize segments
Default library
Warn duplicate symbols
Stack warning
Case-sensitive link
Environment
Message Tracking
Keep messages
Config auto save
Edit auto save
Backup files
Tab Size
Zoomed windows
Screen size
Directories
Include directories
Library directories
Output directories
Turbo C directory
Pick file name
Current pick file
Arguments
Save options
Retrieve options

3. Requirements

①Read the menu data file, and build an example of the tree as shown above;

②Use width to traverse and output menu title verification.

③Please see the menu item.ppt and finish.

Note: Only one page of this information is related to Java, and some of the materials are written in C. Please complete with Java language.

2. Program design

1. UML graphics

Insert picture description here

2. Design ideas

①Storage structure MenuItem, MenuAnalyseStru

The MenuIterm class is used to store menu options. There are private attributes menuTitle (storing the content of menu options) and private attributes menu (storing the list of child nodes), providing corresponding get and set methods externally, and also providing print methods for recursive printing Self and child nodes
Insert picture description here

The MenuAnalyseStru class is used to store the menu information of each layer. It uses the attributes preBlankCount (storing the number of leading spaces) and list (storing the changed menu options), and provides the corresponding get and set methods externally, as well as the add method to add Menu options on this level
Insert picture description here

②File reading tool MyFileReader

In order to comply with the single responsibility principle in the design pattern, operations such as file reading, calculation of leading spaces, and processing and storage are abstracted into separate classes to reduce the complexity of the program.
Use the method in the loader to obtain the running path of the program, use the path to obtain the corresponding file input stream, read line by line and return the String list.
Insert picture description here

③RegexUtil package class RegexUtil

This class is a tool class, which is mainly based on the regular expression string passed in to return the first string matched (that is, the leading space) is
mainly to encapsulate the corresponding operation (using the Pattern and Matcher classes in jdk to read our Required string)
Insert picture description here

④ Handler

The main function of this type is to process the string list read from the file and store it in the storage structure MenuItem and MenuAnalyseStru that we set.
The specific ideas are as follows:
Insert picture description here

⑤Test class

Previously, each operation was abstracted into a separate class, so the test class only needs to call the methods in the corresponding class in order
Insert picture description here

Three, code details

1. Menu Item MenuItem class

package com.dreamchaser.work4;

import java.util.ArrayList;
import java.util.List;

/**
 * 存储每项信息
 */
class MenuItem{
    
    

    /**
     * 菜单内容
     */
    private String menuTitle;
    /**
     * 子菜单
     */
    private List<MenuItem> menu=new ArrayList<>(3);

    public MenuItem(String menuTitle) {
    
    
        this.menuTitle = menuTitle;
    }

    /**
     * 打印自身及以下结点
     */
    public void print(){
    
    
        System.out.println(menuTitle);
        /**
         * 递归打印子节点
         */
        for (MenuItem menuItem:menu){
    
    
            menuItem.print();
        }
    }

    public String getMenuTitle() {
    
    
        return menuTitle;
    }

    public void setMenuTitle(String menuTitle) {
    
    
        menuTitle = menuTitle;
    }

    public List<MenuItem> getMenu() {
    
    
        return menu;
    }

    public void setMenu(List<MenuItem> menu) {
    
    
        this.menu = menu;
    }
}

2. Menu layer MenuAnalyseStru class

package com.dreamchaser.work4;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 存储每层信息
 */
public class MenuAnalyseStru {
    
    
    /**
     * 前导空格数
     */
    private Integer preBlankCount=0;
    /**
     * 同层的菜单项
     */
    private LinkedList<MenuItem> list=new LinkedList<>();

    public MenuAnalyseStru(Integer preBlankCount) {
    
    
        this.preBlankCount = preBlankCount;
    }

    /**
     * 添加一个菜单项
     * @param menuItem
     */
    public void add(MenuItem menuItem){
    
    
        list.add(menuItem);
    }

    public Integer getPreBlankCount() {
    
    
        return preBlankCount;
    }

    public LinkedList<MenuItem> getList() {
    
    
        return list;
    }
}

3. File reading tool MyFileReader

package com.dreamchaser.work4;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件读取类
 */
public class MyFileReader {
    
    
    /**
     * 读取项目文件,以行字符串list返回
     * @param name
     * @return
     */
    public static List<String> readFile(String name){
    
    
        List<String> list=new ArrayList<>(20);
        //获取文件加载时的绝对路径
        String filePath=MyFileReader.class.getClassLoader().getResource(name).getFile();
        File file=new File(filePath);
        if (file.exists()&&file.isFile()){
    
    
            BufferedReader reader=null;
            try {
    
    
                reader=new BufferedReader(new FileReader(file));
                String line=null;
//                //前置空格
                while ((line=reader.readLine())!=null){
    
    
                    list.add(line);
                }
            } catch (FileNotFoundException e) {
    
    
                e.printStackTrace();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }finally {
    
    
                try {
    
    
                    //最后将输入流关闭
                    reader.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }

        }
        return list;
    }
}

4. Regular expression package class RegexUtil

package com.dreamchaser.work4;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexUtil {
    
    
    /**
     * 返回单个字符串,若匹配到多个的话就返回第一个,方法与getSubUtil一样
     * @param soap
     * @param rgex
     * @return
     */
    public static String getSubUtilSimple(String soap,String rgex){
    
    
        Pattern pattern = Pattern.compile(rgex);// 匹配的模式
        Matcher m = pattern.matcher(soap);
        int i=0;
        while(m.find()){
    
    
            return m.group(0);
        }
        return "";
    }
}

5. Handler

package com.dreamchaser.work4;

import java.util.ArrayList;
import java.util.List;

/**
 * 用于处理读取文件后的list,将其处理成根目录返回
 */
public class Handler {
    
    
    public static List<MenuAnalyseStru> handle(List<String> strings){
    
    
        List<MenuAnalyseStru> menuAnalyseStrus=new ArrayList<>(5);
        /**
         * 表示层数
         */
        Integer layer=0;
        /**
         * 前置空格数
         */
        Integer pre=0;
        for (String s:strings){
    
    
            //通过正则表达式匹配相应的前置空格,然后统计长度赋值给pre
            pre=RegexUtil.getSubUtilSimple(s,"^ +").length();
            //创建相应的菜单选项
            MenuItem menuItem=new MenuItem(s);

            if (menuAnalyseStrus.size()==pre/4){
    
    
                //当前层如果没有创建对象则先创建对象
                MenuAnalyseStru menuAnalyseStru=new MenuAnalyseStru(pre);
                menuAnalyseStru.add(menuItem);
                menuAnalyseStrus.add(menuAnalyseStru);
            }else {
    
    
                menuAnalyseStrus.get(pre/4).add(menuItem);
            }
            //如果不是第一层的话,则要把子节点加入父节点中
            if (pre!=0){
    
    
                //获取上一层的最后一个,即父节点
                MenuItem father=menuAnalyseStrus.get(pre/4-1).getList().getLast();
                //再将其加入父节点的子节点中
                father.getMenu().add(menuItem);
            }
        }
        return menuAnalyseStrus;
    }


}

6. Test class Test

package com.dreamchaser.work4;


import java.util.List;

/**
 * 测试类
 */
public class Test {
    
    
    public static void main(String[] args) {
    
    
        //读取文件
        List<String> list=MyFileReader.readFile("TurboC.txt");
        //处理数据
        List<MenuAnalyseStru> strus=Handler.handle(list);
        //打印输出,只需获取顶层的菜单选项遍历即可
        for (MenuItem m:strus.get(0).getList()){
    
    
            m.print();
        }
    }
}

4. Running results (test results)

Insert picture description here

Insert picture description here

Five, gain experience

The main part of the time is that the handler reads the array into the data structure we designed. That part of the logic is a bit convoluted. At first I thought it was complicated, but later I found that it can be quite simple.
There is also how to read the leading spaces. At that time, I only knew that I could use regular expressions to do it. As for how to do it, it was still a bit vague (I didn’t have much impression before I encountered it). Later I went to other people’s blogs. Gradually master.
In addition, reading the file path is also a difficult point. Generally, this path can only be an absolute path (in a maven project, the resource file is placed in the resouces directory). Using a relative path will report the file not found exception, so How to read the absolute path of the file according to the running environment of the program is also a difficult point.

Guess you like

Origin blog.csdn.net/qq_46101869/article/details/109647885