[英]C++ Storing File in Binary Tree
I am finishing a C++ project in which I read a text file as a string and store it in a binary tree. 我正在完成一个C ++项目,在该项目中,我将文本文件读取为字符串并将其存储在二进制树中。 I have to store each letter from the file in a binary tree along with a number of how many times that letter occurs. 我必须将文件中的每个字母以及该字母出现多少次存储在二进制树中。 I then have to store 2 letter occurrences and so on to k occurrences given by the user. 然后,我必须存储2个字母出现,以此类推,直到用户给出k个出现。 For example if a file contains abcdef I have to store a, b, c, d, e, f in the tree and then I go through the string again and store ab, bc, cd, de, ef, and abc, bcd, cde, def, etc. up to the number entered by the user. 例如,如果文件包含abcdef,则必须在树中存储a,b,c,d,e,f,然后再次遍历字符串并存储ab,bc,cd,de,ef和abc,bcd, cde,def等,最多不超过用户输入的数字。 These are stored with a number of how many times they occur, and if a string is ever passed to the tree and the tree already contains that string, the number of that string is simply incremented by one. 这些存储有它们发生的次数,并且,如果将某个字符串传递给该树,并且该树已经包含该字符串,则该字符串的数量仅增加1。 My code is working for single and double occurrences, but for occurrences greater than 2 it is always passing the last double occurrence to the tree twice. 我的代码适用于单次和两次出现,但对于大于2的出现,它总是将最后一次两次出现传递给树两次。
Here is the main.cpp file: 这是main.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;
}
Here is the binarytree.cpp file: 这是binarytree.cpp文件:
#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);
}
}
Here is the binarytree.h file: 这是binarytree.h文件:
#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
And here is the text file: 这是文本文件:
j a z uu e uu a
When the text file is entered in the program along with num 3 for the number of occurrences, this is displayed to the screen: 当文本文件与数字3一起输入到程序中时,将显示在屏幕上:
a: 2 az: 1 azu: 1 e: 1 eu: 1 euu: 1 j: 1 ja: 1 jaz: 1 u: 4 ua: 2 ue: 1 ueu: 1 uu: 2 uua: 1 uue: 1 z: 1 zu: 1 zuu: 1 //(each on a new line) a:2 az:1 azu:1 e:1 eu:1 euu:1 j:1 ja:1 jaz:1 u:4 ua:2 ue:1 ueu:1 uu:2 uua:1 uue:1 z: 1 zu:1 zuu:1 //(每个换行)
and as you can see ua is being counted twice when it should only be counted once. 如您所见,ua只应计数一次,所以ua被计数两次。 This only occurs when num > 2. The problem is somewhere in the if(num > 1) statement. 仅当num> 2时才会发生。问题出在if(num> 1)语句中。 I am trying to avoid the null character being passed to the tree and I added a cout statement to display "null" if null is ever reached but this is never displayed, and I am not sure what is causing the problem. 我试图避免将null字符传递给树,并且添加了cout语句,如果曾经达到null却从未显示过,则显示“ null”,但我不确定是什么引起了问题。
Thanks for your help. 谢谢你的帮助。
The issue is with this loop: for (unsigned int j = 0; j < filedata.size()-1; j++)
. 问题在于此循环: for (unsigned int j = 0; j < filedata.size()-1; j++)
。
This doesn't guarantee that all inserted elements will have a size of i. 这不能保证所有插入的元素的大小都为i。
If you replace it with for (unsigned int j = 0; j < filedata.size()-i+1; j++)
, then j will go up to the last index for a string of length i, which is what you are looking for. 如果将其替换for (unsigned int j = 0; j < filedata.size()-i+1; j++)
,则j会升至长度为i的字符串的最后一个索引,这就是您要查找的对于。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.