Cannot create a parse tree from a postfix expression - c++

I am trying to create a parse tree from a postfix expression. But it is giving me segmentation error.
Here is my code:
#include <iostream>
#include <stack>
#include <string>
#include <set>
#include <vector>
#include <cstdio>
#include <queue>
#include <list>
using namespace std;
struct my_tree{
struct my_tree* left;
char a;
struct my_tree* right;
};
typedef struct my_tree TREE;
bool is_binary_op(char a){
if(a == '|' || a == '.') return true;
else return false;
}
bool is_unary_op(char a){
if(a == '*') return true;
else return false;
}
int main() {
string postfix = "ab|*a.b.";
stack<TREE*> parse_tree;
for(unsigned i=0; i<postfix.length(); i++){
if(is_binary_op(postfix[i])){
TREE* n;
TREE* right = parse_tree.top();
parse_tree.pop();
TREE* left = parse_tree.top();
parse_tree.pop();
n->left = left;
n->a = postfix[i];
n->right = right;
parse_tree.push(n);
} else if(is_unary_op(postfix[i])){
TREE* n;
TREE* left = parse_tree.top();
parse_tree.pop();
n->left = left;
n->a = postfix[i];
n->right = NULL;
parse_tree.push(n);
} else{
TREE* n;
n->left = NULL;
n->a = postfix[i];
n->right = NULL;
parse_tree.push(n);
}
}
return 0;
}

Modify all the
TREE *n;
into
TREE *n = new TREE;
since all of them seems to be a new node on tree. You need to allocate the actual instance by operator new.

Related

Read from text file and make a dictionary text file

I want to read a text file and store new words in linked list. From this linked list I want to write a dictionary file with new words. I don't know why my code don't run. Can anyone help me?
p/s: when i run debug it found this when store vector element to new_node->word
Error
This is my code
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
typedef struct dictionary
{ string word;
int line;
int page;
struct dictionary* next;
} node;
int main()
{
node* Head = NULL;
ifstream file("filetest.txt");
if(file.fail())
cout << "Loi mo file! "<<endl;
string temp;
int cpage = 1,cline = 1;
while(getline(file,temp))
{
stringstream spliter;
spliter << temp;
vector<string> result;
while(!spliter.eof())
{
string str;
spliter >> str;
result.push_back(str);
}
for(size_t i = 0;i != result.size();i++)
{
if(Find(Head,result[i])==0)
{
Append(&Head,result[i],cline,cpage);
}
}
cline++;
if(cline == 25)
cpage++;
}
file.close();
;
ofstream outfile("test.txt");
node* p = Head;
while(p != NULL)
{
outfile << p->word <<","<<p->page<<"-"<<p->line<<endl;
p=p->next;
}
}
Append( add member to linked list)
void Append(node** First,string &newstr,int newl,int newp)
{
node* new_node = (node*)malloc(sizeof(node));
node* last = *First;
new_node->word=newstr;
new_node->line=newl;
new_node->page=newp;
new_node->next = 0;
if(*First == 0)
{
*First = new_node;
return;
}
while(last->next != 0)
{
last = last->next;
}
last->next = new_node;
return;
}
Find( check if a word is new or not)
int Find(node* head,string &tumoi)
{
node* current = head;
while(current != 0)
{
if(current->word == tumoi)
return 1;
current = current->next;
}
return 0;
}
You should not use malloc with C++ types. It does not properly initialize them.
Your node struct contains a std::string which needs to have its constructor called to be properly initialized.
When you do this
node* new_node = (node*)malloc(sizeof(node));
new_node->word=newstr;
The new_node->word is not initialized and can contain pointers to nowhere.
You should do
node* new_node = new node();
new_node->word=newstr;
instead.

Segmentation violation signal in unidirectional list

I'm trying to make a unidirectional list with nodes containing a value and a pointer to the next node (the pointer in the final node is supposed to be a nullptr).
Howerver, things are not going as planed. It's compiling without any problems, but when I try to run it i get this fatal error condition:
SIGSEGV - Segmentation violation signal.
It think it's trying to reach memory which it doesn't have permission to use, or something? Another common cause is an accidental "=" instead of "==", but that doesn't seem to be the problem here.
It seems that the error occurs when I try to construct a Sorted_List without any nodes in my test file, like this:
Sorted_List empty_list{};
Here is the code I imagine can be relevant to the error:
Sorted_List.cc
#include "Sorted_list.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
Sorted_List::Sorted_List() : head{nullptr} {}
Sorted_List::Sorted_List(initializer_list<int> i)
:Sorted_List()
{
for (auto ii : i)
{
add_val(ii);
}
}
Sorted_List::~Sorted_List()
{
if (!check_empty())
{
Node* del = head;
while(del != nullptr)
{
Node* next = del->next;
delete del;
del = next;
}
}
}
bool Sorted_List::check_empty() const
{
return (head->value == 0 && head->next == nullptr);
}
void Sorted_List::del_val(int num)
{
Node* del = head;
if (num == 1)
{
head = del->next;
delete del;
}
for (int i = 1; i < num - 1; i++)
{
del = del->next;
}
}
void Sorted_List::add_val(int num)
{
Node* temp = new Node;
temp->value = num;
if (head == nullptr || head->value >= temp->value)
{
temp->next = head;
head = temp;
}
else
{
Node* current = head;
while(current->next != nullptr && current->next->value <temp->value)
{
current = current->next;
}
temp->next = current->next;
current->next = temp;
}
}
string Sorted_List::print( Sorted_List& list)
{
Sorted_List::Node* temp;
stringstream list_stream;
for(temp = list.head; temp != nullptr; temp = temp->next)
{
list_stream << temp->value;
if(temp->next != nullptr)
list_stream << ", ";
}
return list_stream.str();
}
Sorted_List.h
#ifndef SORTED_LIST_H
#define SORTED_LIST_H
#include <string>
#include <iostream>
#include <initializer_list>
#include <string>
class Sorted_List
{
private:
class Node
{
public:
int value{};
Node* next{};
};
Node* head{};
public:
Sorted_List();
Sorted_List(std::initializer_list<int>);
~Sorted_List();
std::string print(Sorted_List&);
void add_val(int num);
bool check_empty() const;
void del_val(int num);
};
#endif
Sorted_List_test.cc
#define CATCH_CONFIG_MAIN
#include "Sorted_list.h"
#include "catch.hpp"
#include <iostream>
#include <string>
using namespace std;
TEST_CASE(" EMPTY ")
{
Sorted_List empty_list{}; // this is where the error occurs
//REQUIRE(empty_list.check_empty() == true);
//REQUIRE(empty_list.print(empty_list) == "");
}
Any clues?
If you use a debugger you will see that the crash happens when the empty_list object is destructed. More precisely in the check_empty function called from the destructor.
This is because the default constructor sets head to a null pointer, and then in the check_empty you dereference this null pointer.
Your check_empty function should check if head is a null pointer.

AVL Tree Sentinel

I am trying to finish a school project with AVL trees. What happens is that once I insert the root as well as two other nodes everything is ok, the program fails if I try adding any more than those three nodes. I figured that the problem was the newnode's pointers were not pointing to the sentinel NIL once they were created; I tried setting the newnode's pointers pointing to NIL, but no luck.
How can I fix this?
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include <stdio.h>
#include "graphvisualize.h"
using namespace std;
typedef struct node Tnode;
Tnode *root;
Tnode *NIL;
Tnode *newnode;
void InitializeTree(int k) {
//initialize the list with the root node
NIL=(Tnode *)malloc(sizeof(Tnode));
root=(Tnode *)malloc(sizeof(Tnode));
//change to null later
root->value = k;
root->parent = NIL;
root->right = NIL;
root->left = NIL;
root->height = 1;
NIL->right = NULL;
NIL->left = NULL;
NIL->parent = NULL;
}
void insert(int v) {
Tnode *newnode=(Tnode *)malloc(sizeof(Tnode));
newnode->value = v;
Tnode *y = NIL;
Tnode *x = root;
while(x != NIL) {
y = x;
if(newnode->value < x->value) {
x = x->left;
} else {
x = x->right;
}
newnode->parent = y;
if(y == NIL) {
root = newnode;
} else if(newnode->value < y->value) {
y->left = newnode;
} else {
y->right = newnode;
}
cout << "insert ";
//Heres my problem
//trying to set right and left pointer to NIL
newnode->left = NIL;
newnode->right = NIL;
}
//height manager
int h = 1;
newnode->height = h;
while((newnode->parent != NIL) && (newnode->height >= newnode->parent->height)) {
newnode = newnode->parent;
newnode->height++;
}
cout << "height-fix ";
}
//Display AVL Tree
void ViewTree() {
ofstream AVLfile;
AVLfile.open("AVLgraphfile.dot");
AVLfile << visualize_tree(root);
AVLfile.close();
}
int main() {
InitializeTree(7);
cout << "root ";
insert(5);
insert(8);
//insert(6);
ViewTree();
return 0;
}

Binary Search Tree not working properly? (parse errors)

I'm getting parse errors in my code. I'm probably missing something silly.. but after staring at it, I can't figure out what's wrong. The errors start at line 26:
BinaryTree.cpp:26: parse error before 'new
BinaryTree.cpp:31: parse error before ';'
....etc etc... any ideas?
#include <cstdlib>
#include <iostream>
using namespace std;
class BinaryTree{
struct node{
int data;
node *left;
node *right;
};
node *root;
public:
BinaryTree(int);
void addNode(int);
void inorder();
void printInorder(node);
int getHeight();
int height(node);
};
BinaryTree::BinaryTree(int data){
node *new = new node;
new->data = data;
new->left = NULL;
new->right = NULL;
root = new;
}
void BinaryTree::addNode(int data){
node *new = new node;
new->data = data;
new->left = NULL;
new->right = NULL;
node *current;
node *parent = NULL;
current = root;
while(current){
parent = current;
if(new->data > current->data) current = current->right;
else current = current->left;
}
if(new->data < parent->data) parent->left = new;
else parent->right = new;
}
void BinaryTree::inorder()
printInorder(root);
}
void BinaryTree::printInorder(node current){
if(current != NULL){
if(tree->left) printInorder(tree->left);
cout<<" "<<tree->data<<" ";
if(tree->right) printInorder(tree->right);
}
else return;
}
int BinaryTree::getHeight(){
return height(root);
}
int BinaryTree::height(node new){
if (new == NULL) return 0;
else return max(height(new->left), height(new->right)) + 1;
}
int main(int argCount, char *argVal[]){
int number = atoi(argVal[1]);
BinaryTree myTree = new BinaryTree(number);
for(int i=2; i <= argCount; i++){
number = atoi(argVal[i]);
myTree.addNode(number);
}
myTree.inorder();
int height = myTree.getHeight();
cout << endl << "height = " << height << endl;
return 0;
}
new is a C++ keyword. You mustn't use it as an identifier (e.g. variable name).
In any event, your constructor would be better off as:
BinaryTree::BinaryTree(int data) : root(new node) { /* ... */ }
And your class as a whole would probably be better off with unique_ptr<Node>s.
new is keyword in c++ and You can't name variable with that word so
node *new = new node;
is illegal
new is a reserved word, you cannot use it as a variable name.

insert on first BST giving end of no-void function errror?

So I am attempting to learn how to code my first BST, and it is hard.... I am already having trouble with just a few lines of codes. the problem is in the insert, but I have included everything so that I could get some feedback on my style/other errors. I was suggested to use a pointer to pointer implementation, but we havent learned it yet, so I dont feel comfort/know how to code it yet. the
error is
cc1plus: warnings being treated as errors
tree.cpp: In member function âbool Tree::insert(Tree::Node*&, int, std::string)â:
tree.cpp:34: warning: control reaches end of non-void function
the tree.h file
#ifndef TREE_H
#define TREE_H
#include <iostream>
#include <string>
using namespace std;
class Tree
{
public:
Tree();
bool insert(int k, string s);
private:
struct Node
{
int key;
string data;
Node* left;
Node* right;
};
Node* root;
bool insert(Node*& root, int k, string s);
};
#endif
tree.cpp
#include <iostream>
#include "tree.h"
#include <stack>
#include <queue>
#include <string>
using namespace std;
Tree::Tree()
{
root = NULL;
}
bool Tree::insert(int k, string s)
{
return insert(root, k, s);
}
bool Tree::insert(Node*& currentRoot, int k, string s)
{
if(currentRoot == NULL){
currentRoot = new Node;
currentRoot->key = k;
currentRoot->data = s;
currentRoot->left = NULL;
currentRoot->right = NULL;
return true;
}
else if (currentRoot->key == k)
return false;
else if (currentRoot->key > k)
insert(currentRoot->left, k, s);
else
insert (currentRoot->right,k, s);
}
movieList.cpp
#include <iostream>
#include <stack>
#include <queue>
#include <string>
#include "tree.h"
using namespace std;
int main()
{
Tree test;
test.insert(100, "blah");
return 0;
}
cc1plus: warnings being treated as errors
tree.cpp: In member function âbool Tree::insert(Tree::Node*&, int, std::string)â:
tree.cpp:34: warning: control reaches end of non-void function
This just says that you don't return something on every possible path. Try this:
bool Tree::insert(Node*& currentRoot, int k, string s)
{
if(currentRoot == NULL){
currentRoot = new Node;
currentRoot->key = k;
currentRoot->data = s;
currentRoot->left = NULL;
currentRoot->right = NULL;
return true;
}
else if (currentRoot->key == k)
return false;
else if (currentRoot->key > k)
return insert(currentRoot->left, k, s);
// ^^^^^^
else
return insert (currentRoot->right,k, s);
// ^^^^^^
}
How about:
bool Tree::insert(Node*& currentRoot, int k, string s)
{
if(currentRoot == NULL){
currentRoot = new Node;
currentRoot->key = k;
currentRoot->data = s;
currentRoot->left = NULL;
currentRoot->right = NULL;
return true;
}
else if (currentRoot->key == k)
return false;
else if (currentRoot->key > k)
insert(currentRoot->left, k, s);
else
insert (currentRoot->right,k, s);
return true;
}
All branches need to return a value (boolean in this case).