Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <cstring>
- #include <iomanip>
- #include "BST.h"
- using namespace std;
- //define a node in a single linked list with data and a link field
- struct ListNode
- {
- char data;
- ListNode * next;
- };
- /* The class defines a List ADT with the core functionality, specifically the
- ability to: 1) Insert an item into a List, 2) Delete an item from the List,
- 3) Print the List, and 4) Edit an item in the List. The only data maintained
- by the List is a pointer to the current head (front) of the list. If the
- List is empty, then head will be equal to NULL.
- */
- class List
- {
- public:
- List();
- ~List();
- bool Enq(char);
- ListNode* Deq();
- void Print();
- bool Edit(char, char);
- bool Empty();
- string toStr();
- void deleteAll();
- private:
- void deleteAllRecursion(ListNode*);
- ListNode * head;
- ListNode * rear;
- };
- List::List()
- {
- head = NULL;
- rear = NULL;
- }
- List::~List()
- {
- //Checking if the list is empty
- if (head != NULL)
- {
- for (ListNode*cur = head; cur != NULL; cur = cur->next)
- {
- //cycling through the linked list to delete
- ListNode*temp = head;
- head = head->next;
- delete temp;
- }
- }
- head = NULL;
- rear = NULL;
- }
- /*This function creates a new node and if head is null, sets head to it.
- If not, rear->next is set to temp. Then rear is set to temp.*/
- bool List::Enq(char insertedData)
- {
- ListNode *temp = new ListNode;
- if (!temp){
- cout << "Memory allocation failed...\n";
- return false;
- }
- temp->data = insertedData;
- temp->next = NULL;
- if (head == NULL){
- head = temp;
- }
- else{
- rear->next = temp;
- }
- rear = temp;
- return true;
- }
- /*trail, a pointer to a Node, is declared. The list is traversed and each Node's data is checked against the char to be deleted.
- The trail keeps track of the previous Node. If the Node to be deleted is head, head is changed to head->next and the Node is
- deleted. Otherwise, the list is traversed the rest of the way and Node pointers are reassigned and the Node to be deleted is
- removed, deallocating its memory.
- */
- ListNode* List::Deq()
- {
- if (head != NULL){
- ListNode*returnvalue = head;
- head = head->next;
- return returnvalue;
- }
- else{
- return NULL;
- }
- }
- //The List is traversed and all of its values are outputted to the console.
- void List::Print()
- {
- for (ListNode*cur = head; cur != NULL; cur = cur->next)
- {
- cout << cur->data << endl;
- }
- }
- /******************************************************************************
- delete all is public, allowing for the deconstruction of the list on the fly.
- I don't feel like calling the deconstructor so here you go: an even sillier
- way to delete the whole list... through recursion. Because I like recursion.
- ******************************************************************************/
- void List::deleteAll(){
- deleteAllRecursion(head);
- head = NULL;
- rear = NULL;
- }
- void List::deleteAllRecursion(ListNode* aye){
- if (aye != NULL){
- deleteAllRecursion(aye->next);
- }
- delete aye;
- }
- //checks if the list is empty
- bool List::Empty(){
- return(head == NULL && rear == NULL);
- }
- //this loops through the linked list and stores them in a c-string one by one.
- //that c-string is stored in a string object and outputted. **WARNING** c-string
- //is statically allocated to 50 characters, so no more than 49 characters per word.
- //idk if this will be a problem, we'll see.
- string List::toStr(){
- char cstrOut[50];
- int x = 0;
- ListNode*out = Deq();
- while (out != NULL){
- cstrOut[x++] = out->data;
- out = Deq();
- }
- cstrOut[x] = NULL;
- string output = cstrOut;
- return output;
- }
- /*This function searches the c-string for a word and stores it in a queue
- then turns it into a string and returns it.
- */
- void parsingForWords(string line, BST &wordCount){
- int length = line.length();
- const char* lineCstr = line.c_str();
- List word;
- for (int x = 0; x < length; x++)
- {
- if (isalpha(lineCstr[x])){
- word.Enq(toupper(lineCstr[x]));
- }
- else if (!word.Empty()){
- wordCount.Insert(word.toStr());
- }
- }
- }
- void main()
- {
- //I feel like this could have been more efficient, but this is how I did it.
- //a new BST object is created
- BST WordCount;
- //a std::string is created to store the inputted filename
- string fileName;
- //input the file name
- cout << "Enter name of file to be processed (79 characters or less, including extension): ";
- cin >> fileName;
- //the size of the string is saved in a const int
- const int fileNameSize = fileName.length();
- /****************************************************************************************************
- Very elaborate code designed to create the input and output files. This prevents the original name
- from being altered while simultaneously creating the output file in the BST to create the .frq file.
- The function takes a string (the file name) as a parameter, and creates several local variables to
- get the output file name to have a .frq instead of .txt (or whatever it's extension is; it's set up
- to stop at a '.'). The many local variables create a c-string to store the std::string in order to
- process it. A while loop stores the individual characters into a new c-string until a '.' or NULL is
- reached, at which point the loop exits and adds '.frq' on, each character at a time. The post-
- increment operator is used often. Then finally, NULL is stored in the last slot. **WARNING** The
- file name character array is statically allocated to store 80 characters, so the file name cannot
- exceed 79 characters.
- ****************************************************************************************************/
- const char* cstr = fileName.c_str();
- //that elaborate slew of local variables slowing the program down but getting done what I want
- char outFileName[80];
- int j = 1;
- char i = *cstr;
- //the loop to store the file name, minus the extension
- while (i != '.' && i != NULL)
- {
- outFileName[j] = i;
- i = *(cstr + j);
- j++;
- }
- //adding the new extension
- outFileName[j++] = '.';
- outFileName[j++] = 'f';
- outFileName[j++] = 'r';
- outFileName[j++] = 'q';
- outFileName[j] = NULL;
- /*****************************************************************************
- the OutputFile member of the WordCount BST's open method is used to open the
- file, and the outFileName is passed to it as a name.
- *****************************************************************************/
- WordCount.OutputFile.open(outFileName);
- //the input file is opened.
- ifstream inFile(fileName);
- //the parsing function is called while reading in line-by-line.
- if (!inFile.good())
- cout << "Input file not opened...\n";
- else{
- while (!inFile.eof()){
- string line;
- getline(inFile, line);
- parsingForWords(line, WordCount);
- }
- }
- //The user is asked if they wish to delete a Node.
- //If I had time, I'd learn to use GUIs and implement one, but I dont
- //so I won't. Enjoy the command line instead. q:
- char input;
- string deleteThis;
- cout << "Delete a node? (y/n)";
- cin >> input;
- while (input == 'y' || input == 'Y'){
- cin >> deleteThis;
- WordCount.Delete(deleteThis);
- cout << "Delete a node? (y/n)";
- cin >> input;
- }
- //The final frontier... writing it all.
- WordCount.write();
- WordCount.OutputFile << "Height: " << WordCount.findMax() << endl
- << "Number of Nodes: " << WordCount.NodeTotal() << endl;
- WordCount.OutputFile.close();
- }
Advertisement
Add Comment
Please, Sign In to add comment