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.
Related
I was trying to code insert in linkedlist for position 0 (i.e. the beginning of the linked list) and for other positions (like in between any two nodes and at the end of the linkedlist). The code is given below. But it seems to be not working as expected. Please let me know as to what I am doing wrong here.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node *next;
};
void displayLL(Node *p)
{
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
Node *createLL(int A[], int n, Node *ll)
{
Node *tmp, *last;
ll = new Node;
ll->data = A[0];
ll->next = NULL;
last = ll;
for (int i = 1; i < n; i++)
{
tmp = new Node;
tmp->data = A[i];
tmp->next = NULL;
last->next = tmp;
last = tmp;
}
return ll;
}
int countNodesLL(Node *p)
{
int count = 0;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
void InsertNodeLL(Node *p, int index, int value)
{
Node *tmp;
if (index < 0 || index > countNodesLL(p))
{
return;
}
tmp = new Node;
tmp->data = value;
// This should insert in the beginning of the Linked List - but it is not working.
if (index == 0)
{
tmp->next = p; // pointing next of tmp to p node
p = tmp; // making tmp as the HEAD of linkedList
}
// This inserts after 1st node, in between two nodes and at the end of the LL
else
{
for (int i = 0; i < index - 1; i++)
{
p = p->next;
}
tmp->next = p->next;
p->next = tmp;
}
}
int main(int argc, char const *argv[])
{
Node *linkedList = NULL;
int A[] = {1, 2, 3, 4, 5, 6, 7, 8};
linkedList = createLL(A, 8, linkedList);
displayLL(linkedList);
cout << endl;
InsertNodeLL(linkedList, 0, 15);
displayLL(linkedList);
cout << endl;
InsertNodeLL(linkedList, 4, 10);
displayLL(linkedList);
return 0;
}
I am getting the below output:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 10 5 6 7 8
Expected Output:
1 2 3 4 5 6 7 8
15 1 2 3 4 5 6 7 8
15 1 2 3 4 10 5 6 7 8
Please help me as to what is wrong in the code.
You made two mistakes, first you didn't return a value back to the linked list since you passed the pointer by value, and second in your insert function you also do not return a value as well you are modifying the head variable so you lose the previous values. Also you want to insert at the 5th position not the 4th. When you make the changes inside the function you are only using local variables so after the stack frame gets popped your linked list doesn't get updated. You can use a global variable instead but if you are passing by value you have to return back to the caller if you wish to change the list in main. Here is my reimplementation of your code: `
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
void displayLL(Node* p)
{
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
Node* createLL(int A[], int n, Node* ll)
{
Node* tmp, * last;
ll = new Node;
ll->data = A[0];
ll->next = NULL;
last = ll;
for (int i = 1; i < n; i++)
{
tmp = new Node;
tmp->data = A[i];
tmp->next = NULL;
last->next = tmp;
last = tmp;
}
return ll;
}
int countNodesLL(Node* p)
{
int count = 0;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
Node* InsertNodeLL(Node* p, int index, int value)
{
Node* tmp;
Node* tmp2;
if (index < 0 || index > countNodesLL(p))
{
return 0;
}
tmp = new Node;
tmp->data = value;
// This should insert in the beginning of the Linked List - but it is not working.
if (index == 0)
{
tmp->next = p; // pointing next of tmp to p node
p = tmp;
return p; // making tmp as the HEAD of linkedList
}
// This inserts after 1st node, in between two nodes and at the end of the LL
else
{
tmp2 = p;
for (int i = 0; i < index - 1; i++)
{
tmp2 = tmp2->next;
}
tmp->next = tmp2->next;
tmp2->next = tmp;
return p;
}
}
int main(int argc, char const* argv[])
{
Node* linkedList = NULL;
int A[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
linkedList = createLL(A, 8, linkedList);
displayLL(linkedList);
cout << endl;
linkedList = InsertNodeLL(linkedList, 0, 15);
displayLL(linkedList);
cout << endl;
linkedList = InsertNodeLL(linkedList, 5, 10);
displayLL(linkedList);
return 0;
}
`
#include <iostream>
using namespace std;
struct Node
{
int data;
struct Node *next;
} *first = NULL;
void create(int A[], int n)
{
int i;
struct Node *t, *last;
first = new Node;
first->data = A[0];
first->next = NULL;
last = first;
for (i = 1; i < n; i++)
{
t = new Node;
t->data = A[i];
t->next = NULL;
last->next = t;
last = t;
}
}
void Display(struct Node *p)
{
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
int count(Node *p)
{
int count = 0;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
void Insert(struct Node *p, int index, int x)
{
struct Node *t;
int i;
if (index < 0 || index > count(p))
return;
t = new Node;
t->data = x;
// When a node needs to be inserted at the beginning
if (index == 0)
{
t->next = first;
first = t;
}
// When a node needs to be inserted in between two nodes or at the last
else
{
for (i = 0; i < index - 1; i++)
p = p->next;
t->next = p->next;
p->next = t;
}
}
int main()
{
int A[] = {10, 20, 30, 40, 50};
create(A, 5);
Insert(first, 0, 5);
Display(first);
cout << endl;
Insert(first, 2, 15);
Display(first);
cout << endl;
return 0;
}
This too works!!
I have 3 functions here, and the compiler is going through the first 2 functions, but it is not entering the 3rd function(detect_duplicates).
#include <iostream>
using namespace std;
struct node {
int data;
struct node* next;
};
struct node* head = NULL;
void createLL(int a[], int n)
{
head = (struct node*)malloc(sizeof(struct node));
head->data = a[0];
head->next = NULL;
struct node *t, *last;
last = head;
for (int i = 1; i < n; i++) {
t = (struct node*)malloc(sizeof(struct node));
t->data = a[i];
t->next = NULL;
last->next = t;
last = t;
}
}
void printList(struct node* head_ref)
{
printf("Linked list : {");
while (head_ref != NULL) {
printf(" %d ", head_ref->data);
head_ref = head_ref->next;
}
printf("}\n");
}
void detect_duplicates(struct node* head, int size)
{
int x, y;
struct node *temp, *temp2;
temp = head;
cout << "Duplicate elements are : ";
for (int i = 0; i < size; i++) {
x = temp->data;
temp = temp->next;
temp2 = temp;
while (temp2->next != NULL) {
y = temp2->data;
if (x == y) {
cout << y << " ";
}
temp2 = temp2->next;
}
}
}
int main()
{
int Linked_list[30] = { 1, 2, 3, 4, 5, 1, 2, 4, 6, 7, 8 }, size = 11;
createLL(Linked_list, size);
cout << "Input ";
printList(head);
detect_duplicates(head, size);
return 0;
}
This is a program to detect the duplicate elements from an integer linked list. I can't figure out the error in my detect_duplicates function and also my compiler isn't showing a known error. It is just showing a Segmentation fault.
When you want to access the next of temp2 in
temp2 = temp;
while (temp2->next != NULL) {
y = temp2->data;
if (x == y) {
cout << y << " ";
}
temp2 can be a nullptr which may cause a segmentation fault, because it points to nothing and you are trying to access it's member.
I need to define a class of linked list,List, in a way such that object of class can be defined in two ways,
List obj1 = L1();//head=0
List obj2 = L2(given_arr[], size of array) // I would be given an array, whose elements are elements of list
so, I need to form a construter for both,
for obj1, Its easy.
List(){head=0};
But I am not abe to do so for second type of object.
I tried to form a program for this.
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head;
int arr[];
List() { head = 0; }
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
int i;
head->val = arr[0];
for (i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[4] = {9, 89, 0, 43};
List* M = new List();
List* L = new List(barr[4], 4);
L->display();
return 0;
}
This program doesn't work. Please suggest a way to do so.
Make these changes to your main().
int main() {
int barr[] = {9, 89, 0, 43}; // No need to specify size if you're initializing
// List* M = new List(); // unused
// Your array is barr, barr[4] makes no sense. You also don't allocate the List,
// the list allocates
List L = List(barr, sizeof(barr) / sizeof(barr[0]);
L.display(); // -> to .
return 0;
}
This now compiles, but immediately segfaults. Simply running the program in the debugger shows a simple error. The line head->val = arr[0]; attempts to dereference a null pointer. Which takes us to the next thing. Use nullptr, not NULL or 0.
Your array constructor was over-complicated, you just need this:
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
Your addnode() function already handled an empty list. Fixing that, your code should run. I made a couple other small changes, mostly trimming cruft out. Here's your complete code:
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head = nullptr;
List() = default;
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[] = {9, 89, 0, 43};
List L = List(barr, sizeof(barr) / sizeof(barr[0]));
L.display();
return 0;
}
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);
}
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