Member 13779871 Ответов: 2

Посмотрите, какие слова существуют в моем BST из файла


Я пытаюсь вывести "неправильно написанные" (слова, которые не находятся в BST) слова из файла, который я вставляю. Таким образом, в основном у меня есть полностью функциональное двоичное дерево. Только необходимые функции вставки и существует. Когда я вставляю свой словарь (пока что очень хороший) и читаю файл, содержащий несколько слов в каждой строке, он выходит из строя (отображает преобразованные слова из верхнего регистра в нижний и те, которые имели пунктуацию. Но когда я вставляю файл, в котором каждое слово находится в другой строке, программа выдает мне слова с ошибками.

<pre>#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <algorithm>
#include "bst.h"

using namespace std;

int main()
{
    char dictionaryFile[50]; //input dictionary file
	char file[50]; // input file
	
	string misspelt; // misspelt 
	string wordsDictionary;
	string words;
	
	ifstream inputDictionaryFile; // file input
	ifstream inputFile;
	BinarySearchTree *tree = new BinarySearchTree();
	
	/* GETTING DICTIONARY*/
	
	cout << "Enter dictionary file name: ";
	
	cin.getline(dictionaryFile,1000); // getting lines 
	
	inputDictionaryFile.open(dictionaryFile); //open
	
	//if it fails to open - Error
	if(!inputDictionaryFile.is_open())
	{
		cout << "Fail to open file" << endl;
		exit(EXIT_FAILURE);
	}
	
	while(inputDictionaryFile >> wordsDictionary)
	{
		int i =0;
		for( i = 0;wordsDictionary[i]!='\0'; i++) 
		{
			//find upperCase letters
			if(wordsDictionary[i] >= 'A' && wordsDictionary[i] <= 'Z')
			{
				//overwrite to lowerCase
				wordsDictionary[i] = tolower(wordsDictionary[i]);			
					
			}//end of if statement 
			//ignore tab
			if(wordsDictionary[i] == '\t')
			{ 
				wordsDictionary[i] = ' ';
			}//end of if statement
	
			//ignoring punctuation 	
			if(wordsDictionary[i] == ',' || wordsDictionary[i] == '.' || wordsDictionary[i] == '!' || wordsDictionary[i] == '?' || wordsDictionary[i] == '"' || wordsDictionary[i] == ':' || wordsDictionary[i] ==';' || wordsDictionary[i] == '-' || wordsDictionary[i] == '/' || wordsDictionary[i] == '`' || wordsDictionary[i] == '&' || wordsDictionary[i] == '@' || wordsDictionary[i] == '^' || wordsDictionary[i] == '(' || wordsDictionary[i] == ')' || wordsDictionary[i] == '<' || wordsDictionary[i] == '>' || wordsDictionary[i] == '#' || wordsDictionary[i] == '%' || wordsDictionary[i] == '{' || wordsDictionary[i] == '}' || wordsDictionary[i] == '[' || wordsDictionary[i] == ']' || wordsDictionary[i] == '|' || wordsDictionary[i] == '+' || wordsDictionary[i] == '*')
			{
				wordsDictionary[i] = ' ';
			}//end of is statement 
				
			//ignore if there is double space
			if(wordsDictionary[i] == '  ')
			{
				wordsDictionary[i] = ' ';
			}//end of if statement
		}
		tree->insert(wordsDictionary); // insert to file
	}
	
	if(tree == nullptr)
	{
		cout << "Empty tree" << endl;
	}
	
	/* GETTING FILE*/
	
	cout << "Enter file name: ";
	
	cin.getline(file,1000); // getting lines 
	
	inputFile.open(file); //open
	//if it fails to open - Error
	if(!inputFile.is_open())
	{
		cout << "Fail to open file" << endl;
		exit(EXIT_FAILURE);
	}
	
	while(inputFile >> words)
	{	
		int i =0;
		for( i = 0;words[i]!='\0'; i++) 
		{
			//find upperCase letters
			if(words[i] >= 'A' && words[i] <= 'Z')
			{
				//overwrite to lowerCase
				words[i] = tolower(words[i]);			
				
			}//end of if statement 
				
			//ignore tab
			if(words[i] == '\t')
			{ 
				words[i] = ' ';
			}//end of if statement
	
			//ignoring punctuation 	
			if(words[i] == ',' || words[i] == '.' || words[i] == '!' || words[i] == '?' || words[i] == '"' || words[i] == ':' || words[i] ==';' || words[i] == '-' || words[i] == '/' || words[i] == '`' || words[i] == '&' || words[i] == '@' || words[i] == '^' || words[i] == '(' || words[i] == ')' || words[i] == '<' || words[i] == '>' || words[i] == '#' || words[i] == '%' || words[i] == '{' || words[i] == '}' || words[i] == '[' || words[i] == ']' || words[i] == '|' || words[i] == '+' || words[i] == '*')
			{
				words[i] = ' ';
			}//end of is statement 
				
			//ignore if there is double space
			if(words[i] == '  ')
			{
				words[i] = ' ';
			}//end of if statement
			
		} //end of for loop	
		//tree->exists(words);
		if(!tree->exists(words))
		{
			cout <<"Misspelled: " << words << endl;
		}
	}
	
	delete tree;
	
	return 0;
}

^
|
spellChecker.cpp файл

<pre lang="c++"><pre>// Checks if a word is in the tree
bool BinarySearchTree::exists(std::string word) const
{
    Node* node = root;
	while(node != nullptr)
	{
		if(node->data == word) 
		{
			return true;
		}
		else
		{
			if (word > node->data)
			{
				node = node->right;
			}
			else
			{
				node = node->left;
			}
		}
	}
	return false;
}


<pre>//Helper function to insert a word into the tree
void insertHelper(Node **node, std::string word)
{
	//Check if nullptr. If so set new node
	if(*node == nullptr)
	{
		//Create new node
		*node = new Node;
		//Set new word
		(*node)-> data = word;
		//Set branches to nullptr
		(*node)-> left = nullptr;
		(*node)->right = nullptr;
	}
	else  // if not empty
	{
		if(word < (*node)->data)
			insertHelper(&(*node)->left,word);
		else if(word > (*node)->data)
			insertHelper(&(*node)->right, word);
		else
			return;
	}
}

// Adds a word to the tree
void BinarySearchTree::insert(std::string word)
{
	insertHelper(&root, word);
}



Отдельных слов входного файла
C 
is
the
most
commonly
used
programming
language
for
writing
operating
systems
The 
first
operatingg
system
written 
in 
C 
is 
Unix
Later 
operating
systems 
like 
Linux 
were 
all 
written 
in 
C 
Not 
only 
is 
C 
the 
language 
of 
operating 
systems 
it 
is 
the 
precursor 
and 
insspiration 
for 
almost 
all 
of 
the 
most 
popular 
high 
level 
languages 
available 
today 
In 
fact
Perl 
PHP 
Python 
and 
Ruby 
are 
all 
writtten 
in
c

И другой похож, но слова находятся на той же линии. Есть также вкладки.

Что я уже пробовал:

Я попробовал изменить свою пунктуационную функцию
//ignoring punctuation 	
			if(wordsDictionary[i] == ',' || wordsDictionary[i] == '.' || wordsDictionary[i] == '!' || wordsDictionary[i] == '?' || wordsDictionary[i] == '"' || wordsDictionary[i] == ':' || wordsDictionary[i] ==';' || wordsDictionary[i] == '-' || wordsDictionary[i] == '/' || wordsDictionary[i] == '`' || wordsDictionary[i] == '&' || wordsDictionary[i] == '@' || wordsDictionary[i] == '^' || wordsDictionary[i] == '(' || wordsDictionary[i] == ')' || wordsDictionary[i] == '<' || wordsDictionary[i] == '>' || wordsDictionary[i] == '#' || wordsDictionary[i] == '%' || wordsDictionary[i] == '{' || wordsDictionary[i] == '}' || wordsDictionary[i] == '[' || wordsDictionary[i] == ']' || wordsDictionary[i] == '|' || wordsDictionary[i] == '+' || wordsDictionary[i] == '*')
				wordsDictionary[i] = ' ';
			}//end of is statement 
				
			//ignore if there is double sp

в ispunct но это не сработало. Понятия не имею, как игнорировать знаки препинания, не заменяя их чем-то другим. Попробовал вставить и существующую функцию в другой цикл. Попробовал с помощью метода что - то вроде этого :
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string str = "this. is my string. it's here.";

    transform(str.begin(), str.end(), str.begin(), [](char ch)
    {
        if( ispunct(ch) )
            return '\0';
        return ch;
    });
}

Richard MacCutchan

Вы используете кувалду, чтобы расколоть орех; большая часть вашего кода избыточна и даже может быть неправильной. Существуют функции C и классы C++, которые могут разбивать строки на отдельные токены и выполнять сравнения без учета регистра.

2 Ответов

Рейтинг:
2

Richard MacCutchan

//ignore if there is double space
if(words[i] == '  ') // ???
{
	words[i] = ' ';
}//end of if statement

Вы не можете создать символьные константы более одного символа, и вы не можете сравнить один символ с двумя символами. Я предполагаю, что вы подавляете или игнорируете предупреждающие сообщения компилятора.


Рейтинг:
0

KarstenK

Научитесь пользоваться отладчик чтобы проверить ваш код.

Я бы решил проверку символов другим способом: только добавьте разрешающий символ к слову, которое входит в ваше дерево. Я думаю, что это сработало бы вокруг вашей недостающей обработки CR и LF.

Таким образом код может быть упрощен:

void insertHelper(Node *node, std::string word)
И я бы добавил конструктор узлов, который берет строку и устанавливает left и right в NULL.