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;
}
Related
I've been struggling with this homework for so long that I really appreciate any help I can get.
The problem I am stuck on is pretty simple but a bit confusing.
So the big part of the problem is solved (As mentioned in the first code comment — to find the maximum sum path between these two sorted linked lists)
/*
|--------------------------------------------------------------------------
| ADSL Assignment 1 | Maximum Sum Problem. |
|--------------------------------------------------------------------------
| * You are provided with two sorted lists as input.
| * Those lists have some nodes in common.
| * Find a new list composed of the union of the nodes of those two lists.
| * To create the new list, you should take parts (paths of one or more nodes) from each list and merge them together.
| * You are allowed to switch between the two original lists only at intersections (same node in both lists).
| * in order to figure out the resulting list having the path that represents the greatest maximum total.
| Input:
| * Two Sorted Linked Lists.
| Output:
| * New list containing maximum sum path.
| * Location of switches between the 2 lists.
*/
#include <iostream>
using namespace std;
class Node {
public:
int num;
Node* next;
Node(int data, Node* next = 0) { this->num = data; this->next = next; }
Node() { this->next = 0; }
};
class List {
public:
Node* head;
Node* tail;
List() { head = tail = 0; }
void AddToTail(int data) {
if (head == 0) head = tail = new Node(data);
else {
tail->next = new Node(data);
tail = tail->next;
tail->next = 0;
}
}
void Print() {
Node* temp = head;
if (temp == 0) cout << "Empty List\n";
while(temp != 0) {
cout << temp->num << "\t";
temp = temp->next;
}
cout << "\n";
}
};
List MaxSumPath(Node* head1, Node* head2)
{
List l;
Node* temp1 = 0;
Node* temp2 = 0;
Node* temp = 0;
Node* result = 0;
int sum1 = 0;
int sum2 = 0;
while (head1 || head2) {
temp1 = head1;
temp2 = head2;
sum1 = sum2 = 0;
while (head1 && head2)
{
if (head1->num < head2->num)
{
sum1 += head1->num;
head1 = head1->next;
}
else if (head2->num < head1->num)
{
sum2 += head2->num;
head2 = head2->next;
}
else break;
}
if (head1 == 0)
{
while (head2){
sum2 += head2->num;
head2 = head2->next;
}
}
if (head2 == 0)
{
while (head1){
sum1 += head1->num;
head1 = head1->next;
}
}
if (sum1 >= sum2)
{
if (result == 0) {
result = temp1;
temp = head1;
}
else {
temp->next = temp1;
temp = head1;
}
}
else if (sum1 < sum2) {
if(result == 0) {
result = temp2;
temp = head2;
}
else {
temp->next = temp2;
temp = head2;
}
}
if (head1 && head2 && temp) {
head1 = head1->next;
head2 = head2->next;
temp->next = 0;
}
}
while (result)
{
l.AddToTail(result->num);
result = result->next;
}
return l;
}
int main() {
List l1;
l1.AddToTail(1);
l1.AddToTail(3);
l1.AddToTail(30);
l1.AddToTail(90);
l1.AddToTail(120);
l1.AddToTail(240);
l1.AddToTail(511);
List l2;
l2.AddToTail(0);
l2.AddToTail(3);
l2.AddToTail(12);
l2.AddToTail(32);
l2.AddToTail(90);
l2.AddToTail(125);
l2.AddToTail(240);
l2.AddToTail(249);
cout << "List 1 = ";
l1.Print();
cout << "List 2 = ";
l2.Print();
cout << "---------------------------" << endl;
cout << "List 3 = ";
List result = MaxSumPath(l1.head, l2.head);
result.Print();
return 0;
}
What I can't get my hands on is the switches between two these linked lists, in the example given they should be 3 & 240
A switch is a number that the path continue from in order to get to the maximum sum path, and it only can be a common node between the two lists.
The original problem on geeksforgeeks
You can create a sliding window where the sliding window runs from point of first intersection to second. For two linked lists, there exist two sliding windows. The sliding window with larger sum of the two has to be in the new linked list.
You can have two temp variables pointing to the first element in each linked list after the sliding window's first intersection. And you can point the intersection node to that address once you figure out the path.
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
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).
I was reading about Quicksort, and most of the codes I found were extremely complicated. So, I decided to make one on my own, wherein I considered the first element as pivot and then calling sort function recursively on the rest of the list.
I made the following code for Quicksort. It's as follows:
#include <iostream>
using namespace std;
class node
{
public:
int data;
node * next;
};
node * newnode (int x);
void quicksort(node ** begin, node ** end);
int main (void)
{
int foo,n,i,j,k;
node * temp;
node * head = NULL;
node * tail = NULL;
cout<<"How many nodes do you want to insert\n";
cin>>n;
cout<<"Enter data of linked list\n";
for ( i = 0; i < n; i++ )
{
cin>>foo;
node * bar;
if (head == NULL)
{
head = newnode(foo);
tail = head;
}
else
{
bar = newnode(foo);
tail->next = bar;
tail = bar;
}
}
cout<<"The linkedlist that you entered is as follows\n"; // Taking input
temp = head;
node * prev = NULL;
while (temp != NULL)
{
cout<<temp->data<<"\t";
prev = temp;
temp = temp->next;
}
cout<<"\n";
cout<<"Sorting the linked list now\n"; // Calling sort function
quicksort(&head,&prev);
temp = head;
while (temp != NULL) // Printing output
{
cout<<temp->data<<"\t";
temp = temp->next;
}
return 0;
}
node * newnode (int x) // for allocating a new node
{
node * foo = new node;
foo->data = x;
foo->next = NULL;
return foo;
}
void quicksort(node ** begin, node ** end) // actual sort function
{
if (*begin == *end)
return;
node * pivot = *begin;
node * temp = *begin;
temp = temp->next; // for pointing to next element
while (temp != *end)
{
if (temp->data < pivot->data)
{
node * temp1 = *begin; // swapping the two nodes if less than pivot
*begin = temp;
temp = temp->next;
(*begin)->next = temp1;
}
else
temp = temp->next; else moving to next
}
quicksort(begin,&pivot); // calling for remaining elements (first half)
quicksort(&(pivot->next),end); for second half
}
Howeever, when I run this, on input as 5 4 3 2 1, it sort of goes into an infinite loop. I tried running it through a debugger, but it get's extremely complicated to the extent that I lose my way in between. Can you point out the error where I might be going wrong? Thanks!
I am trying to find the smallest two numbers in a linked list in C++ (without using any built-in functions).
I tried to do so as below:
My logic is:
(1) Assume the first node in the linked list is minimum1 and the second is minimum2. Compare them. The greater becomes minimum2 and the smaller becomes minimum1.
(2) Start from the third node (third because we have already covered first and second) in a while loop until we reach NULL, thus traversing all the list.
(3) Compare the newly traversed node with minimum1 and minimum2. If this node is smaller than minimum1, then put its value in minimum1. minimum2 now will contain the value of minimum1, and minimum1 will contain the value of the newly found node which was smaller than minumum1.
Below is my code which takes the number of nodes to be created, reads the values of all nodes continuously (just keep on pressing Enter after every number), and creates the linked list from all the nodes. These are working fine.
Code
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node* next;
};
typedef struct node node;
node* tree;
// Finding minimum two elements:
void find_two_min(node** List, node** lmin1, node** lmin2)
{
int i;
node* temp = *List;
node *min1, *min2;
node* var1 = *List;
node* second = (*List)->next;
if (var1 > second)
{
min2 = var1;
min1 = second;
}
else
{
min1 = var1;
min2 = second;
}
while (temp->next->next->next != NULL)
{
if (temp->freq < min2->freq)
{
min1 = min2;
min2 = temp;
}
else if (temp->freq < min1->freq)
{
min1 = temp;
}
temp = temp->next;
}
*lmin1 = min1;
*lmin2 = min2;
}
void main()
{
int size, data;
node *min1, *min2;
int count = 0; // This flag is to check whether it's the first node inside the do-while loop.
tree = NULL;
printf("Enter the number of nodes:\n");
scanf("%d", &size);
printf("Enter the elements:\n");
node* prev;
do
{
scanf("%d", &data);
if (count == 0)
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
}
else
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
--size;
++count;
}
while (size > 0);
printf("Printing linked list:\n");
node* temp1;
temp1 = tree;
while (temp1 != NULL)
{
printf("%d, ", temp1->freq);
temp1 = temp1->next;
}
node* temp5 = tree;
find_two_min(&temp5, &min1, &min2);
printf("\nThe two minimum numbers are min1: %d and min2: %d.\n", min1->freq, min2->freq);
}
My code doesn't work on the following input (it gives the wrong output):
Enter the number of nodes:
4
Enter the elements:
0
-5
-2
8
Printing linked list:
0, -5, -2, 8,
The two minimum numbers are min1: 0 and min2: -5.
It was supposed to print "min1: -5" and "min2: -2" but I don't know why it doesn't.
Could anyone please help me eliminate this problem? Any algorithm or piece of code in C/C++ to use as a reference is appreciated. Thanks.
Note: I can't use any built-in functions.
If trying to do 2 things at once confuses you,
then do only 1 thing,
AND LATER, follow that with another singular effort.
i.e.
1st - write search1() to find the smallest item and record the node pointer.
2nd - write search2() to find the smallest item, but add to your search2 the idea to compare the node address to the previously found smallest node. And when already found, skip it as if was not even there.
Implement search1, debug it, and get that working.
AFTER THAT
Implement search2, (probably a copy) and pass in the node pointer found in the search1.
Each time you find a possible update to the search2's smallest node,
insert a test to determine if this node matches the previously found
You have a bug in the line
if(var1>second)
This is comparing the memory addresses of the two nodes, not their frequencies!
There's another bug in the line
if(temp->freq<min2->freq)
and the later line
else if(temp->freq<min1->freq)
The code inside the if statement block following the first line behaves as though you compared temp->freq with min1->freq, not min2->freq as you're currently doing -- and vice versa for the code inside the else if statement block following the second line.
Have two ints min1, min2, both INT_MAX (from limits.h). (Assumption: No element can have the value INT_MAX.)
Walk through your list, one by one. For each element do:
If it is smaller than min1 then min1 is now the second smallest ever, so assign min1 to min2. Then replace min1 with the element.
If it is not smaller than min1 but smaller than min2, it replaces min2.
If none of the above, skip element.
After iterating the list min1 will hold the smallest list value, min2 the second smallest. If min2 is INT_MAX, the list had only one element. If min1 is INT_MAX, the list was empty.
I don't have a full answer for you, but I don't trust checking temp->next->next->next!=NULL in a while loop. That's going to have problems with short lists.
You might be better off looking at one item at a time. Set your two min values to maximum possible value (i.e. INT_MAX) and the node pointers to NULL.
If the value of the first item on the list is less than one of your two min values, update the min value and node pointer.
If the value of the next item on the list is less than one of your two min values, update the min value and the node pointer. You may need to rearrange the order of the min values.
Repeat until you've looked at every item in the list.
You should have your answer when you get to the end of the list and the pointer manipulation will be easier to trace/debug.
I have done the solution of my question using INT_MAX. It works fine:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <limits.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
//Problem creating area is below (code for finding minimum two elements)
void find_two_min(node * * List, node * * lmin1, node * * lmin2)
{
node * temp = * List;
node * min1;
min1 = (node*) malloc(sizeof(node));
min1 -> freq = INT_MAX;
node * min2;
min2 = (node*) malloc(sizeof(node));
min2 -> freq = INT_MAX; //This initialisation of INT_MAX to min2->freq creates problem because printf() statment above it works well but don't work below it.
printf("check1\n");
while (temp != NULL)
{
printf("\ncheck2\n");
if ((temp) -> freq < min2 -> freq)
{
printf("check3\n");
min1 = min2;
min2 = temp;
}
else if ((temp) -> freq < min1 -> freq && (temp) -> freq != min2 -> freq)
{
printf("check4\n");
min1 = temp;
}
temp = temp -> next;
}
* lmin1 = min1;
* lmin2 = min2;
printf("address of min2 is : %d and value is %d \n" ,min2, min2->freq);
printf("check5\n");
}
//Problem creating area is above//
void main()
{
int size, data;
node * min1;
node * min2;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
node * prev;
do {
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev = temp;
tree = prev;
}
else
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev -> next = temp;
prev = prev -> next;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked list\n");
node * temp1;
temp1 = tree;
while (temp1 != NULL)
{
printf("%d-> ", temp1 -> freq);
temp1 = temp1 -> next;
}
node * temp5 = tree;
find_two_min( & temp5, & min1, & min2);
printf("\n The two minimum numbers are min1 :%d and min2 : %d\n", min1 -> freq, min2 -> freq);
}
This should do it:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node {
int freq;
struct node* next;
};
typedef struct node node;
//Function Prototype
void find_two_min(node**, node**, node**);
void main() {
node* min1 = (node*) malloc(sizeof(node));
node* min2 = (node*) malloc(sizeof(node));
node* tree = NULL;
node* prev;
node* temp1;
node* temp;
node* temp5 = tree;
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
printf("enter the size of node\n");
scanf("%d", &size);
printf("start entering the number of elements until your size\n");
do {
scanf("%d", & data);
if (count == 0) {
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
} else {
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
size--;
++count;
} while (size > 0);
printf("Printing linked list\n");
temp1 = tree;
while (temp1) {
printf("%d-> ", temp1->freq);
temp1 = temp1->next;
}
if (count > 1) {
find_two_min(&tree, &min1, &min2);
printf("\n The two minimumnumbers are min1 :%d and min2 : %d\n",min1->freq,min2->freq);
} else
printf("\n Not enough data\n\n");
}
//Function Definition
void find_two_min(node** List,node** lmin1,node** lmin2) {
node* temp = *List;
node* min1;
node* min2;
node* var1 = *List;
node* second=(*List)->next;
/* OLD ONE
if (var1->freq > second->freq) {
min2 = var1;
min1 = second;
} else {
min1 = var1;
min2 = second;
}
*/
if (var1->freq > second->freq) {
min1 = var1;
min2 = second;
} else {
min2 = var1;
min1 = second;
}
while(temp->next) {
printf("\nCurrent freq is %d", temp->freq);
printf("\nNext freq is %d", (temp->next)->freq);
if ((temp->next)->freq < min2->freq) {
printf("\n Condition one is fulfilled");
min1 = min2;
min2 = temp->next;
} else if ((temp->next)->freq < min1->freq) {
printf("\n Condition two is fulfilled");
min1 = temp->next;
}
temp = temp->next;
}
*lmin1 = min1;
*lmin2 = min2;
}