C ++在二叉树中存储文件

时间:2015-12-11 22:50:34

标签: c++ string binary-tree

我正在完成一个C ++项目,其中我将文本文件作为字符串读取并将其存储在二叉树中。我必须将文件中的每个字母存储在二叉树中,以及该字母出现的次数。然后我必须存储2个字母出现,依此类推到用户给出的k次出现。例如,如果一个文件包含abcdef,我必须在树中存储a,b,c,d,e,f,然后我再次遍历字符串并存储ab,bc,cd,de,ef和abc,bcd, cde,def等,直到用户输入的数字。它们存储的次数是多少次,如果字符串传递给树并且树已经包含该字符串,则该字符串的数量只增加1。我的代码适用于单次和双次出现,但是对于大于2的事件,它总是将最后一次双重事件传递给树两次。

这是main.cpp文件:

mDesiredWorkTime = workFromDatabase;
mDesiredRestTime = restFromDatabase;

这是binarytree.cpp文件:

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include "binarytree.h"
using namespace std;

int main()
{
    string filename;
    string filedata;
    string a;
    string b;
    int num;
    BinaryTree tree;
    fstream file;

    cout << "Please enter a filename: ";
    cin >> filename;

    file.open(filename.c_str(), ios::in);

    if (!file)
    {
    cout << "ERROR: Cannot open file.";
    }

    else
    {
        cout << "Please enter the maximum number of consecutive letters to count the occurrences of: ";
        cin >> num;

        while (num < 1)
        {
            cout << "Please enter a number greater than 0: ";
            cin >> num;
        }
    }

    while (getline(file, a))
    {
        filedata += a;
    }

    cout << "File data: " << filedata << endl;
    filedata.erase(remove(filedata.begin(),filedata.end(),' '),filedata.end());
    cout << "File data: " << filedata << endl;

    for (unsigned int i = 0; i < filedata.size(); i++)
    {
        if (filedata[i] != ' ')
        {
            string a(1, filedata[i]);
            tree.insertNode(a);
        }
    }

    if (num > 1)
    {
        for (int i = 2; i < num + 1; i++)
        {
            int k = 1;
            for (unsigned int j = 0; j < filedata.size()-1; j++)
            {
                if (filedata[j+k] == '\0')
                    cout << "null" << endl;
                else if (filedata[j+k] != '\0')
                {
                    b = "";
                    b += filedata.substr(j, i);
                    tree.insertNode(b);
                }
            }
            k++;
        }
    }

    file.close();

    tree.displayInOrder();

    return 0;
}

这是binarytree.h文件:

#include <iostream>
#include <cstdlib>
#include "binarytree.h"
using namespace std;

void BinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode, string letter)
{

    if (nodePtr == NULL)
    {
        TreeNode *newTreeNode = new TreeNode;
        newTreeNode->letter = letter;
        newTreeNode->value = 1;
        newTreeNode->left = newTreeNode->right = NULL;
        if(newNode->letter > newTreeNode->letter)
            newNode->left = newTreeNode;
        else
            newNode->right = newTreeNode;
    }
    else if (nodePtr->letter > letter)
        insert(nodePtr->left, nodePtr, letter);
    else if (nodePtr->letter < letter)
        insert(nodePtr->right, nodePtr, letter);
    else if (nodePtr->letter == letter)
        nodePtr->value += 1;
}

void BinaryTree::insertNode(string letter)
{
    if (root == NULL)
    {
        root = new TreeNode;
        root->letter = letter;
        root->value = 1;
        root->left = root->right = NULL;
    }
    else if(root->letter > letter)
        insert(root->left, root, letter);
    else if(root->letter < letter)
        insert(root->right, root, letter);
    else if(root->letter == letter)
        root->value += 1;
}

void BinaryTree::destroySubTree(TreeNode *nodePtr)
{
    if (nodePtr)
    {
        if (nodePtr->left)
            destroySubTree(nodePtr->left);
        if (nodePtr->right)
            destroySubTree(nodePtr->right);
        delete nodePtr;
    }
}

void BinaryTree::displayInOrder(TreeNode *nodePtr) const
{
    if (nodePtr)
    {
        displayInOrder(nodePtr->left);
        cout << nodePtr->letter << ": " << nodePtr->value << endl;
        displayInOrder(nodePtr->right);
    }
}

这是文本文件:

#include <iostream>
#include <string>
#ifndef BINARYTREE_H_
#define BINARYTREE_H_
using namespace std;

class BinaryTree
{
    private:
        struct TreeNode
        {
            string letter;
            int value;
            TreeNode *left;
            TreeNode *right;
        };

        TreeNode *root;

        void insert(TreeNode *&, TreeNode *&, string);
        void destroySubTree(TreeNode *);
        void deleteNode(int, TreeNode *&);
        void makeDeletion(TreeNode *&);
        void displayInOrder(TreeNode *) const;

    public:
        BinaryTree()
        {
            root = NULL;
        }
        ~BinaryTree()
        {
            destroySubTree(root);
        }
        void insertNode(string);
        void remove(int);
        void displayInOrder() const
        {
            displayInOrder(root);
        }
};

#endif

当在程序中输入文本文件以及出现次数为num 3时,会显示在屏幕上:

a:2 az:1 azu:1 e:1 欧:1 euu:1 j:1 ja:1 贾兹:1 你:4 ua:2 你:1 ueu:1 uu:2 uua:1 uue:1 z:1 zu:1 zuu:1 //(每个都在一个新行上)

并且正如你所看到的,当它只被计算一次时,它被计算两次。仅当num>时才会发生这种情况。 2.问题出现在if(num&gt; 1)语句中。我试图避免传递给树的空字符,我添加了一个cout语句来显示&#34; null&#34;如果达到null但是从未显示过,我不确定导致问题的是什么。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

问题在于这个循环:for (unsigned int j = 0; j < filedata.size()-1; j++)

这并不能保证所有插入的元素都具有i的大小。

如果用for (unsigned int j = 0; j < filedata.size()-i+1; j++)替换它,那么j将上升到长度为i的字符串的最后一个索引,这就是你要找的。