I'm practicing linked list today, trying my best to understand it, so I tried making one singly linked list where I can add at the beginning,middle,and end, it also initializes to add one if the list is empty then printing the result.
I already use functions for this insertion and display of inputs or outputs but still the outputs result to nothing, event the printing the list, i tried to change the position of
node* head = NULL;
and still nothing happens
void insert(node* head, int numb, int size, int pos)
{
node* temp = new node();
int counter;
temp->number = numb;
if (head == NULL) {
head = temp;
}
else {
int counter = 0;
node* current = head;
node* trail = NULL;
while (counter++) {
if (counter == pos) {
temp->next = current;
trail->next = temp;
break;
}
else {
trail = current;
current = current->next;
continue;
}
}
}
size++;
}
void printlist(node* head)
{
while (head != NULL) {
cout << " " << head->number;
head = head->next;
}
}
int main()
{
node* head = NULL;
int numb, size = 0, pos;
numb = 5;
pos = 0;
insert(head, numb, size, pos);
printlist(head);
numb = 6;
pos = 2;
insert(head, numb, size, pos);
printlist(head);
}
I expect the output for the first is 5 then the second is 5 6.
The pointer you pass in insert(node* head is just a copy of the pointer in main. Any modifications to this pointer (e.g. head = temp) will not be reflected in main.
You need to pass either a pointer to the pointer or a reference to the pointer, for example:
void insert(node*& head, int numb, int size, int pos)
The function is invalid and in general has undefined behavior. For example this statement in the function
size++;
does not make sense because the parameter size does not have a referenced type. That is the function deals with a copy of its argument. The object size passed as an argument to the function will stay unchanged. And as a result the variable size within main will be always equal to 0.
Or within the loop
node* trail = NULL;
while (counter++) {
if (counter == pos) {
temp->next = current;
trail->next = temp;
//...
for the position equal to 1 the node trail is equal to NULL so this statement
trail->next = temp;
has undefined behavior.
Also the head node in main is not changed by the function because it is passed to the function by value. That is again the function deals with a copy of the head node.
And it is a bad idea to define the variables size and pos as having a signed integer type. In this case you have to check within the function whether the value of the parameter pos is greater than or equal to 0.
The function can be defined as it is shown in the demonstrative program below.
#include <iostream>
struct node
{
int number;
node *next;
};
void insert( node * &head, int number, size_t &size, size_t pos )
{
node **current = &head;
while ( pos != 0 && *current != nullptr )
{
--pos;
current = &( *current )->next;
}
*current = new node { number, *current };
++size;
}
std::ostream & printlist( const node* head, std::ostream &os = std::cout )
{
for ( const node *current = head; current != nullptr; current = current->next )
{
os << current->number << ' ';
}
return os;
}
int main()
{
node *head = nullptr;
size_t size = 0;
size_t pos;
int numb;
numb = 5;
pos = 0;
insert( head, numb, size, pos );
printlist(head) << '\n';
numb = 6;
pos = 2;
insert( head, numb, size, pos );
printlist(head) << '\n';
numb = 4;
pos = 0;
insert( head, numb, size, pos );
printlist(head) << '\n';
numb = 10;
pos = 2;
insert( head, numb, size, pos );
printlist(head) << '\n';
std::cout << "There are " << size << " nodes in the list.\n";
return 0;
}
The program output is
5
5 6
4 5 6
4 5 10 6
There are 4 nodes in the list.
Pay attention to that you need to write also a function that will free all allocated memory for the list.
Related
I was printing the max of a linked list in C++ language . But I was not getting the desired output. While Building and running the code, the terminal gets stuck in building it. I tried it in VS Code and Sublime text both. I am using mingw64 compiler.
After the run the program this happens Gets stuck after displaying the linked list
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct node {
int data;
struct node *next;
} *first = NULL;
//declaring a global head/first pointer which stores the address of first node
void create(int a[], int n) {
int i;
struct node *t, *last;
first = (struct node *)malloc(sizeof(struct node));
first->data = a[0];
first->next = NULL;
last = first;
for (i = 1; i < n; i++) {
// t = new node;
t = (struct node *)malloc(sizeof(struct node));
t->data = a[i];
t->next = NULL;
last->next = t;
last = t;
}
}
void display(struct node *p) {
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
}
int Max(struct node *p) {
int max = -100;
while (p != NULL) {
if (p->data > max) {
max = p->data;
p = p->next;
}
}
return max;
}
int main() {
int m = 0;
int a[] = { 3, 5, 7, 10, 15, 8, 12, 20 };
create(a, 8);
display(first);
printf("\n");
m = Max(first);
cout << "The maximum of the linked list is : " << m;
return 0;
}
while (p != NULL)
{
if (p->data > max)
{
max = p->data;
p = p->next;
}
}
Update this to
while (p != NULL)
{
if (p->data > max)
{
max = p->data;
}
p = p->next;
}
Otherwise your code will STUCK in infinite loop.
I usually prefer one line comparison so that code is easy to understand and no bus will appear
int Max(struct node *p) {
int max_number = INT_MIN;
while (p != NULL) {
max_number = max(max_number, p->data);
p = p->next;
}
return max_number;
}
Your code is a mixture of C and C++ code. You should settle for one or the other and use idioms appropriate for the one you choose. Using a mixture of C and C++ is a recipe for failure. As coded, the program is closer to C than C++, just remove the C++isms and program in C.
The reason it gets stuck is p does not get updated in the while loop when the value p->data is not greater than max. Note however that there are other problems: the code will not find the maximum value if all values are less than -100 and it will return -100 if the list is empty.
Here is a modified version, in C, with both issues corrected:
#include <stdio.h>
#include <stdlib.h>
//declaring a global head/first pointer which stores the address of first node
struct node {
int data;
struct node *next;
} *first = NULL;
/* append the elements from a[] to the end of the linked list */
void create(const int a[], int n) {
struct node *last;
last = first;
while (last && last->next) {
last = last->next;
}
for (int i = 0; i < n; i++) {
// t = new node;
struct node *t = (struct node *)malloc(sizeof(struct node));
if (t == NULL)
return;
t->data = a[i];
t->next = NULL;
if (last)
last->next = t;
else
first = t;
last = t;
}
}
void display(const struct node *p) {
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int getmax(struct node *p) {
int max = 0;
if (p != NULL) {
max = p->data;
p = p->next;
while (p != NULL) {
if (max < p->data) {
max = p->data;
}
p = p->next;
}
}
return max;
}
int main() {
int a[] = { 3, 5, 7, 10, 15, 8, 12, 20 };
create(a, sizeof(a) / sizeof(a[0]));
display(first);
printf("The maximum of the linked list is: %d\n", getmax(first));
return 0;
}
Except these two lines
using namespace std;
and
cout << "The maximum of the linked list is : " << m;
there is nothing in the program that could be referenced as a C++ code and not C code. Moreover you even forgot to include the header <iostream>.
Also the program has an inconsistence interface. Some functions deal directly with the global variable first while other functions accept the variable through parameters.
Even the function create can invoke undefined behavior because the user can pass as the second argument zero or a negative number.
void create(int a[], int n) {
int i;
struct node *t, *last;
first = (struct node *)malloc(sizeof(struct node));
first->data = a[0];
//...
In this case the expression a[0] has an indeterminate value.
The function Max (Why does its name start with an upper case letter?) has a bug. Moving to a next node occurs only in case when p->data > max
if (p->data > max) {
max = p->data;
p = p->next;
}
You need to place the statement
p = p->next;
after the if statement
int Max(struct node *p) {
int max = -100;
while (p != NULL) {
if (p->data > max) {
max = p->data;
}
p = p->next;
}
return max;
}
But in any case the function does not make a great sense because the returned value -100 for an empty list can be a valid data for the list.
If you are learning C++ then start to learn it from the C++ 17 Standard and use features of C++ instead of features of C as the C++ operator new instead of the C function malloc.
Your program as indeed a C++ program can look for example the following way.
#include <iostream>
#include <optional>
#include <functional>
#include <iterator>
struct node
{
int data;
node *next;
};
void clear( node * &head )
{
while ( head ) delete std::exchange( head, head->next );
}
void create( node *&head, const int a[], size_t n )
{
clear( head );
node **current = &head;
for (size_t i = 0; i < n; i++)
{
*current = new node{ a[i], nullptr };
current = &( *current )->next;
}
}
std::ostream &display( const node *head, std::ostream &os = std::cout )
{
for (const node *current = head; current; current = current->next)
{
os << current->data << " -> ";
}
return os << "null";
}
std::optional<int> max( const node *head )
{
std::optional<int> max_value;
if (head)
{
max_value = head->data;
for (const node *current = head->next; current; current = current->next)
{
if (max_value < current->data) max_value = current->data;
}
}
return max_value;
}
int main()
{
node *head = nullptr;
int a[] = { 3, 5, 7, 10, 15, 8, 12, 20 };
create( head, a, std::size( a ) );
display( head ) << '\n';
auto max_value = max( head );
if ( max_value )
{
std::cout << "The maximum of the linked list is : " << *max_value << '\n';
}
else
{
std::cout << "The list is empty.\n";
}
clear( head );
max_value = max( head );
if ( max_value )
{
std::cout << "The maximum of the linked list is : " << *max_value << '\n';
}
else
{
std::cout << "The list is empty.\n";
}
return 0;
}
The program output is
3 -> 5 -> 7 -> 10 -> 15 -> 8 -> 12 -> 20 -> null
The maximum of the linked list is : 20
The list is empty.
# include <iostream>
using namespace std;
class Node
{
public:
int d;Node*temp1;
Node*next;Node*temp2;
};
void insert(Node*&head,int x)
{
Node*node = new Node(); // allocate memory 2 node let node be an abstract data
node->d = x; // define data in the new node as new data (saving data define in there)
node->next = head; // Let next of the new node as head
head = node; // let pointer name head point new node
}
void print(Node*node)
{
while (node != NULL)
{
cout<<' '<<node->d;
node = node->next;
}
}
void Delete(Node*&head,int n) // Delete node at position
{
int i;Node*node=head;// temp1 points 2(n-1)th
if(n==1)
{
head = node->next; // head now points 2 second node.
return;
}
for(i=0;i<n-2;i++)
{
head = node->next;
} // temp1 points 2 (n-1)th Node
Node*nnode= node->next; // nth node temp1=node temp2=nnode
node-> next = nnode->next; //(n+1)th Node
}
int main()
{
Node*head = NULL; // Start with empty List
int a,n,i,x;
cin>>n;
for(i=0;i<n;i++)
{
cin>>x;
insert(*&head,x);
}
cout<<"Enter a position:";
cin>>a;
Delete(head,a);print(head);
}
The Output is:
3 // how many number that singly linked list can received
1 2 3 // define many numbers
Enter a position : 1
2 1 // false output it should be 2 3
The output should be:
3
1 2 3
Enter a position : 1
Linked List is 1->2->3
position 1 is remove // at any position we want 2 remove it will show that position we remove
2->3
Enter a position : 4
No data at 4th position
Linked List is 2->3
In the Delete function you have the loop
for(i=0;i<n-2;i++)
{
head = node->next;
}
Because you pass head by reference, you actively destroy the list with this loop. Furthermore since you have node = head earlier, the assignment is effectively head = head->next in the first iteration.
You need to use the variable node instead of head:
for(i=0;i<n-2;i++)
{
node = node->next;
}
You also need to protect against going beyond the end of the list:
for(i = 0; (i < n - 2) && (node->next != nullptr) ;i++)
For starters the declaration of the node of a singly linked list has redundant data members temp1 and temp2 that do not make sense.
The declarations can look like
struct Node
{
int data;
Node *next;
};
In this case the function insert (that you could call like
insert(head,x);
instead of
insert(*&head,x);
as you are doing) will look like
void insert( Node * &head, int x )
{
head = new Node { x, head };
}
In C++ (and in C) indices start from 0. So the function delete also shall accept indices starting from 0. The type of the corresponding parameter shall be an unsigned integer type for example size_t. Otherwise the user can pass a negative number as an index.
The function produces memory leaks because it in fact does not free allocated nodes. It can invoke undefined behavior when the pointer to the head node is equal to NULL. And in general the function does not make sense.
It can be defined the following way
bool Delete( Node * &head, size_t n )
{
Node **current = &head;
while ( *current && n-- )
{
current = &( *current )->next;
}
bool success = *current != nullptr;
if ( success )
{
Node *tmp = *current;
*current = ( *current )->next;
delete tmp;
}
return success;
}
Here is a demonstrative program.
#include <iostream>
struct Node
{
int data;
Node *next;
};
void insert( Node * &head, int x )
{
head = new Node { x, head };
}
bool Delete( Node * &head, size_t n )
{
Node **current = &head;
while ( *current && n-- )
{
current = &( *current )->next;
}
bool success = *current != nullptr;
if ( success )
{
Node *tmp = *current;
*current = ( *current )->next;
delete tmp;
}
return success;
}
std::ostream & print( Node * &head, std::ostream &os = std::cout )
{
for ( Node *current = head; current != nullptr; current = current->next )
{
os << current->data << " -> ";
}
return os << "null";
}
int main()
{
Node *head = nullptr;
for ( int i = 3; i != 0; i-- ) insert( head, i );
print( head ) << '\n';
size_t pos = 0;
if ( Delete( head, pos ) )
{
print( head ) << '\n';
}
else
{
std::cout << "No data at the position " << pos << '\n';
}
pos = 4;
if ( Delete( head, pos ) )
{
print( head ) << '\n';
}
else
{
std::cout << "No data at the position " << pos << '\n';
}
pos = 1;
if ( Delete( head, pos ) )
{
print( head ) << '\n';
}
else
{
std::cout << "No data at the position " << pos << '\n';
}
pos = 0;
if ( Delete( head, pos ) )
{
print( head ) << '\n';
}
else
{
std::cout << "No data at the position " << pos << '\n';
}
return 0;
}
Its output is
1 -> 2 -> 3 -> null
2 -> 3 -> null
No data at the position 4
2 -> null
null
How can I can remove max value from a Simply-Connected list?
Two of the solutions I tried produce wrong results. Please explain to me what am I doing wrong. With code, if not difficult.
Stack:
struct Stack
{
int info;
Stack *next;
} *top;
Wrong solution 1:
void delMaxValue(Stack **stck, int maxValue){
Stack *tmp = NULL;
do {
if ((*stck)->info != maxValue)
tmp = *stck;
cout << tmp->info << endl;
tmp = tmp->next;
*stck = (*stck)->next;
} while ((*stck)->next != NULL);
while (tmp != NULL)
{
*stck = tmp;
*stck = (*stck)->next;
tmp = tmp->next;
}
Wrong solution 2:
Stack* deleteMaxValue(Stack *begin) {
Stack *t = begin, *p = begin->next;
for (; p; p = p->next)
if (p->info > t->info) t = p;
p = begin;
if (p != t) {
while (p->next != t) p = p->next;
p->next = t->next;
}
else
begin = t->next;
delete t;
return begin;}
#include <cstdio>
#include <iostream>
struct Stack
{
int info;
Stack *next;
// added just to easy initialization
Stack(int _info, Stack *_next) : info(_info), next(_next) {}
} *top;
void delMaxValue(Stack *&head)
{
// first - find MaxValue in the list
// as you can see, i save pointer to the previous element in the list
Stack* max_prev = nullptr;
Stack* max = head;
for(Stack *i_prev = nullptr, *i = head; i; i_prev = i, i = i->next) {
if (max->info < i->info) {
max_prev = i_prev;
max = i;
}
}
// max has the maximum value and max_prev is the element before max in the list
// now we remove max
if (max_prev == nullptr) {
// max has no prev, so max is the head of the list. We assign the new head
head = max->next;
} else {
max_prev->next = max->next;
max->next = NULL;
}
}
void printStack(Stack *head) {
std::cout << "Priting " << head << std::endl;
for(Stack *i = head; i; i = i->next) {
std::cout << i << " " << i->info << std::endl;
}
}
int main()
{
Stack *head = new Stack(1, new Stack(15, new Stack(10, nullptr)));
printStack(head);
delMaxValue(head);
printStack(head);
return 0;
}
You may interest yourself in list helping macros from bsd, now available in glibc, newlib, openbsd etc., see here.
Your first solution takes maximum value as a parameter, while the second one doesn't. I am assuming we don't have the maximum value and will calculate it while processing the stack.
The basic approach should be to think of a logic first.
Step 1.) We need to pop all the elements to find the maximum element in the stack. Also, we need to store all the values we popped in another stack(say, auxiliary). Now, we are aware of the maximum value(say MAX).
Step 2.) Note we would have the stack in reverse now. Pop all elements from the auxiliary stack and if the value is not max, push them in the original stack.
Data Initially,
Original Stack: 1->2->3->4->100->5->7->NULL
Auxiliary Stack: NULL
Data after first Step,
Original Stack: NULL
Auxiliary Stack: 7->5->100->4->3->2->1->NULL
MAX: 100
Finally,
Original Stack: 1->2->3->4->5->7->NULL
Auxiliary Stack: NULL
Try to code for this. Your both solutions are doing things way differently than expected.
I hope It will be helpful.
#include <iostream>
struct LList
{
int info;
LList *next;
//constructer
LList(int info_) :info(info_) {
next = nullptr;
}
};
void removeMaxValue(LList *&root) {
int max = 0;
LList *temp = root;
//Searching for max value
while (temp!=nullptr)
{
if (temp->info > max)
max = temp->info;
temp = temp->next;
}
temp = root;
//Find max value and remove
while (temp->next->info != max)
temp = temp->next;
LList *maxNode = temp->next;
temp->next = temp->next->next;
delete maxNode;
}
void print(const LList *root)
{
while (root!=nullptr)
{
std::cout << root->info << " ";
root = root->next;
}
std::cout << std::endl;
}
int main() {
LList *root = new LList(15);
root->next= new LList(10);
root->next->next= new LList(45);
root->next->next->next = new LList(85);
root->next->next->next->next = new LList(5);
//before removing
print(root);
removeMaxValue(root);
//After removing
print(root);
std::cin.get();
}
Your two functions take two different approaches. I chose the one where the function doesn't know what actual max value is so it has to find it first.
First, the function just iterates through the elements and chooses the max value.
Then it searches for the first node that contains this value and removes the node.
void stackRemoveMaxValue(Stack*& top) {
if(top == nullptr) {
return;
}
// Find max value.
int maxValue = top->info;
Stack* node = top->next;
for(; node != nullptr; node = node->next) {
if(maxValue < node->info) {
maxValue = node->info;
}
}
// Remove first node that contains maxValue.
Stack* previous = nullptr;
Stack* current = top;
do {
if(current->info != maxValue) {
previous = current;
current = current->next;
} else {
if(previous != nullptr) {
previous->next = current->next;
} else {
top = current->next;
}
delete current;
return;
}
} while(current != nullptr);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a task to delete any duplicate elements from a list. I am using a struct and pointers for my functions. Here is the struct and the function:
struct node
{
int key;
node *next;
}*start = NULL;
int SIZE = 0;
Where size increments when an item is added. There is the function for deleting duplicates:
void del_dup()
{
if (!start) {
return;
}
if (SIZE == 1) {
return;
}
node * pointer = start->next;
node * prev = start;
node * mPointer = nullptr;
node * mPrev = nullptr;
for (int i = 0; i < SIZE - 1; i++)
{
if (pointer->next)
{
mPointer = pointer->next;
mPrev = pointer;
}
for (int j = i + 1; j <= SIZE; j++)
{
if (pointer->key == mPointer->key)
{
mPrev->next = mPointer->next;
delete mPointer;
}
else
{
mPrev = mPointer;
mPointer = mPointer->next;
}
}
prev = pointer;
pointer = pointer->next;
}
}
The thing is I get a crash at the if statement to compare if the two elements match:
if (pointer->key == mPointer->key)
The error is access violation type and nullptr for mPointer.
The list is filled from the user every time he runs the program with the values he wants. Here is the push function:
void push_start(int n) {
elem *p = start;
start = new elem;
start->key = n;
start->next = p;
SIZE++;
}
Any help to fix this would be appreciated. Thanks in forward!
For starters it is a bad idea to declare the variable SIZE outside the structure definition. In this case all functions that deal with the list will suffer from accessing to the global variable. You can not have more than one list in the program.
You could "wrap" the structure node in one more structure as for example
struct node
{
int key;
node *next;
};
struct list
{
node *head;
size_t /*int*/ size;
};
In this case each list would have its one data member size.
The function del_dup looks very confusing and you are using confusing names as for example pointer and mPointer. You should not rely on the variable SIZE that shall be decremented when a node is deleted.
I can suggest the following function implementation.
#include <iostream>
#include <cstdlib>
#include <ctime>
struct node
{
int key;
node *next;
} *head = nullptr;
size_t size;
void push_front( node * &head, int key )
{
head = new node { key, head };
++size;
}
std::ostream & display_list( node * head, std::ostream &os = std::cout )
{
os << size << ": ";
for ( const node *current = head; current; current = current->next )
{
os << current->key << ' ';
}
return os;
}
void del_dup( node * head )
{
for ( node *first = head; first; first = first->next )
{
for ( node *current = first; current->next; )
{
if ( current->next->key == first->key )
{
node *tmp = current->next;
current->next = current->next->next;
delete tmp;
--size;
}
else
{
current = current->next;
}
}
}
}
int main()
{
const size_t N = 10;
std::srand( ( unsigned int )std::time( nullptr ) );
for ( size_t i = 0; i < N; i++ )
{
push_front( head, std::rand() % ( int )N );
}
display_list( head ) << std::endl;
del_dup( head );
display_list( head ) << std::endl;
return 0;
}
The program output might look like
10: 2 2 3 3 8 5 6 2 6 1
6: 2 3 8 5 6 1
At a guess, you're at some point comparing keys with an already deleted node. For example, you're assigning mPointer = pointer->next, then possibly deleting mpointer, then at the end of the inner loop assigning pointer = pointer->next. So wouldn't it be possible for pointer->next to have already been deleted there?
Edit
Acutally it's much more likely that your inner loop condition is the problem. Try just:
for (int j = i + 1; j < SIZE; j++)
instead.
So my assignment requires us to use doubly linked lists to add or multiply numbers together and print them out. I was able to get it to work for whole numbers, but I can't figure out what to change to make it work for decimal numbers as well. Here's what I've got so far. I know it's not the most efficient or cleanest code, but I can try to clarify stuff if it doesn't make sense to you
For example this program will work fine if I do 50382+9281 or 482891*29734,but I need to get it to work for something like 4.9171+49.2917 or 423.135*59
EDIT: Pretend the int values are doubles. I changed it on my actual code, but the result when I do the math is still giving me a whole number so I need to figure out how to insert the decimal at the right place
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <cstdlib>
#include <cstring>
using namespace std;
// A recursive program to add two linked lists
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
// A linked List Node
struct node
{
int data;
node* next;
node *prev;
};
typedef struct node node;
class LinkedList{
// public member
public:
// constructor
LinkedList(){
int length = 0;
head = NULL; // set head to NULL
node *n = new node;
n->data = -1;
n->prev = NULL;
head = n;
tail = n;
}
// This prepends a new value at the beginning of the list
void addValue(int val){
node *n = new node(); // create new Node
n->data = val; // set value
n->prev = tail; // make the node point to the next node.
// head->next = n;
// head = n;
// tail->next = n; // If the list is empty, this is NULL, so the end of the list --> OK
tail = n; // last but not least, make the head point at the new node.
}
void PrintForward(){
node* temp = head;
while(temp->next != NULL){
cout << temp->data;
temp = temp->next;
}
cout << '\n';
}
void PrintReverse(){
node* temp = tail;
while(temp->prev != NULL){
cout << temp->data;
temp = temp->prev;
}
cout << '\n';
}
void PrintReverse(node* in){
node* temp = in;
if(temp->prev== NULL){
if(temp->data == -1)
cout << temp->data << '\n';
}
else{
cout << temp->data << '\n';
temp = temp->prev;
PrintReverse(temp);
}
}
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int popValue(){
node *n = head;
int ret = n->data;
head = head->next;
delete n;
return ret;
}
void swapN(node** a, node**b){
node*t = *a;
*a = *b;
*b = t;
}
node *head;
node *tail;
// Node *n;
};
/* A utility function to insert a node at the beginning of linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* A utility function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d", node->data);
node = node->next;
}
// printf("\n");
}
// A utility function to swap two pointers
void swapPointer( node** a, node** b )
{
node* t = *a;
*a = *b;
*b = t;
}
/* A utility function to get size of linked list */
int getSize(struct node *node)
{
int size = 0;
while (node != NULL)
{
node = node->next;
size++;
}
return size;
}
// Adds two linked lists of same size represented by head1 and head2 and returns
// head of the resultant linked list. Carry is propagated while returning from
// the recursion
node* addSameSize(node* head1, node* head2, int* carry)
{
// Since the function assumes linked lists are of same size,
// check any of the two head pointers
if (head1 == NULL)
return NULL;
int sum;
// Allocate memory for sum node of current two nodes
node* result = (node *)malloc(sizeof(node));
// Recursively add remaining nodes and get the carry
result->next = addSameSize(head1->next, head2->next, carry);
// add digits of current nodes and propagated carry
sum = head1->data + head2->data + *carry;
*carry = sum / 10;
sum = sum % 10;
// Assigne the sum to current node of resultant list
result->data = sum;
return result;
}
// This function is called after the smaller list is added to the bigger
// lists's sublist of same size. Once the right sublist is added, the carry
// must be added toe left side of larger list to get the final result.
void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
{
int sum;
// If diff. number of nodes are not traversed, add carry
if (head1 != cur)
{
addCarryToRemaining(head1->next, cur, carry, result);
sum = head1->data + *carry;
*carry = sum/10;
sum %= 10;
// add this node to the front of the result
push(result, sum);
}
}
// The main function that adds two linked lists represented by head1 and head2.
// The sum of two lists is stored in a list referred by result
void addList(node* head1, node* head2, node** result)
{
node *cur;
// first list is empty
if (head1 == NULL)
{
*result = head2;
return;
}
// second list is empty
else if (head2 == NULL)
{
*result = head1;
return;
}
int size1 = getSize(head1);
int size2 = getSize(head2) ;
int carry = 0;
// Add same size lists
if (size1 == size2)
*result = addSameSize(head1, head2, &carry);
else
{
int diff = abs(size1 - size2);
// First list should always be larger than second list.
// If not, swap pointers
if (size1 < size2)
swapPointer(&head1, &head2);
// move diff. number of nodes in first list
for (cur = head1; diff--; cur = cur->next);
// get addition of same size lists
*result = addSameSize(cur, head2, &carry);
// get addition of remaining first list and carry
addCarryToRemaining(head1, cur, &carry, result);
}
// if some carry is still there, add a new node to the fron of
// the result list. e.g. 999 and 87
if (carry)
push(result, carry);
}
node* reverse_list(node *m)
{
node *next = NULL;
node *p = m;
node *prev;
while (p != NULL) {
prev = p->prev;
p->prev = next;
next = p;
p = prev;
}
return prev;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Multiply2(node* n1, node* n2);
int digitsPerNode = 2;
node* result;
node* resultp = result;
node* resultp2 = result;
void Multiply(node* n1, node* n2)
{
if (n2->prev != NULL)
{
Multiply(n1, n2->prev);
}
Multiply2(n1, n2);
resultp2 = resultp = resultp->prev;
}
void Multiply2(node* n1, node* n2)
{
if (n1->prev != NULL)
{
Multiply2(n1->prev, n2);
}
if (resultp2 == NULL)
{
resultp2->data = 0;
result = resultp = resultp2;
}
int m = n1->data * n2->data + resultp2->data;
int carryon = (int)(m / pow(10, digitsPerNode));
resultp2->data = m % (int)pow(10, digitsPerNode);
if (carryon > 0)
{
if (resultp2->prev == NULL)
{
resultp2->prev->data = carryon;
}
else
{
resultp2->prev->data += carryon;
}
}
resultp2 = resultp2->prev;
}
/* int* buffer;
int lenBuffer = 0;
void multiplyHelper(int v, node* , int o);
void addToBuffer(int v, int i);
node* multiply(node* num1, node* num2)
{
if (num1 == NULL || num2 == NULL) return NULL;
int length1 = getSize(num1);
int length2 = getSize(num2);
if (length1 > length2) return multiply(num2, num1);
// initialize buffer
lenBuffer = length1 + length2;
buffer = new int[lenBuffer];
memset(buffer, 0, sizeof(int) * lenBuffer);
// multiply
int offset = 0;
node* anode = num1;
while (anode && anode->data!= -1)
{
multiplyHelper(anode->data, num2, offset);
anode = anode->prev;
offset++;
}
// transfer buffer to a linked list
node* h;
int pos = 0;
while (pos < lenBuffer && buffer[pos] == 0) pos++;
if (pos < lenBuffer)
{
node* temp;
temp->data = buffer[pos++];
h = temp;
anode = h;
while (pos < lenBuffer)
{
node* temp;
temp->data = buffer[pos++];
anode->prev = temp;
anode = anode->prev;
}
}
delete buffer;
lenBuffer = 0;
buffer = NULL;
cout << h->data << endl;
return h;
}
// multiply a single digit with a number
// called by multiply()
void multiplyHelper(int value, node* head, int offset)
{
// assert(value >= 0 && value <= 9 && head != NULL);
if (value == 0) return;
node* anode = head;
int pos = 0;
while (anode != NULL)
{
int temp = value * anode->data;
int ones = temp % 10;
if (ones != 0) addToBuffer(ones, offset + pos + 1);
int tens = temp / 10;
if (tens != 0) addToBuffer(tens, offset + pos);
anode = anode->prev;
cout << anode->data;
pos++;
}
}
// add a single digit to the buffer at place of index
// called by multiplyHelper()
void addToBuffer(int value, int index)
{
// assert(value >= 0 && value <= 9);
while (value > 0 && index >= 0)
{
int temp = buffer[index] + value;
buffer[index] = temp % 10;
value = temp / 10;
index--;
}
}*/
// Driver program to test above functions
int main(int argc, char *argv[])
{
char filename[50];
string name= argv[1];
string dig;
name.erase(0,9);//Parse input to only get input file.
ifstream file;
int digits;
for(int i = 0; i < name.length(); i++){
if(name.at(i) == ';'){
// dig = name.substr(0,name.length()-i);
name = name.substr(0,name.length()-i);
}
}
//cout << dig << endl;
//file.open("input.txt");
file.open(name.c_str());
digits = 2;
///////
///////////////////////////////////////////////////////////////////////
int words = 0;
int numbers = 0;
while(!file.eof()) //Goes through whole file until no more entries to input
{
string word;
getline(file,word); //Inputs next element as a string
// word << file;
//cout << word << '\n';
int x = 0;
node *head1 = NULL, *head2 = NULL, *result = NULL;
int counter = 0;
int t1index = 0; //keep tracks of nodes to multiply
int t2index = 0;
char operatorX;
LinkedList tempList1;
LinkedList tempList2;
while(x<word.length()) //Loops through each string input
{
//if(x<word.length()&&isalpha(word.at(x))) //Checks that x is in bounds and that char at position x is a letter
if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit
{
int start = x;
while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion
{
x++;
}
string temp = word.substr(start, x).c_str();
// cout << temp << '\n';
for(int i = 0; i < temp.length();i++){
tempList1.addValue(atoi(temp.substr(i, 1).c_str()));
// push(&head1, atoi(temp.substr(i, 1).c_str()));
counter++;
t1index++;
}
//search for the operator
while(x<word.length()){
if(x<word.length()&& (!isspace(word.at(x)) && !isdigit(word.at(x))))
{
while(x<word.length()&&(!isspace(word.at(x)) && !isdigit(word.at(x)))) //Loops past the letter portion
{
// cout << (word.at(x))<< '\n';
operatorX = word.at(x);
x++;
}
//search second value
while(x<word.length()){ //second value find
//start
if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit
{
int start = x;
while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion
{
x++;
}
string temp = word.substr(start, x).c_str();
for(int i = 0; i < temp.length();i++){
tempList2.addValue(atoi(temp.substr(i, 1).c_str()));
// push(&head2, atoi(temp.substr(i, 1).c_str()));
// cout << atoi(temp.substr(i, 1).c_str());
counter++;
}
//////START READING NUMBERS BACKWARDS
LinkedList finalList;
node* tempA = tempList1.tail;
node* tempB = tempList2.tail;
// multiply(tempA, tempB);
//ADDITION
while(tempA != NULL){
if(tempA->data != -1){
push(&head1,tempA->data);
// cout << tempA->data;
}
tempA = tempA->prev;
}
while(tempB != NULL){
if(tempB->data != -1){
push(&head2, tempB->data);
// cout << tempB->data;
}
tempB = tempB->prev;
}
// multiply(head1, head2);
// result = multiply(head1, head2);
// tempList1.PrintReverse();
addList(head1, head2, &result);
printList(head1);
cout << operatorX;
printList(head2);
cout << "=";
printList(result);
cout << endl;
}
else{
x++;
}
//end
}
}
else{
x++;
}
}
}
else //If char at position x is neither number or letter skip over it
{
x++;
}
}
}
}
Since you're working in C++, use a template/overloaded operators. Cast your ints to a floating point type as necessary. See e.g.:
C++ Template problem adding two data types