Doubly Linked list instream - C++ - c++

I am doing a project that reads from an input file and puts the digits in two separate doubly linked lists and does operations (addition, multiplication, ) between the two and outputs them to a third doubly linked list.
I am stuck in how to make the loop read character by character and create a new node for each digit.
The intention, in the end, is to change to different sizes of digits per node.
The file would look similar to this:
0*0
890+0
0*400
7650.4+100.26
160008800999008800+4
976976*863586589
Here is the code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
struct node// original node
{
int data;
node* next;
node* prev;
};
struct node *newNode(int data)// add new node with int data input
{
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->data = data;
new_node->next = NULL;
new_node->prev = NULL;
return new_node;
};
// This is supposed to add a new node to a doubly linked list at the end
void insert(node** head_ref,int n)// NOT WORKING PLEASE HELP
{
node* temp = newNode(n);
temp->data = n;
temp->next = NULL;
temp->prev = (*head_ref);
(*head_ref)->next = temp;
temp = (*head_ref);
/*last->next = temp;
last = temp;*/
}
void push(struct node** head_ref, int new_data)// insert at the beginning of the list
{
/* allocate node */
struct node* new_node = newNode(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;
}
/* Adds contents of two linked lists and return the head node of resultant list */
struct node* addTwoLists(struct node* first, struct node* second)
{
struct node* res = NULL; // res is head node of the resultant list
struct node *temp, *prev = NULL;
int carry = 0, sum;
while (first != NULL || second != NULL) //while both lists exist
{
// Calculate value of next digit in resultant list.
// The next digit is sum of following things
// (i) Carry
// (ii) Next digit of first list (if there is a next digit)
// (ii) Next digit of second list (if there is a next digit)
sum = carry + (first ? first->data : 0) + (second ? second->data : 0);
// update carry for next calulation
carry = (sum >= 10) ? 1 : 0;
// update sum if it is greater than 10
sum = sum % 10;
// Create a new node with sum as data
temp = newNode(sum);
// if this is the first node then set it as head of the resultant list
if (res == NULL)
res = temp;
else // If this is not the first node then connect it to the rest.
prev->next = temp;
// Set prev for next insertion
prev = temp;
// Move first and second pointers to next nodes
if (first) first = first->next;
if (second) second = second->next;
}
if (carry > 0)
temp->next = newNode(carry);
// return head of the resultant list
return res;
}
void printList(node* list)
{
node* temp = list;
while (temp != NULL)
{
cout << temp->data << "";
temp = temp->next;
}
}
int main(int argc, char* argv[])
{
struct node* res = NULL;
struct node* first = NULL;
struct node* second = NULL;
// create 2 lists for testing, not the final intention
push(&first, 6);
push(&first, 4);
push(&first, 9);
push(&first, 5);
push(&first, 7);
push(&second, 4);
push(&second, 8);
//Set input
string filename = argv[1];
filename.erase(0, 14);
std::string s = filename;
std::string delimiter = "=";
size_t pos = 0;// Get digits per node
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
s.erase(0, pos + delimiter.length());
}
int digitsPerNode = std::stoi(s);//obtain DigitsPerNode
std::string f = filename;//get correct filename
std::string cutoff = ";";
std::string reducedname = f.substr(0, f.find(cutoff)); // token is "scott"
ifstream instream(reducedname);//Obtain Input Stream
string operands;
char currentchar;
string group;
//Char solution
bool isfirstoperation= true;
char operation = '+';
while (instream.get(currentchar))
{
for (int i = 0; i < digitsPerNode; i++)
{
if (currentchar == '\n')
{
cout << "piripitiflautica" << endl;
}
cout << currentchar << endl;
if (isdigit(currentchar))
{
}
if (currentchar == '+')
{
isfirstoperation = false;
operation = '+';
}
if (i != digitsPerNode)
{
instream.get(currentchar);
}
}
if (currentchar == '\n')
{
cout << "newline" << endl;
}
/*cout <<endl << "Final: "<< group;
group = "";
cout <<endl;*/
}
//Operate
printList(first);
cout << operation;// display operation
printList(second);
cout << "=" ;//Display answer
if (operation = '+')
{
res = addTwoLists(first, second);
//printf("Resultant list is ");
printList(res);
}
cout << endl;
return 0;
}

Two problems to get you started: In insert (which you are not calling), temp = (*head_ref); is backwards; it should be *head_ref = temp;.
And in push you're not updating the prev node in the existing list (watch out for an empty list when you handle this).

Related

C++ How do I get the next node to appear before the previous in a double linked list?

For example, my text file reads:
A 1
A 3
B
A 2
The goal is for the output to be 123, but I have gotten everything but that.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Node
{
public:
char letter;
Node* next;
Node* prev;
Node(char cc)
{
letter = cc;
next = prev = nullptr;
}
};
string command;
char parameter;
Node* p = nullptr;
Node* rows[10];
int currentRow = 0;
void main()
{
for (int i = 0; i < 10; i++)
{
rows[i] = new Node('.');
rows[i]->next = nullptr;
rows[i]->prev = nullptr;
}
ifstream input("c:\\temp\\input.txt");
while (input.peek() != -1)
{
Node* c = rows[currentRow];
c = rows[currentRow];
while (c->next != nullptr)
c = c->next;
input >> command;
if (command == "B") { // Back Curser
//Moves curser back
}
else if (command == "F") { // Forward Curser
//Moves curser forward
}
else if (command == "A") // Add char Done
{
input >> parameter;
Node* newnode = new Node(parameter);
c->next = newnode;
newnode->prev = c;
}
}
input.close();
// display linked list
cout << endl;
for (int i = 0; i < 10; i++)
{
Node* t = rows[i]->next;
if (t != nullptr)
{
while (t != nullptr)
{
cout << t->letter;
t = t->next;
}
cout << endl;
}
}
}
At first I had tried c = c->prev, but that did not work, as nothing was reorganized in my linked list.
I also attempted to create a brand new node that was hopefully then filled by the upcoming character, but my logic did not add up to that, and I ran into multiple issues.
For the lack of implementation details in 'B', I'll just help you fix 'A' instead.
You see, when moving the cursor back, you are now pointing to an element that already has a 'following node' (next is no longer nullptr)
else if (command == "A") // Add char Done
{
input >> parameter;
Node* newnode = new Node(parameter);
newnode->next = c->next; //Link the new node to the previously following node (may be nullptr)
c->next = newnode;
newnode->prev = c;
}
Without the line I inserted, the previous next of c becomes inaccessible, leading to a memory leak.

Cloning a linked list where each node has a random pointer to any other node in linked list

Please help me find what is wrong with my code
(1).
You are given a Singly Linked List with N nodes where each node next pointing to its next node. You are also given M random pointers , where you will be given M number of pairs denoting two nodes a and b i.e. a->arb = b.
The task is to complete the function copyList() which takes one argument the head of the linked list to be cloned and should return the head of the cloned linked list.
NOTE : If their is any node whose arbitrary pointer is not given then its by default null.
I tried to write code for the above problem..but it is not working
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
void print(Node *root) {
Node *temp = root;
while (temp != NULL) {
int k;
if (temp->arb == NULL)
k = -1;
else
k = temp->arb->data;
cout << temp->data << " " << k << " ";
temp = temp->next;
}
}
Node *copyList(Node *head);
void append(Node **head_ref, Node **tail_ref, int new_data) {
Node *new_node = new Node(new_data);
if (*head_ref == NULL) {
*head_ref = new_node;
} else
(*tail_ref)->next = new_node;
*tail_ref = new_node;
}
bool validation(Node *head, Node *res, Node *cloned_addr,
Node *generated_addr) {
if (generated_addr == cloned_addr) return false;
Node *temp1 = head;
Node *temp2 = res;
int len1 = 0, len2 = 0;
while (temp1 != NULL) {
len1++;
temp1 = temp1->next;
}
while (temp2 != NULL) {
len2++;
temp2 = temp2->next;
}
/*if lengths not equal */
if (len1 != len2) return false;
temp1 = head;
temp2 = res;
while (temp1 != NULL) {
if (temp1->data != temp2->data) return false;
if (temp1->arb != NULL and temp2->arb != NULL) {
if (temp1->arb->data != temp2->arb->data) return false;
} else if (temp1->arb != NULL and temp2->arb == NULL)
return false;
else if (temp1->arb == NULL and temp2->arb != NULL)
return false;
temp1 = temp1->next;
temp2 = temp2->next;
}
return true;
}
/* Driver program to test above function*/
int main() {
int T, i, n, l, k;
Node *generated_addr = NULL;
/*reading input stuff*/
cin >> T;
while (T--) {
generated_addr = NULL;
struct Node *head = NULL, *tail = NULL;
cin >> n >> k;
for (i = 1; i <= n; i++) {
cin >> l;
append(&head, &tail, l);
}
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
Node *tempA = head;
int count = -1;
while (tempA != NULL) {
count++;
if (count == a - 1) break;
tempA = tempA->next;
}
Node *tempB = head;
count = -1;
while (tempB != NULL) {
count++;
if (count == b - 1) break;
tempB = tempB->next;
}
// when both a is greater than N
if (a <= n) tempA->arb = tempB;
}
/*read finished*/
generated_addr = head;
Node *res = copyList(head);
Node *cloned_addr = res;
cout << validation(head, res, cloned_addr, generated_addr) << endl;
}
return 0;
}
// } Driver Code Ends
/* the node structure is as follows
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
*/
// Should return the head of the copied linked list the
// output will be 1 if successfully copied
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node*q=head;
Node*clone=new Node(q->data);
clone->next=0;
clone->arb=q->arb;
Node*p=clone;
Node*r=q;
q=q->next;
while(q)
{
r->next=p;
p->next=new Node(q->data);
p=p->next;
p->next=0;
p->arb=q->arb;
r=q;
q=q->next;
}
r->next=p;
p=clone;
while(p)
{
if(p->arb)
p->arb=p->arb->next;
p=p->next;
}
return clone;
}
The pointers inside the list cannot be assigned until you have constructed the cloned list itself, because until then the nodes to point will not exist.
Therefore, you need two iterations: the first one to clone the list and make a dictionary that associates the original node with the clone, and the second one to update the pointers. The code would look like this:
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node* it1 = head;
Node* clone = new Node;
Node* it2 = clone;
std::map<Node*, Node*> nodeDict;
nodeDict[nullptr] = nullptr;
// first iteration: create the list and the values
while(it1){
it2->data = it1->data;
nodeDict[it1] = it2;
it1 = it1->next;
it2->next = it1 ? new Node: nullptr;
it2 = it2->next;
}
// second iteration: connect the nodes
it1 = head;
it2 = clone;
while(it1){
it2->arb = nodeDict[it1->arb];
it1 = it1->next;
it2 = it2->next;
}
return clone;
}

C++ Doubly linked list adding node in alphabetical order and value

My task is a create doubly linked list and sort them according to their data, if new written node's data is equal to the one of the nodes' data in my doubly linked list, i should sort them in a alphabetical order but I am stuck in the function strcmp(temp->name, newnode->name),
For example, I am trying to check if these values entered in order
Christian 250
Tom 200
Alex 250
My sorted doubly linked list give the output as
Alex 250
Christian 250
Tom 200
Here is example of my code
struct node {
int data;
string name;
node* left;
node* right;
node(int i = 0, string s = "", node* l = nullptr, node* r = nullptr) : data(i), name(s), left(l), right(r) {}
};
struct node* head = NULL;
struct node* tail = NULL;
at the top of the program
void insert(int newdata, string name) // Used for insertion at the end of the linked list and make
{ // the connection for each of the node
node* newnode = new node();
node* nodehead = head;
newnode->data = newdata;
newnode->name = name;
newnode->right = NULL;
if( head == NULL)
{
newnode -> left = NULL;
head = tail = newnode;
}
else
{
while (nodehead->right != NULL)
{
nodehead = nodehead->right;
}
nodehead->right = newnode; // make the connection for each of them
newnode->left = nodehead;
tail = newnode; // and newly created node is our tail
sorting(newnode); // then go the function to sort them
}
cout << "New node is added " << newnode->name << " " << newnode->data << endl;
}
then sort them based on their comparison of their data and if they are equal i should check based on their alphabetical order
void sorting( node * &newnode) // ı call sorting function in the insertion function
{
node* temp = head;
node* temp2 = newnode;
int numtemp;
while (temp != nullptr)
{
node* temp2 = temp->right;
while (temp2 != nullptr)
{
if (temp2->data > temp->data) // comparison of their data if newnode's data is larger
{
string strtemp = "";
numtemp = temp->data; // Change their number
temp->data = temp2->data;
temp2->data = numtemp;
strtemp = temp->name; // Change their name
temp->name = temp2->name;
temp2->name = strtemp;
}
else if (temp2->data = temp->data) // if newly data is equal to linked list data
{
int ret;
ret = strcmp(temp2->name, temp->name); // i tried to check their string comparison but it did not work
}
temp2 = temp2->right;
}
temp = temp->right;
}
}
Your comparison operator is bad:
if(temp2->name < temp->name ) // make comparison but im not sure wheteris logical or not
{
string strtemp = "";
strtemp = temp->name; // name change
temp->name = temp2->name;
temp2->name = strtemp;
}
Should be <.
ı basically add in the else if part if the values are same and change names but appreantly it changes whole list of numbers
void sorting( node * &newnode)
{
node* temp = head;
node* temp2 = newnode;
int numtemp;
while (temp != nullptr)
{
node* temp2 = temp->right;
while (temp2 != nullptr)
{
if (temp2->data > temp->data)
{
string strtemp = "";
numtemp = temp->data; // num change
temp->data = temp2->data;
temp2->data = numtemp;
strtemp = temp->name; // name change
temp->name = temp2->name;
temp2->name = strtemp;
}
else if (temp2->data == temp->data) // here is the change
{
if(temp2->name > temp->name ) // make comparison but im not sure wheteris logical or not
{
string strtemp = "";
strtemp = temp->name; // name change
temp->name = temp2->name;
temp2->name = strtemp;
}
}
temp2 = temp2->right;
}
temp = temp->right;
}
}
I'd recommend that you define a comparison on the node itself, and use that in sorting. Keep in mind that if you are comparing through pointers, you'll need to dereference (compare the nodes, not the pointers).
The standard library already has a way to do comparison based on multiple terms. https://en.cppreference.com/w/cpp/utility/tuple/tie
using std::tie ensures that you meet https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings
I am, of course, assuming that std::string's comparison meets your need for alphabetical. If that's not the case, this may need a minor tweek.
#include <string>
#include <iostream>
struct node {
int data;
std::string name;
node* left;
node* right;
node(int i = 0, std::string s = "", node* l = nullptr, node* r = nullptr)
: data(i), name(s), left(l), right(r)
{}
bool operator< (const node & rhs) {
return std::tie(data, name) < std::tie(rhs.data, rhs.name);
}
};
int main(){
// simplistic demo
node a { 21, "green" };
node b { 21, "yellow" };
node * p1 = &a;
node * p2 = &b;
bool less = (*p1) < (*p2);
if (p1->data == p2->data) {
if (*p1 < *p2) {
std::cout << p1->name << " < " << p2->name << std::endl;
} else {
std::cout << p1->name << " >= " << p2->name << std::endl;
}
}
}

I have a program that works for whole numbers, but I need to get it to work for decimal numbers as well

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

Summing two linked lists where each node is a digit

I'm trying to write a function that sums integers, each of which are represented by a linked list where each node->data is a digit 0-9. The least significant digit is at the head of the list and the most is at the tail.
This is from the book Cracking the Coding Interview. Here is my code:
SinglyLinked<int>& addLists(SinglyLinked<int>& ll1, SinglyLinked<int>& ll2)
{
SinglyLinked<int> *sumList = new SinglyLinked<int>;
ListNode<int> *node1 = ll1.head; ListNode<int> *node2 = ll2.head;
int sum, carry = 0;
while(node1 || node2)
{
if(node1)
sum += node1->data;
if(node2)
sum += node2->data;
sum += carry;
carry = 0;
sumList->insertAtEnd(sum%10);
if(sum > 9)
carry = 1;
sum = 0;
node1 = node1->next; node2 = node2->next;
}
return *sumList;
}
First of all, is this code correct? It seems to work, but it seg faults when given two linked lists (integers) of different lengths. I'm wondering if the problem was only intended to solve for the case where the integers are of the same length. If not, how would I go about summing two lists of different lengths? My naive solution is to store the length of each list and then use that to create the digits which only one of the numbers will contribute to, until the two integers are aligned. Is there something more elegant than that?
It segfaults on different length lists, because then the node1 or node2 points to null.
Change
node1 = node1->next; node2 = node2->next;
to
if (node1)
node1 = node1->next;
if (node2)
node2 = node2->next;
while(node1 || node2)
If either node is ok keep going. But the block expects both nodes to be valid when it gets here:
node1 = node1->next; node2 = node2->next;
You needs your "nexts" in the if node1 checks:
if(node1) {
sum += node1->data;
node1 = node1->next;
}
etc.
There is one condition, where node1 and node2 will point to NULL and if there is a carry from the previous digit operation, it will not be appended to the end of the sumlist. For example, 6->5->4 + 4->5->6 should be 0->1->1->1 but sumlist will be 0->1->1. So before return line you should add:
if (carry)
sumList->insertAtEnd(carry);
Another solution to this problem is when you add the numbers in each list, add them together to get the big sum equal to the sum of two lists, convert that sum into a string, and append each character of the string to a new list. Hope it helps someone. Below is the code.
node.h file
#ifndef node_h
#define node_h
class LinkedList
{
private:
struct node
{
int data;
node *next;
};
node *head;
public:
LinkedList ();
node *createNode (int key);
void appendNodeBack (const int &key);
void printList ();
int SumOfNodes (const LinkedList list1);
};
#endif
node.cpp file
#include "node.h"
#include <math.h>
LinkedList::LinkedList ():head(NULL) {}
LinkedList::node *LinkedList::createNode (int key)
{
node *newNode = new node;
newNode->data = key;
newNode->next = NULL;
return newNode;
}
void LinkedList::appendNodeBack (const int &key)
{
node *newNode = createNode (key);
//if tree is empty
if (head == NULL)
{
head = newNode;
return;
}
//if tree is not empty
//traverse to the last node in the list
node *temp = head;
while (temp->next != NULL)
temp = temp->next;
temp->next = newNode;
}
void LinkedList::printList ()
{
//if tree is empty
if (head == NULL)
{
std::cout << "Tree is empty!\n";
return;
}
//if tree not empty
node *temp = head;
while (temp != NULL)
{
std::cout << temp->data<<"-->";
temp = temp->next;
}
std::cout << "NULL\n";
}
int LinkedList::SumOfNodes (const LinkedList list1)
{
//find the length of the list
node *temp = head;
int count = 0;
while (temp != NULL)
{
count++;
temp = temp->next;
}
//re-assign temp to head
temp = head;
//calculate the sum
unsigned int sum = 0;
for (unsigned int i = 1; i < pow (10, count); i = i * 10)
{
sum = sum + temp->data * i;
temp = temp->next;
}
return sum;
}
main.cpp file
#include <iostream>
#include "node.cpp"
int main ()
{
LinkedList list1, list2, list3;
list1.appendNodeBack (2);
list1.appendNodeBack (3);
list1.appendNodeBack (5);
list1.appendNodeBack (4);
list2.appendNodeBack (5);
list2.appendNodeBack (6);
list2.appendNodeBack (7);
list2.appendNodeBack (8);
list1.printList ();
std::cout << list1.SumOfNodes (list1) << std::endl;
list2.printList ();
std::cout << list2.SumOfNodes (list2) << std::endl;
unsigned int sum = list1.SumOfNodes (list1) + list2.SumOfNodes (list2);
//convert the number to string
std::string str = std::to_string (sum);
//append integer value to the new list
for (unsigned int i = 0; i < str.length (); i++)
list3.appendNodeBack (int (str[i] - '0'));
std::cout << "The new list becomes\n";
list3.printList();
return 0;
}