当出现“同义词”这个词时,我想停止阅读我的文本输入文件。我正在使用ifstream而且我不知道如何打破循环。我尝试使用字符串流“同义词”,但它结束了我的bst。我在下面列出了完整的项目文件,以防你想避免打字。
重要部分:
for(;;) /*here, I wanna break the cycle when it reads "synonyms"*/
{
inStream >> word;
if (inStream.eof()) break;
wordTree.insert(word);
}
wordTree.graph(cout);
dictionary.txt
1 cute
2 hello
3 ugly
4 easy
5 difficult
6 tired
7 beautiful
synonyms
1 7
7 1
antonyms
1 3
3 1 7
4 5
5 4
7 3
Project.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "MiBST.h"
using namespace std;
class WordInfo{
public:
//--id accesor
int id ()const {return myId; }
/* myId is the number that identifies each word*/
//--input function
void read (istream &in)
{
in>>myId>>word;
}
//--output function
void print(ostream &out)
{
out<<myId<<" "<<word;
}
//--- equals operator
bool operator==(const WordInfo & otherword) const
{ return myId == otherword.myId; }
//--- less-than operator
bool operator<(const WordInfo & otherword) const
{ return myId < otherword.myId; }
private:
int myId;
string word;
};
//--- Definition of input operator
istream & operator>>(istream & in, WordInfo & word)
{
word.read(in);
}
//---Definition of output operator
ostream & operator <<(ostream &out, WordInfo &word)
{
word.print(out);
}
int main(){
// Open stream to file of ids and words
string wordFile;
cout << "Enter name of dictionary file: ";
getline(cin, wordFile);
ifstream inStream(wordFile.data());
if (!inStream.is_open())
{
cerr << "Cannot open " << wordFile << "\n";
exit(1);
}
// Build the BST of word records
BST<WordInfo> wordTree; // BST of word records
WordInfo word; // a word record
for(;;) /*here, I wanna break the cycle when it reads "synonyms"*/
{
inStream >> word;
if (inStream.eof()) break;
wordTree.insert(word);
}
wordTree.graph(cout);
//wordTree.inorder(cout);
system ("PAUSE");
return 0;
}
MiBST.h(如果你想运行它)
#include <iostream>
#include <iomanip>
#ifndef BINARY_SEARCH_TREE
#define BINARY_SEARCH_TREE
template <typename DataType>
class BST
{
public:
/***** Function Members *****/
BST();
bool empty() const;
bool search(const DataType & item) const;
void insert(const DataType & item);
void remove(const DataType & item);
void inorder(std::ostream & out) const;
void graph(std::ostream & out) const;
private:
/***** Node class *****/
class BinNode
{
public:
DataType data;
BinNode * left;
BinNode * right;
// BinNode constructors
// Default -- data part is default DataType value; both links are null.
BinNode()
: left(0), right(0)
{}
// Explicit Value -- data part contains item; both links are null.
BinNode(DataType item)
: data(item), left(0), right(0)
{}
}; //end inner class
typedef BinNode * BinNodePointer;
/***** Private Function Members *****/
void search2(const DataType & item, bool & found,
BinNodePointer & locptr, BinNodePointer & parent) const;
/*------------------------------------------------------------------------
Locate a node containing item and its parent.
Precondition: None.
Postcondition: locptr points to node containing item or is null if
not found, and parent points to its parent.#include <iostream>
------------------------------------------------------------------------*/
void inorderAux(std::ostream & out,
BST<DataType>::BinNodePointer subtreePtr) const;
/*------------------------------------------------------------------------
Inorder traversal auxiliary function.
Precondition: ostream out is open; subtreePtr points to a subtree
of this BST.
Postcondition: Subtree with root pointed to by subtreePtr has been
output to out.
------------------------------------------------------------------------*/
void graphAux(std::ostream & out, int indent,
BST<DataType>::BinNodePointer subtreeRoot) const;
/*------------------------------------------------------------------------
Graph auxiliary function.
Precondition: ostream out is open; subtreePtr points to a subtree
of this BST.
Postcondition: Graphical representation of subtree with root pointed
to by subtreePtr has been output to out, indented indent spaces.
------------------------------------------------------------------------*/
/***** Data Members *****/
BinNodePointer myRoot;
}; // end of class template declaration
//--- Definition of constructor
template <typename DataType>
inline BST<DataType>::BST()
: myRoot(0)
{}
//--- Definition of empty()
template <typename DataType>
inline bool BST<DataType>::empty() const
{ return myRoot == 0; }
//--- Definition of search()
template <typename DataType>
bool BST<DataType>::search(const DataType & item) const
{
typename BST<DataType>::BinNodePointer locptr = myRoot;
typename BST<DataType>::BinNodePointer parent =0;
/* BST<DataType>::BinNodePointer locptr = myRoot;
parent = 0; */ //falta el typename en la declaracion original
bool found = false;
while (!found && locptr != 0)
{
if (item < locptr->data) // descend left
locptr = locptr->left;
else if (locptr->data < item) // descend right
locptr = locptr->right;
else // item found
found = true;
}
return found;
}
//--- Definition of insert()
template <typename DataType>
inline void BST<DataType>::insert(const DataType & item)
{
typename BST<DataType>::BinNodePointer
locptr = myRoot, // search pointer
parent = 0; // pointer to parent of current node
bool found = false; // indicates if item already in BST
while (!found && locptr != 0)
{
parent = locptr;
if (item < locptr->data) // descend left
locptr = locptr->left;
else if (locptr->data < item) // descend right
locptr = locptr->right;
else // item found
found = true;
}
if (!found)
{ // construct node containing item
locptr = new typename BST<DataType>::BinNode(item);
if (parent == 0) // empty tree
myRoot = locptr;
else if (item < parent->data ) // insert to left of parent
parent->left = locptr;
else // insert to right of parent
parent->right = locptr;
}
else
std::cout << "Item already in the tree\n";
}
//--- Definition of remove()
template <typename DataType>
void BST<DataType>::remove(const DataType & item)
{
bool found; // signals if item is found
typename BST<DataType>::BinNodePointer
x, // points to node to be deleted
parent; // " " parent of x and xSucc
search2(item, found, x, parent);
if (!found)
{
std::cout << "Item not in the BST\n";
return;
}
//else
if (x->left != 0 && x->right != 0)
{ // node has 2 children
// Find x's inorder successor and its parent
typename BST<DataType>::BinNodePointer xSucc = x->right;
parent = x;
while (xSucc->left != 0) // descend left
{
parent = xSucc;
xSucc = xSucc->left;
}
// Move contents of xSucc to x and change x
// to point to successor, which will be removed.
x->data = xSucc->data;
x = xSucc;
} // end if node has 2 children
// Now proceed with case where node has 0 or 2 child
typename BST<DataType>::BinNodePointer
subtree = x->left; // pointer to a subtree of x
if (subtree == 0)
subtree = x->right;
if (parent == 0) // root being removed
myRoot = subtree;
else if (parent->left == x) // left child of parent
parent->left = subtree;
else // right child of parent
parent->right = subtree;
delete x;
}
//--- Definition of inorder()
template <typename DataType>
inline void BST<DataType>::inorder(std::ostream & out) const
{
inorderAux(out, myRoot);
}
//--- Definition of graph()
template <typename DataType>
inline void BST<DataType>::graph(std::ostream & out) const
{ graphAux(out, 0, myRoot); }
//--- Definition of search2()
template <typename DataType>
void BST<DataType>::search2(const DataType & item, bool & found,
BST<DataType>::BinNodePointer & locptr,
BST<DataType>::BinNodePointer & parent) const
{
locptr = myRoot;
parent = 0;
found = false;
while (!found && locptr != 0)
{
if (item < locptr->data) // descend left
{
parent = locptr;
locptr = locptr->left;
}
else if (locptr->data < item) // descend right
{
parent = locptr;
locptr = locptr->right;
}
else // item found
found = true;
}
}
//--- Definition of inorderAux()
template <typename DataType>
void BST<DataType>::inorderAux(std::ostream & out,
BST<DataType>::BinNodePointer subtreeRoot) const
{
if (subtreeRoot != 0)
{
inorderAux(out, subtreeRoot->left); // L operation
out << subtreeRoot->data << " "; // V operation
inorderAux(out, subtreeRoot->right); // R operation
}
}
//--- Definition of graphAux()
template <typename DataType>
void BST<DataType>::graphAux(std::ostream & out, int indent,
BST<DataType>::BinNodePointer subtreeRoot) const
{
if (subtreeRoot != 0)
{
graphAux(out, indent + 8, subtreeRoot->right);
out << std::setw(indent) << " " << subtreeRoot->data << std::endl;
graphAux(out, indent + 8, subtreeRoot->left);
}
}
#endif
答案 0 :(得分:4)
您应该在WordInfo上创建一个运算符==以将其与字符串进行比较,然后您可以在阅读循环中进行此操作:
if ( word == "synonyms" ) break;
答案 1 :(得分:2)
你可以这样做
/* here, it stops when reading "synonyms" or when failing to extract a word. */
while(inStream >> word && word != "synonym") {
wordTree.insert(word);
}
wordTree.graph(cout);
请注意,当它无法读取一系列非空白字符时,它会设置流的失败位。 inStream的计算结果为false。这就是循环工作的原因。使用.eof();
时要小心。在尝试超出文件末尾读取后,它只返回true。因此,例如,您将退出循环,并在此处错过 3 tree 这个词:
1 house 2 garden 3 tree
假设树之后没有空格。如果您在单词信息之间有换行符并且在最后一个单词后面没有尾随换行符,那么当然会发生同样的情况。使用if(inStream)
(while循环隐式执行)是安全的。在这种情况下,它仍然会评估为真,如果除了空格之外没有读取任何内容,它仍然会为false。
答案 2 :(得分:0)
@SoapBox:
我创建了这个==运算符:
//--- equals operator for String
bool operator==(const string & aString) const
{ return word == aString; } // word is the WordInfo string field for 'real' word
并将for(;;)更改为:
for(;;)
{
inStream >> word;
if (word=="synonyms") break;
wordTree.insert(word);
}
结束了无限循环打印:
"Item already in the tree"
顺便说一下,我以前用这样的样本字典对树进行了测试,结果很有效。
dict2.txt
1可爱
你好
3难看
4容易
5难
6累
7美丽