C # Обновление бинарного дерева поиска слов - PullRequest
0 голосов
/ 23 ноября 2018

Итак, у меня есть реализация Binary Search Tree, предназначенная для документов HTML, которая принимает имя документа и некоторый контент HTML и создает дерево слов вместе с их количеством в документе и именем документа.Затем дерево визуализируется внутри элемента управления TreeView следующим образом:

- Root: html - d1, C: 4
- - Left: head - d1, C: 2
- - - Left: document - d1, C: 2
- - - - Left: body - d1, C: 2
- - Right: title - d1, C: 2
- - - Left: simple - d1, C: 2
- - - - Left: p - d1, C: 4
- - - - - Right: paragraphs - d1, C: 1
- - - Right: two - d1, C: 1

И входной HTML-документ выглядит следующим образом (удаляются стоп-слова и специальные символы):

<html>
<head>
<title>
  A Simple HTML Document
</title>
</head>
 <body>
  <p> This is a very simple HTML document</p>
  <p>It only has two paragraphs</p>

</body>
</html>

Теперь,Моя задача - обновить (и расширить) это дерево, используя другие документы.Проблема в том, что узлы со словами, которые уже существуют в дереве, нужно добавлять, а не добавлять как новые, например:

- Root: html - d1, C: 4, d2, C: 2
-- Left: head - d1, C: 2, d2, C: 2, d3, C:3 (and so on)

Это мой основной код для дерева:

public class Node
    {
        public string data;
        public Node left { get; set; }
        public Node right { get; set; }

        public Node(string data)
        {
            this.data = data;
            left = right = null;
        }
    }
    public class Tree
    {
        public Node root;
        public Tree()
        {
            root = null;
        }
        public void insert(string data, TreeView view)
        {
            Node newItem = new Node(data);
            if (root == null)
            {
                root = newItem;
            }
            else
            {
                Node current = root;
                Node parent = null;
                while (current != null)
                {
                    parent = current;
                    if (String.Compare(data, current.data) < 0)
                    {
                        current = current.left;
                        if (current == null)
                        {
                            parent.left = newItem;
                        }
                    }
                    else
                    {
                        current = current.right;
                        if (current == null)
                        {
                            parent.right = newItem;
                        }
                    }
                }
            }
        }

        public String search(string element, Node root)
        {
            Node current = root;
            if (current == null)
            {
                return "Not found";
            }
            if (String.Compare(element, current.data) == 0)
            {
                return element;
            }
            if (String.Compare(element, current.data) < 0)
            {
                return this.search(element, current.left);
            }
            else
            {
                return this.search(element, current.right);
            }
        }
    }



    public void preOrder(Node node, TreeNode treeNode)
    {
        treeNode.Text += node.data;
        if (node.left != null)
        {
            preOrder(node.left, treeNode.Nodes.Add("Left: "));
        }
        if (node.right != null)
        {
            preOrder(node.right, treeNode.Nodes.Add("Right: "));
        }
    }

    void DisplayTree(Tree tree)
    {
        preOrder(tree.root, treeView1.Nodes.Add("Root: "));
    }

Метод onclick:

private void button6_Click(object sender, EventArgs e)
    {
        string d_name = textBox1.Text;
        if(d_name == "")
        {
            MessageBox.Show("Please enter a document name.", "Indexing");
            return;
        }
        Tree glb_tree = new Tree();
        string data = richTextBox1.Text;
        if(data == "")
        {
            MessageBox.Show("Missing input.", "Indexing");
            return;
        }
        //creates a list of the needed words
        List<string> dataList = createList(data, d_name);
        glb_tree = createTree(dataList, treeView1, glb_tree, doc_names, d_name);

    }

И функция дерева:

public Tree createTree(List<string> input, TreeView treeView, Tree bst, List<string> doc_names, string cur_name)
    {
        int word_count = 1;
        string res = "";
        string tree_res = "";
        var match = doc_names.FirstOrDefault(stringToCheck => stringToCheck.Contains(cur_name));
        // Do not allow existing document names
        if (match == null)
        {
            doc_names.Add(cur_name);
        }
        else
        {
            MessageBox.Show("Document Name already exists!", "Tree Create");
            return null;
        }
        for (int i = 0; i < input.Count; i++)
        {
            for (int j = i + 1; j < input.Count; j++)
            {
                //Calculate word count
                if (input[i] == input[j])
                {
                    input[j] = "";
                    word_count++;
                }
            }

            res = input[i] + " - " + cur_name + ", C:" + word_count;
            //Some elements in word list are empty, skip them
            if (res.StartsWith(" -"))
            {
                word_count = 1;
                continue;
            }
            bst.insert(res, treeView);
            word_count = 1;
        }
        DisplayTree(bst);
        treeView1.ExpandAll();
        return bst;
    }

РЕДАКТИРОВАТЬ : Неважно, решил мою проблему, этобыло на самом деле довольно просто.Мне просто нужно было изменить список, который идет к дереву в качестве входных данных, а не изменять само дерево.Поэтому я просто добавил простую вспомогательную функцию для добавления новых данных:

public List<string> appendToList(List<string> cur_data, string data, string dname)
    {
        List<string> newDataList = createList(data, dname);
        bool found = false;

        if (newDataList != null && cur_data != null)
        {
            for(int i=0; i<newDataList.Count; i++)
            {
                found = false;
                for(int j=0; j < cur_data.Count; j++)
                {
                    string op1 = newDataList[i].Substring(0, newDataList[i].IndexOf(' '));
                    string op2 = cur_data[j].Substring(0, cur_data[j].IndexOf(' '));
                    if (op1.Equals(op2))
                    {
                        int wcsub = newDataList[i].IndexOf(':') + 2;
                        int wclength = newDataList[i].IndexOf(';') - wcsub;
                        string wc = newDataList[i].Substring(wcsub, wclength);
                        cur_data[j] += dname + ": " + wc + "; ";
                        found = true;
                        break;
                    }                 
                }
                if (!found)
                {
                    cur_data.Add(newDataList[i]);
                }
            }
        }
        return cur_data;
    }
...