Take a look at the code, what am I doing wrong in the operator overloading while adding polynomials (lists)? It's not printing the desired answer.
e.g.
P1: 5x^12 + 2x^9 + 4x^7 + 6x^6 + 1x^3
P2: 7x^8 + 2x^7 + 8x^6 + 6x^4 + 2x^2 + 3^x + 40
Answer: 5x^12 + 2x^9 + 7x^8 + 6x^7 + 14x^6 + 6x^4 + 1x^3 + 2x^2 + 3^x + 40
What is the correct way to add them?
#include <stdio.h>
#include <iostream>
using namespace std;
//Node is defined
class node {
public:
//value will contain data
int value1;
int value2;
//next stores location
node *next;
//Default Constructor
node()
{
value1 = 0;
value2 = 0;
next = NULL;
}
};
//mylist is defined
class mylist {
public:
//head will keep notice of beginning of the list
node* head;
//track number of nodes
int count = 0;
//default constructor
mylist() {}
//constructor
//insert at beginning
void insert_at_beginning(int new_value1, int new_value2)
{
//creating new node
node *new_node = new node();
//increasing count
count++;
//copying value to new_node
new_node->value1 = new_value1;
new_node->value2 = new_value2;
//pointing head to new_node when we have empty list
if (head == NULL)
{
head = new_node;
}
//when list isn't empty
else
{
/* new_node->next points where heads points*/
new_node->next = head;
/* Updating head node to point to newly added node*/
head = new_node;
}
}
//inert node or item at Specific Location
void insert_at_loc(int location, double new_val1, double new_val2)
{
//temp node to keep track of location
node* temp = head;
//x acts as counter
int x = count;
//check if location is valid or not
if (count < location) {
cout << ("\n --Invalid Location Node Can't be Added at this Location -- ") << endl;
}
else {
//traversing thourgh list finding specific location to add node
while (x != NULL) {
if (x == (count - location + 2)) {
//found location now creating new node and fixing links
node *new_node1 = new node();
//increasing count
count++;
new_node1->value1 = new_val1;
new_node1->value2 = new_val2;
//new_node1->next points to temp->next
new_node1->next = temp->next;
//temp-next points to newly added new_node1
temp->next = new_node1;
}
else {
temp = temp->next;
}
x--;
}
}
}
//printing list
void printList()
{
cout << endl << "Linked-List : ";
node* temp = head;
while (temp != NULL) {
cout << temp->value2 << "x^" << temp->value1 << "--> ";
temp = temp->next;
}
}
void del(int del_loc) {
//temp1 to keep track location
node* t1 = head;
//if location is head
if (del_loc <= 1) {
head = t1->next;
//free memory
delete(t1);
//decrementing count
count--;
}
//location is other than head
else if (del_loc < count) {
for (int y = count; y != (count - del_loc + 2); y--) {
t1 = t1->next;
}
//fixing links
node* t2 = t1->next;
t1->next = t2->next;
//free memory
delete t2;
//decrementing count
count--;
}
else {
cout << "\n **Sorry Location Doesn't Exist **" << endl;
}
}
//Display Number of Nodes
void count_func() {
cout << "\n\n No. of Nodes Present in Linked List : " << count << endl;
}
void mylist::operator+=(const mylist& l2) {
node *temp_l1 = head;
node *temp_l2 = l2.head;
mylist answer;
while ((temp_l1 != NULL) && (temp_l2 != NULL)) {
if (temp_l1 != NULL && temp_l2 == NULL) {
answer.insert_at_beginning(temp_l1->value1, temp_l1->value2);
temp_l1 = temp_l1->next;
}
if (temp_l1 == NULL && temp_l2 != NULL) {
answer.insert_at_beginning(temp_l2->value1, temp_l2->value2);
temp_l2 = temp_l2->next;
}
if (temp_l1 != NULL && temp_l2 != NULL) {
if (temp_l1->value1 == temp_l2->value1) {
answer.insert_at_beginning(temp_l1->value1, (temp_l1->value2+temp_l2->value2) );
if (temp_l1 != NULL)
temp_l1 = temp_l1->next;
if (temp_l2 != NULL)
temp_l2 = temp_l2->next;
}
else if (temp_l1->value1 > temp_l2->value1 ) {
answer.insert_at_beginning(temp_l1->value1, temp_l1->value2);
temp_l1 = temp_l1->next;
}
else if (temp_l1->value1 < temp_l2->value1) {
answer.insert_at_beginning(temp_l2->value1, temp_l2->value2);
temp_l2 = temp_l2->next;
}
}
}
node *temp_ans = answer.head;
while (temp_ans != NULL) {
cout << temp_ans->value2 << "z^" << temp_ans->value1 << "--> ";
temp_ans = temp_ans->next;
}
}
};
int main() {
//creating linked_list
mylist linked_list;
mylist linked_list_1;
mylist linked_list_2;
mylist linked_list_ans;
int menu = 0;
int list_1_exp = 0;
int list_1_exp_check = -100;
double list_1_coef;
char list_1_menu = 0;
cout << " *********************** Enter 1st Polynomial in Ascending Order w.r.t Exponential *********************** " << endl;
while (list_1_menu != 'E' || list_1_menu != 'e') {
cout << " \nWould you like to add term in 1st Polynomial (y or n): " << endl;
cout << " Enter 'E' to exit: " << endl;
cout << " Your Choice: ";
cin >> list_1_menu;
if (list_1_menu == 'Y' || list_1_menu == 'y') {
cout << "Enter the Exponent for the term : ";
cin >> list_1_exp;
if (list_1_exp > list_1_exp_check || list_1_exp_check == -100) {
list_1_exp_check = list_1_exp;
}
else if (list_1_exp <= list_1_exp_check) {
cout << " Invalid Exponent for the term (can't be Equal or Less than Last Term) " << endl;
cout << " Please Enter Exponent Greater than " << list_1_exp_check << endl;
cout << " Enter the Exponent for the term : ";
cin >> list_1_exp;
list_1_exp_check = list_1_exp;
}
cout << "Enter the Coefficent for the term : ";
cin >> list_1_coef;
linked_list_1.insert_at_beginning(list_1_exp, list_1_coef);
linked_list_1.printList();
cout << " NULL" << endl << endl;
}
else if (list_1_menu == 'N' || list_1_menu == 'n') {
break;
}
else if (list_1_menu == 'E' || list_1_menu == 'e') {
break;
}
}
//priting list
linked_list_1.printList();
cout << " NULL" << endl << endl;
int list_2_exp = 0;
int list_2_exp_check = -100;
double list_2_coef;
char list_2_menu = 0;
cout << " \n *********************** Enter 2nd Polynomial in Ascending Order w.r.t Exponential ***********************" << endl;
while (list_2_menu != 'E' || list_2_menu != 'e') {
cout << " \nWould you like to add term in 2nd Polynomial (y or n): " << endl;
cout << " Enter 'E' to exit: " << endl;
cout << " Your Choice: ";
cin >> list_2_menu;
if (list_2_menu == 'Y' || list_2_menu == 'y') {
cout << "Enter the Exponent for the term : ";
cin >> list_2_exp;
if (list_2_exp > list_2_exp_check || list_2_exp_check == -100) {
list_2_exp_check = list_2_exp;
}
else if (list_2_exp <= list_1_exp_check) {
cout << " Invalid Exponent for the term (can't be Equal or Less than Last Term) " << endl;
cout << " Please Enter Exponent Greater than " << list_2_exp_check << endl;
cout << " Enter the Exponent for the term : ";
cin >> list_2_exp;
list_2_exp_check = list_2_exp;
}
cout << "Enter the Coefficent for the term : ";
cin >> list_2_coef;
linked_list_2.insert_at_beginning(list_2_exp, list_2_coef);
linked_list_2.printList();
cout << " NULL" << endl << endl;
}
else if (list_2_menu == 'N' || list_2_menu == 'n') {
break;
}
else if (list_2_menu == 'E' || list_2_menu == 'e') {
break;
}
}
//priting list
linked_list_2.printList();
cout << " NULL" << endl << endl;
linked_list_1.printList();
cout << " NULL" << endl << endl;
cout << " Addition " << endl;
linked_list_1 += (linked_list_2);
cout << "\nFinal List" << endl;
linked_list_ans.printList();
//program success
system("pause");
return 0;
}
I think that logic I'm trying for addition makes sense but it's not working. In the majority of cases it works as in if I have equal terms in the polynomial with the same degrees. It works fine for that but not for all cases. Please help!
Why not keep it simple instead:
Create a map<int, int>. Traverse through P1 and P2, insert indices as key and put coefficient as value. Increment the value of entry if the index or power already exist in the map, else create new entry with the index as key. After finishing the traversal of both P1 and P2, the map will compose of entries with index as key and sum of coefficients for each power/index in P1 and P2 as corresponding value.
The loop condition (temp_l1 != NULL) && (temp_l2 != NULL)guarantees that temp_l1 != NULL && temp_l2 == NULL and temp_l1 == NULL && temp_l2 != NULL are always false, so the bodies of corresponding ifs are never executed. Take them out of the loop (and convert them to loops of course).
PS: to quickly find problems like this, use a debugger.
Related
I will try to keep it as simple as possible.
Basically, I am working with graphs and writing Kruskal's Algorithm for a minimum spanning tree. I have made a class of forest, each forest node contains a link list whose head represents a vertice of the graph, and ahead connected nodes contain the vertices that the main head vertice is connected to, and the next forest node contains the next vertice of the graph, and the link list in that forest node contains the vertices that the specific vertice is connected to.
My code up until now is 400 lines. I will share a snippet that contains the problem:
#include <iostream>
using namespace std;
class node
{
public:
int data;
node* right;
node()
{
data = 0;
right = NULL;
}
~node()
{
cout << data << " node has been destroyed " << endl;
}
};
class forest
{
public:
node* vertices;
int weight;
forest* next;
forest()
{
vertices = NULL;
weight = 0;
next = NULL;
}
~forest()
{
cout << vertices->data << " vertice has been destroyed " << endl;
}
};
class que
{
public:
int root;
int connected;
int weight;
int set_no; // for checking of disjoint sets
que* next;
que()
{
root = 0;
connected = 0;
weight = 0;
set_no = 0;
next = NULL;
}
~que()
{
cout << "edge with root " << root << " connected to " << connected << " has been dequed " << endl;
}
};
que* priority_dq(que*& front)
{
que* move = front;
que* link = front;
que* required = new que;
required = move;
while (move->next != NULL)
{
if (required->weight > move->next->weight)
{
link = move;
required = move->next;
}
move = move->next;
}
if (link == front)
{
front = front->next;
link->next = NULL;
}
else
{
link->next = required->next;
}
return required;
}
void make_spanning_tree(forest*& root, que*& front, int count)
{
que* use;
forest* sets = new forest; // we using forest here bcz the data structure of its members is according to the dynamically changing disjoint set structure we need
int set_no = 1; // each forest node 's vertices will contain 1 set's members
node* move = new node;
forest* iterate;
//forest* start ;
for (int i = 0; i < count; i++)
{
iterate = sets;
use = priority_dq(front);
if (iterate->vertices->data == 0)
{
iterate->vertices->data = use->root;
node* add = new node;
add->data = use->connected;
iterate->vertices->right = add;
}
else
{
int* r_count = new int[set_no], * c_count = new int[set_no];
int new_r = 1, new_c = 1;
for (int j = 0; j < set_no; j++)
{
r_count[j] = 0;
c_count[j] = 0;
move = iterate->vertices;
while (move != NULL)
{
if (use->root == move->data)
{
r_count[j] = 1;
new_r = 0;
}
if (use->connected == move->data)
{
c_count[j] = 1;
new_c = 0;
}
move = move->right;
}
iterate = iterate->next;
}
}
}
iterate = sets;
while (iterate != NULL)
{
move = iterate->vertices;
while (move != NULL)
{
cout << move->data << " ";
move = move->right;
}
cout << endl;
iterate = iterate->next;
}
}
int main()
{
forest* root = new forest;
forest* temp = root;
int a;
cout << "enter the vertices for the graph and enter -1 to stop" << endl;
cin >> a;
while (a != -1)
{
temp = root;
if (temp->vertices == NULL)
{
node* join = new node;
join->data = a;
temp->vertices = join;
}
else
{
while (temp->next != NULL)
{
temp = temp->next;
}
node* join = new node;
join->data = a;
forest* add = new forest;
add->vertices = join;
temp->next = add;
}
cin >> a;
}
que* front = new que;
int count = 1, from, to;
cout << "Now enter the edges(atleast 3) present in the graph and their respective weights.To stop enter -1 " << endl;
cout << "what is the root of edge no " << count << " ? ";
cin >> from;
while (from != -1)
{
forest* check;
check = root;
int is_vertice = 0;
while (check != NULL)
{
if (check->vertices->data == from)
{
is_vertice = 1;
}
check = check->next;
}
if (is_vertice == 0)
{
cout << "sorry vertice is not present in graph, try an exsisting one " << endl;
}
else
{
cout << "\nwhat is it connected to ? ";
cin >> to;
while (to != -1)
{
check = root;
is_vertice = 0;
while (check != NULL)
{
if (check->vertices->data == to)
{
is_vertice = 1;
}
check = check->next;
}
if (is_vertice == 0)
{
cout << "sorry vertice is not present in graph, try an exsisting one or enter -1 to stop" << endl;
cin >> to;
}
else
{
if (front->root == 0)
{
front->root = from;
front->connected = to;
cout << "enter the weight of this edge" << endl;
cin >> to;
front->weight = to;
count++;
break;
}
else
{
que* add = new que;
add->root = from;
add->connected = to;
cout << "enter the weight of this edge" << endl;
cin >> to;
add->weight = to;
add->next = front;
front = add;
count++;
break;
}
}
}
}
cout << "enter next vertice root for edge no " << count << " or enter -1 to stop " << endl;
cin >> from;
}
que* move = front;
cout << "EDGES: " << endl;
while (move != NULL)
{
cout << "from " << move->root << " to " << move->connected << " ,weight: " << move->weight << endl;
move = move->next;
}
move = priority_dq(front);
cout <<endl<< "minimum weight edge" << endl;
cout << endl << "from " << move->root << " to " << move->connected << " ,weight: " << move->weight << endl << endl;
move = front;
cout << endl << "que afterwards" << endl;
while (move != NULL)
{
cout << "from " << move->root << " to " << move->connected << " ,weight: " << move->weight << endl;
move = move->next;
}
cout << endl << "SETS:" << endl;
make_spanning_tree(root, front, count);
}
The main problem to focus on here is that in my make spanning tree function, the 1st for loop in the 1st if check, where I'm reading iterate->vertice->data, tells me iterate contains same null value as the below move did. So, this means my first iteration passed okay with the 1st if used, then in the 2nd loop iteration, my else part was used in which move pointed to null, and now in the third (most probably) it says iterate->vertices has the same value null as the move did. That doesn't make any sense, because I'm re-initializing iterate with sets, which is the root or head which can never be null because I didn't delete my main object, and I want my checks to be read again from the start every time.
I can't understand why it still points to the below null from the last iteration.
I ran your program and it throws exception in first iterate->vertices->data in make_spanning_tree, saying that iterate->vertices is nullptr.
You said you're re-initializing iterate with sets which is the root or head, but it seems that sets is new forest which has nullptr as vertices, not root.
so for my program, we are using singly linked list and i'm having trouble find records.
we have hard-coded two records with rating 5 for example. When we first start my program and search for them, both records show up, but when we enter a new record with a different rating then it says rating not found or address not found.
What is the problem in our code ?
p.s - btw this is a group assignment and my group mate did this, so i'm just trying to figure out how can i fix this...
struct tutor
{
int tutorid, rate;
string tutoraddress;
tutor* next;
};
class record
{
public:
//head as first in node
tutor* head;
tutor* tail;
//Get size of node
int getSize;
//Constructor to flush and renew the value of node to null, and size to 0
record()
{
this->head = NULL;
this->tail = NULL;
this->getSize = 0;
}
void exist()
{
tutor* n = new tutor;
//First
n->tutorid = 1;
n->tutoraddress = "Puchong";
n->rate = 5;
n->next = NULL;
if (head == NULL)
{
head = n;
}
else
{
tail = head;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = n;
}
getSize++;
}
void exist1()
{
tutor* n = new tutor;
//Second
n->tutorid = 2;
n->tutoraddress = "Puchong";
n->rate = 5;
n->next = NULL;
if (head == NULL)
{
head = n;
}
else
{
tail = head;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = n;
}
getSize++;
}
int find()
{
//create n node and assign to head
//then traverse to end of list to find the
//search value
int ch = 0;
int rating = 0;
int id = 0;
string address;
while (true)
{
cout << "\n1>Find ID\n";
cout << "2>Find rating\n";
cout << "3>Find address\n";
cout << "4>Quit\n";
cout << "Select menu: ";
cin >> ch;
if (ch == 1)
{
cout << "\nMenu selected: " << ch << "\n";
cout << "Enter ID: ";
cin >> id;
tutor* n = head;
while (n != NULL)
{
if (n->tutorid == id)
{
cout << "\nID: " << n->tutorid << "\n";
system("pause");
return true;
}
else
{
n = n->next;
}
}
cout << "\nID not found\n";
system("pause");
return false;
}
else if (ch == 2)
{
cout << "\nMenu selected: " << ch << "\n";
cout << "Enter rating: ";
cin >> rating;
tutor* n = head;
while (n != NULL)
{
if (n->rate == rating)
{
cout << "\nID: " << n->tutorid << "\n";
n = n->next;
}
else
{
n = n->next;
cout << "\nRate not found\n";
break;
}
}
}
else if (ch == 3)
{
cout << "\nMenu selected: " << ch << "\n";
cout << "Enter address: ";
cin >> address;
tutor* n = head;
while (n != NULL)
{
if (n->tutoraddress == address)
{
cout << "\nID: " << n->tutorid << "\n";
n = n->next;
}
else
{
n = n->next;
cout << "\nAddress not found\n";
break;
}
}
}
else
{
cout << "\nEnd\n";
system("pause");
break;
}
}
}
}
To answer your question about searching a linked list, here is an example function to search the list by tutoraddress:
tutor * record::find_by_tutor_address(const std::string& key)
{
tutor * p_node = head;
while (p_node != nullptr)
{
if (p_node->tutoraddress == key)
{
break;
}
p_node = p_node->next;
}
return p_node;
}
Searching by the other fields can use a similar function.
The fundamental process is to start at the head node and follow the links until the node is found. The function will return nullptr if the key is not found or it will return a pointer to the node that contains the key.
I am working on reading in a file. It is filled line by line with things such as the following:
e 2
b 1
a 3
h 5
c 4
If I were to sort these by the number I would get the word "beach". I need to do this but at a larger scale. I currently have two errors. There are lines I read in which have a space and a number [ " " 6 ] and my program will not append them/sort these into my linked list and therefore this is causing a segmentation error because my for loop for printing is meant to loop through all 53 words.
Is there any fix for as to why the spaces aren't showing up in my linked list? Also, about 44/53 of the words correctly find their places using my addInOrder function but yet there a few that don't, is there a reason for this?
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <stdio.h>
#include <ctype.h>
using namespace std;
struct ListNode
{
string letter;
string num;
ListNode *next;
};
void append(ListNode *&h, string l, string n);
void addInOrder(ListNode *&h, string l, string n);
void printList(ListNode *h, int &lengthOfFile);
void deleteNode(ListNode *&h, string l, string n);
void deleteList(ListNode *&h);
int main()
{
string letter;
string num;
string lines;
int lengthOfFile = 0;
const string FILENAME = "file link";
ifstream inFile(FILENAME);
/*if (inFile)
{
while (getline( inFile, lines ))
{
lengthOfFile++;
cout << "Hello...1" << endl;
}
}*/
ListNode *head = nullptr;
if (inFile)
{
string line;
for (int lineNum = 1; getline(inFile, line); lineNum++)
{
stringstream ss(line);
string word;
for (int wordNum = 1; ss >> word; wordNum++)
{
if (wordNum == 1)
{
char c = word[0];
if (isalpha(c))
{
cout << "letter: " << c << endl;
letter = c;
}
else if (word == "!" or word == ".")
{
cout << "letter: " << word << endl;
letter = word;
}
else if (word != "!" or word != ".")
{
cout << "letter: " << " " << endl;
cout << "number: " << word << endl;
letter = " ";
num = word;
lengthOfFile++;
}
}
if (wordNum == 2)
{
cout << "number: " << word;
num = word;
lengthOfFile++;
}
if (wordNum == 2)
{
cout << endl;
append(head, letter, num);
//cout << "letter: " << letter << " and num: " << num << endl;
cout << endl;
addInOrder(head, letter, num);
//cout << "letter: " << letter << " and num: " << num << endl;
cout << endl;
cout << endl;
cout << endl;
}
}
cout << endl;
}
inFile.close();
}
cout << "lengthOfFile++;: " << lengthOfFile << endl;
printList(head, lengthOfFile);
}
void append(ListNode *&h, string l, string n)
{
// create a new ListNode and set data and next
ListNode *newNode;
newNode = new ListNode;
newNode->letter = l;
//cout << "l: " << l << endl;
newNode->num = n;
//cout << "n: " << n << endl;
newNode->next = nullptr;
}
void addInOrder(ListNode *&h, string l, string n)
{
// create a new ListNode and set data
ListNode *newNode;
newNode = new ListNode;
newNode->letter = l;
//cout << "l: " << l << endl;
newNode->num = n;
//cout << "n: " << n << endl;
newNode->next = nullptr;
// if list is empty, assign head to new ListNode; otherwise,
// find where to add in (non-descending) order
if (h == nullptr)
{
h = newNode;
newNode->next = nullptr;
}
else
{
ListNode *prev = nullptr;
ListNode *curr = h;
// find location to add
while (curr != nullptr && curr->num < n)
{
prev = curr;
curr = curr->next;
}
// if prev is nullptr, then we're adding to the beginning
// of the list; else, adding to end or between two nodes
if (prev == nullptr)
{
h = newNode;
newNode->next = curr;
}
else
{
prev->next = newNode;
newNode->next = curr;
}
}
}
void printList(ListNode *h, int &lengthOfFile)
{
ListNode * ptr = h;
// loop through and print data
for(int i = 0; i < lengthOfFile; i++)
{
cout << ptr->letter << " ";
cout << ptr->num << " ";
cout << endl;
ptr = ptr->next;
}
}
1)
The problem is in the following line:
ss >> word
The operator >> is eating up whitespace and looking for a valid (non-whitespace) character.
To get a single character from the stream ss.get() should be used.
2) If you want to compare to a character literal, use single apostrophe '.
But then also remeber to extract a character from line.
I keep getting a segmentation fault when I attempt to add a hex number to the current hex number. Here is the line where I'm getting my segmentation fault(I think):
newHex->insertTail(sum);
Here is the whole program:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
using namespace std;
#undef NULL
const int NULL = 0;
const char SENTINEL = '#';
typedef int element;
class listnode {
public:
element data;
listnode * next;
};
class LList {
private:
listnode * head;
listnode * tail;
listnode * view;
public:
LList();
~LList();
void read();
listnode* next();
void print();
void insertTail(element val);
void clean();
//void add(LList operand);
//void multiply(LList operand);
element deleteHead();
};
class Calculator {
public:
Calculator();
LList* add(LList& left, LList& right);
//LList* multiply(LList& left, LList& right);
};
Calculator::Calculator() {
};
LList* Calculator::add(LList& left, LList& right) {
int sum, carry = 0, lval = 0, rval = 0;
bool calculating = true;
listnode *leftNode;
listnode *rightNode;
LList* newHex;
while(calculating) {
leftNode = left.next();
rightNode = right.next();
if(leftNode == NULL) {
lval = 0;
}
else
lval = leftNode->data;
if(rightNode == NULL) {
rval = 0;
}
else
rval = rightNode->data;
if(leftNode == NULL && rightNode == NULL) {
calculating = false;
if(carry != 0) {
newHex->insertTail(carry);
}
break;
}
sum = lval + rval + carry;
carry = 0;
if(sum >= 16) {
carry = 1;
sum -= 16;
}
cout << "Segmentation Fault Below :)" << endl;
newHex->insertTail(sum);
}
return newHex;
};
listnode* LList::next() {
listnode* temp = view;
if(temp != NULL)
view = view->next;
if(view == NULL) {
}
return temp;
};
LList::LList(){
head = NULL;
view = NULL;
};
void LList::print() {
listnode * temp;
int i = 0;
string printValues;
temp = head;
while(temp != NULL) {
int var = temp -> data;
char character = ' ';
if(i % 3 == 0 && i != 0)
printValues += ',';
i++;
if(var > 9 && var < 16)
{
character = static_cast <char>(var + 65 - 10);
}else if (var <= 9 && var >= 0)
character = static_cast <char>(var + 48);
printValues += character;
temp = temp -> next;
}
string tempValues;
for(int i = printValues.length() - 1; i >= 0; i--)
tempValues += printValues[i];
cout << tempValues;
cout << endl;
};
void LList::read() {
string userval;
int i;
bool parsing = true;
char curval;
vector <int> values;
clean();
while(parsing) {
cin >> userval;
for(unsigned int i = 0; i < userval.length(); i++) {
curval = userval[i]; //this is your character
if(curval >= 48 && curval <= 57)
values.push_back(static_cast <int>(curval -
48));
if(curval >= 65 && curval <= 70)
values.push_back(static_cast <int>(curval -
65 + 10));
if(curval == ' ')
break;
if(curval == SENTINEL) {
parsing = false;
break;
}
}
}
for(int i = values.size() -1; i >= 0; i--) {
insertTail(values[i]);
}
};
void LList::insertTail(element val) {
listnode * temp;
temp = new listnode;
temp -> data = val;
temp -> next = NULL;
if(head == NULL) {
head = temp;
view = head;
}
else
tail -> next = temp;
tail = temp;
};
void LList::clean() {
while(head != NULL)
deleteHead();
};
void validCommands() {
cout << "Valid commands are:" << endl;
cout << " e enter enter the current ";
cout << "hexadecimal ";
cout << "number from the keyboard" << endl;
cout << " a add add a new hexadecimal ";
cout << "number to the current hex. number" << endl;
cout << " m multiply ";
cout << "multiply a new hexadecimal number ";
cout << "by the current hex. number" << endl;
cout << " h help show this help menu" << endl;
cout << " q quit quit the program" << endl << endl;
};
/*
void LList::multiply(LList operand) {
int left, right, product, carry;
listnode* operandNext = operand.next();
listnode* currentNode = this->head;
while(operandNext != NULL) {
left = operandNext->data;
right = currentNode->data;
product = left * right;
carry = 0;
if(product >= 16) {
product -= 16;
carry = 1;
}
if(currentNode == NULL) {
this->insertTail(left);
}
currentNode->data = product;
currentNode = currentNode->next;
operandNext = operandNext->next;
}
};
*/
element LList::deleteHead() {
listnode * temp;
temp = head;
head = head -> next;
delete temp;
return temp -> data;
};
LList::~LList(){
delete head;
};
int main() {
LList L, add,multiply;
Calculator calc;
L.insertTail(0);
char option;
bool run;
cout << "Hexadecimal Calculator, Ver 1.0.0 \n";
cout << endl;
do {
cout << "Current Hexadecimal number is: ";
L.print();
cout << endl;
cout << "Command (h for help): ";
cin >> option;
cout << endl << endl;
switch(option) {
case 'e' :
cout << "Enter a hexadecimal number ";
cout << "followed by #: ";
L.read();
cout << endl << "Entering completed.";
cout << endl << endl;
break;
case 'a' :
cout << "Adding a new hexadecimal number ";
cout << "to the current hex. number" << endl;
cout << endl;
cout << "Enter a hexadecimal ";
cout << "number, follow by #: ";
add.read();
cout << endl << "Addition completed.";
cout << endl;
L = *calc.add(L, add);
cout << endl;
break;
case 'm' :
cout << "Multiplying a new hexadecimal ";
cout << "number ";
cout << "to the current hex. number" << endl;
cout << endl;
cout << "Enter a hexadecimal ";
cout << "number, follow by #: ";
//multiply.read();
cout << endl << "Multiplication completed.";
cout << endl;
//L.multiply(multiply);
cout << endl;
break;
case 'h' : validCommands();
break;
case 'q' : run = false;
break;
};
} while (run);
exit(0);
}
If I'm not wrong, the problem is newHex, in Calculator::add()
You define a pointer to a LList
LList* newHex;
and you use it
newHex->insertTail(carry);
[...]
newHex->insertTail(sum);
without allocate it.
this is a code for a dictionary.
each node has 26 pointers and so on.
this code works for around 270 word insertions in linux g++ compiler
but shows segmentation fault even on g++ in mac and fedora, and shows some exception handling error in visual studio 2010.
if more than 275 word are inserted automatically, it shows segmentation fault(ubuntu).
i am not worried about the efficiency of the prog. and that txt file used, contains a list of english words each in a single line.
i just need it to work. thanks in advance..
#define alphabets 26
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <string.h>
using namespace std;
class dictionary
{
//// letter node ////
struct node
{
char letter;
char * meaning;
bool completion;
struct node * pointer[alphabets];
}* root, * temp;
public:
char * word;
int length;
int letterPos;
int pointerId;
bool searchFound;
bool inserted;
//// constructor ////
dictionary()
{
root = new struct node;
root -> letter = '0';
root -> meaning = new char[9];
strcpy(root -> meaning, "rootNode");
root -> completion = 0;
}
//// called from localfunction ////
int insertWord(struct node *& currentNode)
{
if(currentNode == NULL && letterPos < length)
{
//cout << "creating new node" << endl;
//cout << "in insert function" << " " << word[letterPos] << endl;
temp = new struct node;
temp -> letter = word[letterPos];
currentNode = temp;
temp -> meaning = NULL;
//cout << "node address: " << currentNode << endl;
if(letterPos == length - 1)
{
temp -> completion = 1;
inserted = 1;
//cout << "inserted" << endl;
return 0;
}
else
temp -> completion = 0;
letterPos++;
pointerId = word[letterPos] - 'a';
insertWord(currentNode -> pointer[pointerId]);
}
else{
/*if(letterPos == length - 1)
{
cout << "word inserted" << endl;
currentNode -> completion = 1;
return 0;
}*/
//else
{
letterPos++;
pointerId = word[letterPos] - 'a';
insertWord(currentNode -> pointer[pointerId]);
}
}
if(letterPos == length)
{
//cout << "node letter: " << currentNode -> letter << endl;
currentNode -> completion = 1;
//cout << "inseted" << endl;
inserted = 1;
return 0;
}
/*if(currentNode -> letter == word[letterPos])
if(letterPos == length - 1)
{
cout << "in if condition completion" << endl;
currentNode -> completion = 1;
}
*/
//pointerId = word[letterPos] - 'a';
}
//// called from main ////
int insertIntoDictionary(char * wordNew)
{
length = strlen(wordNew);
word = wordNew;
letterPos = 0;
inserted = 0;
pointerId = word[letterPos] - 'a';
//insertWord(root);
//cout << "Root: " << root << endl;
insertWord(root -> pointer[pointerId]);
}
//// called from localfunction ////
int search(struct node * currentNode)
{
//cout << "in search function" << " searching " << word[letterPos] << endl;
if(currentNode == NULL)
{
//cout << "end of search" << endl;
return 0;
}
/*if(currentNode == root)
{
cout << "search function in root " << endl;
pointerId = word[letterPos] - 'a';
search(currentNode -> pointer[pointerId]);
return 0;
}*/
if(word[letterPos] == '\0' && !currentNode -> completion)
{
searchFound = 0;
return 0;
}
if(currentNode -> letter == word[letterPos] && word[letterPos] != '\0')
{
//cout << "in if condition" << endl;
if(letterPos == length - 1)
{
if(currentNode -> completion)
searchFound = 1;
return 0;
}
letterPos++;
pointerId = word[letterPos] - 'a';
//letterPos++;
search(currentNode -> pointer[pointerId]);
/*if(letterPos == length)
{
//cout << "word found" << endl;
searchFound = 1;
return 0;
}*/
}
/*else
{
pointerId = word[letterPos] - 'a';
//letterPos++;
search(currentNode -> pointer[pointerId]);
}
*/
}
//// called from main ////
int searchInDictionary(char * wordFind)
{
word = wordFind;
length = strlen(wordFind);
letterPos = 0;
searchFound = 0;
pointerId = word[letterPos] - 'a';
search(root -> pointer[pointerId]);
//if(searchFound)
//cout << "Word found" << endl;
}
int display1(struct node * currentNode)
{
int i;
if(currentNode != NULL)
{
//cout << "node letter1: " << currentNode -> letter << endl;
for(i = 0; i < alphabets; i++)
display1(currentNode -> pointer[i]);
}
}
/*int display()
{
cout << "display function" << endl;
//letterPos = 0;
//pointerId = word[letterPos] - 'a';
//cout << root ->
//display1(root -> pointer[pointerId]);
cout << "root: " << root << endl;
pointerId = word[letterPos] - 'a';
cout << root -> pointer[0] << endl; //-> letter;
display1(root);
}*/
};
int autoInsert(dictionary &english)
{
int count = 0;
//dictionary english;
FILE * file = fopen("words2.txt", "r");
char * line;
char ch;
/*while(fgets(line, sizeof line, file) != NULL)
{
cout << "Inserting: " << line << endl;
english.insertIntoDictionary(line);
}*/
line = new char[25];
const char * ptr = &ch;
while( count < 274 && ( ch = fgetc(file) ) != EOF )
{
if(ch != '\n')
strcat(line, ptr);
else
{
count++;
cout << "Inserting: " << line << endl;
english.insertIntoDictionary(line);
delete [] line;
line = new char[25];
}
}
return 0;
}
int main()
{
/*dictionary english;
char * word = "apple";
cout << "insert command" << endl;
english.insertIntoDictionary(word);
cout << "search command" << endl;
english.searchInDictionary(word);
*/
system("clear");
dictionary english;
int ch;
char w[100];
start:
cout << "1. insert word\n2. search\n3. auto insert\n4. exit " << endl;
cout << "Enter choice: ";
cin >> ch;
if(ch > 3)
return 0;
if(ch != 3)
{
cout << "word: ";
cin >> w;
}
switch(ch)
{
case 1: english.searchInDictionary(w);
if(english.searchFound)
{
cout << "word already exists" << endl;
break;
}
english.insertIntoDictionary(w);
if(english.inserted)
cout << "word inserted" << endl;
break;
case 2: english.searchInDictionary(w);
if(english.searchFound)
cout << "Word found" << endl;
else
cout << "Word not found" << endl;
break;
case 3: autoInsert(english);
break;
default: return 0;
}
goto start;
return 0;
}
here is the complete code:
http://www.heypasteit.com/clip/10XL
and the txt file link:
http://www.heypasteit.com/clip/10XN
This is happening may be because the pointer[alphabets] is not getting initialized when creating a new node.
Try this definition for struct node
//// letter node ////
struct node
{
char letter;
char * meaning;
bool completion;
struct node * pointer[alphabets];
node()
{
for(int i =0; i<alphabets;i++)
{
pointer[i]=NULL;
}
}
}* root, * temp;
this is the altered code for the function autoInsert();
int autoInsert(dictionary &english)
{
int count = 0;
fstream file("123.txt",ios::in);
char * line = NULL;
char ch;
line = new char[25];
line[0] = '\0';
ch='\0';
char * ptr = &ch;
while( count < 1510 && file.getline(line,25,'\n'))
{
{
count++;
cout << "Inserting: " << line << endl;
english.insertIntoDictionary(line);
}
}
file.close();
return 0;
}
this works perfectly on code blocks but shows unhandled exception, memory access violation.