I dequeue a queue and if the employee's salary is less than 50,000. I am not sure how to enqueue it into another queue as my enqueue function takes three parameters. My assignment says to create a class and then two queues in main. I made the queues being an object of the class, is this correct? How do I enqueue into the second queue with only having one enqueue function in the class which takes three parameters. Thanks for all the help.
#include <cstdlib>
#include <iostream>
#include <string>
#include <iomanip>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::fixed;
using std::setprecision;
struct node{
string name;
int id;
int salary;
struct node *next;
};
node *rear;
node *front;
class DynEmpQueue{
private:
int counter = 0;
public:
void enqueue(string, int, int);
void dequeue();
void traverse()const;
DynEmpQueue()
{
rear = nullptr;
front = nullptr;
counter = 0;
}
};
void DynEmpQueue::enqueue(string localName, int localID, int localSalary)
{
node *temp;
temp = new (struct node);
temp -> name = localName;
temp -> id = localID;
temp -> salary = localSalary;
temp -> next = nullptr;
if (front == nullptr)
front = temp;
else
rear -> next = temp;
rear = temp;
counter++;
}
void DynEmpQueue::dequeue()
{
string localName;
int localID;
int localSalary;
node *temp;
if (front == nullptr)
cout << "The queue is empty.";
else
{
temp = front;
localName = temp -> name;
localID = temp -> id;
localSalary = temp -> salary;
front = front -> next;
delete temp;
counter--;
}
}
void DynEmpQueue::traverse()const
{
node *temp;
temp = front;
if (front == nullptr)
cout << "Queue is empty.";
else
{
cout << "Queue contains " << counter << " elements." << endl;
cout << "Queue elements:" << endl;
while (temp != nullptr)
{
cout << temp -> name << "\t" << temp -> id << "\t" << temp -> salary << endl;
temp = temp -> next;
}
}
}
int main()
{
const int NumberEmployees = 5;
DynEmpQueue originalQueue;
originalQueue.enqueue("Justin Gray", 100, 104000);
originalQueue.enqueue("Mike Smith", 200, 207000);
originalQueue.enqueue("Jose Cans", 400, 47000);
originalQueue.enqueue("Auston Matts", 300, 31000);
originalQueue.enqueue("Liz Learnerd", 600, 89100);
node object;
DynEmpQueue demandSalaryIncrease;
for (int i = 0; i < NumberEmployees; i++)
{
originalQueue.dequeue();
if (object.salary <= 50000)
demandSalaryIncrease.enqueue();
}
demandSalaryIncrease.traverse();
return 0;
}
You cannot know what employees exist in your queue. Look at how you defined your methods:
void enqueue(string, int, int);
void dequeue();
void traverse() const;
As you can see, no method returns either a node or the employee's data. So, as you currently declared the class, there is no way to get employees from your queue. And, since you can't even get employees are in the queue, you cannot add them into another queue.
Possible solution:
Modify your traverse() method so that it takes a salary as argument and returns an array (or even a queue) containing all the employees for which the salary is lower than that salary.
A better and much more flexible solution would be to use a predicate, but (since you are using global variables) it seems like you're not looking for perfect solutions anyway.
Related
how to avoid double id in linked listed, example, i have id, name, gol, so firtst, i input id= 12, name=jon gol=A, when i input again. id=12, its show message "Id cant be same". input again can you help
this is my code for insert linked list first node,
#include <iostream>
#include <string>
#include <conio.h>
struct node {
int id;
char name[20], gol;
node *next;
};
node *head = nullptr;
node *tail = nullptr;
void tambah_awal_list() {
int id;
char name[20];
char gol;
node *baru = new node;
baru->id=head->id;
std::cout << "Id : ";
std::cin >> baru->id;
if (head->id == baru->id){
std::cout << "Id cant be same"<<std::endl;
}
std::cout << "Name : ";
std::cin >> baru->name;
std::cout << "Blood type (A/B/O) : ";
std::cin >> baru->gol;
if(head == nullptr) {
head = baru;
head->next = nullptr;
tail = head;
} else {
baru->next = head;
head = baru;
}
}
what should i change?
It depends on the spec and performance requirements.
If id could be decided by code instead of user input, then you just need to have an global counter increment every time a node is created.
You have to handle it carefully under multi-threading cases or very large number when number of nodes is out of range of int.
// Global variable or class member
int g_nextID = 0;
int generateID(){return ++g_nextID;}
void generate(){
node* n = new node();
n->id = generateID();
// ...
}
Use std::unordered_set<int> which takes O(1) time and O(N) space.
// A global variable or class member
std::unordered_set<int> g_used;
node *head = nullptr;
node *tail = nullptr;
void generate(){
// Inside the function
int id;
// Get user input into id
// ...
// Checking if used
if(g_used.find(id) == g_used.end()){
// Create the node
// ...
g_used.insert(id); // Save it
}else{
// Error handling.
}
}
void removeNode(int id){
// Remove it from list
// ...
// Remove it from set
g_used.erase(id);
}
Lookup the nodes, but it takes O(N) times.
I am trying to get a linked-list class-based queue that holds objects of type "Student", but I've been trying for two days to get this thing to work. Now I am seeing errors of exceptions at the copy constructor of the "Student" class and the return of the dequeue function, and am at a complete loss since I don't even know what that means.
My main issue, from what I can tell, is when I try to assign the return of the dequeue to an object, there is an issue with the fact that I'm using the standard = operator and not a custom operator= for the class. Then again, I am relatively new to classes so I don't know if this is actually the issue.
This is the main code that uses all my files:
#include <iostream>
#include <fstream>
#include <string>
#include "Student.h"
#include "Queue.h"
int main(void)
{
char TempFName[15], TempSName[20];
long Tid_num;
int Tage;
float Tgpa;
Student Student1, StudentA;
queue q1;
int no, temp;
ifstream ip("input.txt");
// modify for your location
ip >> no; /* read in the number of Students */
for (temp = 0; temp < no; temp++)
{
/* read in the Student data in file format */
ip >> TempFName;
Student1.assignFName(TempFName);
ip >> TempSName;
Student1.assignSName(TempSName);
ip >> Tid_num;
Student1.assignId(Tid_num);
ip >> Tage;
Student1.assignAge(Tage);
ip >> Tgpa;
Student1.assignGpa(Tgpa);
q1.enqueue(Student1);
}
ip.close();
queue q2(q1);
q2.enqueue(StudentA);
q1.enqueue(StudentA);
cout << "details for queue 2 are as follows" << endl;
for (temp = 0; temp < no + 1; temp++)
{
Student1 = q2.dequeue();
Student1.print();
}
cout << "There are " << Student1.getNum() << " Student objects in existence";
return 0;
}
My files are:
Student.cpp:
#include <iostream> // need for cout, etc
#include "Student.h"
using namespace std;
Student::Student(const Student& s)
{
firstname = s.firstname;
surname = s.surname;
id_num = s.id_num;
age = s.age;
gpa = s.gpa;
count++;
}
Student::~Student() { count--; }
void Student::assignFName(string tempFName)
{
firstname = tempFName;
}
void Student::assignSName(string tempSName) { surname = tempSName; }
void Student::assignId(long Tid_num) { id_num = Tid_num; }
void Student::assignAge(int Tage) { age = Tage; }
void Student::assignGpa(float Tgpa) { gpa = Tgpa; }
string Student::getSName() { return surname; }
long Student::getId_num() { return id_num; }
int Student::getAge() { return age; }
float Student::getGpa() { return gpa; }
int Student::getNum() { return count; }
void Student::print() const
{
cout << firstname << " " << surname << " " << id_num << " " << age << " ";
cout << gpa << endl; // could do on same line, but do on next line just so can see that can be multiple lines, etc
}
int Student::count = 0;
Student.h:
#pragma once
//Module.h
#ifndef STD_H
#define STD_H
#include <string>
using namespace std;
class Student
{
public:
// just include one constructor definition here to show how it is written if do inline
Student(string fn = "nofirstname", string sn = "nosurname", long i = 0000, int a = 0, float s = 0)
:firstname(fn), surname(sn), id_num(i), age(a), gpa(s) {
count++;
}
Student(const Student& s);
~Student();
void assignFName(string tempFName);
void assignSName(string tempSName);
void assignId(long Tid_num);
void assignAge(int Tage);
void assignGpa(float Tgpa);
string getFName() { return firstname; } // just include one method here to show how it is written if do inline
string getSName();
long getId_num();
int getAge();
float getGpa();
void print() const;
static int getNum();
private:
string firstname, surname;
long id_num;
int age;
float gpa;
static int count;
};
#endif
queue.cpp:
#include "Queue.h"
#include "Student.h"
#include <iostream>
#include <stdlib.h>
void queue::enqueue(Student value) {
QueueNode* temp = new QueueNode(value); //allocating memory for the newly created node, with a value passed into it
if (tail == NULL) { //If there is no tail (i.e. only 1 block in the queue)...
head = tail = temp; //The tail and head are now the one block
return; //
} //
tail->next = temp; //The next address of the tail is made to equal the temporary node
tail = temp; //The tail becomes the temporary node
delete temp;
}
Student queue::dequeue() {
Student a;
if (head == tail) {//if only one node is there
head = tail = NULL;
} else {
head = head->next;
}
if (head == NULL) {
exit(1);
}
a = head->value;
return a;
//Student a;
//QueueNode* temp = head; //store the current head node of the queue
//delete (temp);
//if (head != NULL) {
// head = head->next;
//
//} else {
// tail = NULL;
// //return a;
//}
//a = head->value;
//return a;
}
void queue::printQueue() {
int count = 1; //initiazling counter variable as 1 so that the counter does not start at 0
while (head != NULL) //while the are still blocks in the queue
{
//cout << "\n\tBlock number " << count << " pushed: " << ; //print the block that was just inserted and what position it is at
head->value.print();
head = head->next; //equate the node to the next address
count++; //increment the counter
}
}
queue::~queue() {
head = tail = NULL;
}
queue::queue(const queue& q) {
QueueNode* hold = q.head;
QueueNode* temp, * oldtemp;
if (hold == q.tail)
{
temp = new QueueNode;
head = temp;
tail = temp;
}
else
{
temp = new QueueNode;
head = temp;
while (hold != q.tail)
{
// get the value at the node looking at on queue 'r' list
temp->value = hold->value;
// move to the next entry on 'r' list
hold = hold->next;
oldtemp = temp;
temp = new QueueNode;
oldtemp->next = temp;
}
tail = temp;
}
}
queue::queue() {
head = tail = NULL;
}
//queue::sizeOfQueue() { //function to return the number of nodes in the queue
// //takes in the pointer to the queue so that the function knows which queu to get the size of
// int size = 0; //intialize size integer to be returned
// while (node != NULL) { //for as long as a NULL node is not reached
// node = node->next; //equate the node to the next address
// size++; //increment the size integer
// } //eventually the node will reach the end of the queue where the next address is NULL (because there are no other nodes)
// return size; //return the integer for the size
//}
queue.h:
#pragma once
#include "Student.h"
#include "Node.h"
class queue {
public:
queue();
queue(const queue& q);
~queue();
void enqueue(Student value);
Student dequeue();
void printQueue();
private:
QueueNode* head;
QueueNode* tail;
};
Node.cpp:
#include "Queue.h"
#include "Node.h"
#include "Student.h"
#include <iostream>
QueueNode::QueueNode() {
value = Student();
next = NULL;
}
QueueNode::QueueNode(Student val) {
value = val;
next = NULL;
}
QueueNode::~QueueNode() {
value.~Student();
next = NULL;
}
Node.h:
#pragma once
#include "Student.h"
class QueueNode {
friend void enqueue(Student value);
friend void dequeue();
friend void printQueue();
public:
QueueNode* next; //PUBLIC VARIABLE
Student value;
QueueNode();
QueueNode(Student val);
~QueueNode();
private:
};
The input file that gets the details for the "Student" objects that go in the queue:
3
joe bloggs 40001 24 2.1
mary doe 40002 19 3.9
john boyd 40003 18 1
I look around for some help for single link list around the web but couldn't find the information I needed. What im trying to do is Design and Implement a single linked list with the following operations
a- Create "n" nodes
b- Delete from the middle (where im not deleting the middle, but anything else but the start and end node)
c- Insert in the middle
I did my "insert" part with a ADD function
but when I get to the delete function, im stuck in how to use a single link list & not a double, because Im trying to break that habit. Anyway here my code, it my delete function that im trying to fix. thanks
PS: tell me if my add function is also correct, :)
#include <iostream>
#include <vector>
using namespace std;
class node
{
public:
node(int user_input);
int info;
node * next_node;
};
node::node(int user_input)
{
info = user_input;
next_node = NULL;
}
class link_list
{
public:
node * start;
node * end;
int size;//seperated the attritibute from the method
link_list(); //default constuctor
link_list(int value); //value constuctor
link_list(int value, int num_of_Nodes); //n-ary
void Add(int store_node);
void Print(); //non midify
void insert_at_begining(int value); //while these guys are modify
void insert_at_end(int value); //
void insert_at_middle(int delete_node);
void delete_at_begining();
void delete_at_end(); //
void delete_at_middle(int Nodes_store);
private:
int Number_of_nodeV2;
};
link_list::link_list(int value, int num_of_Nodes) //this
{
//if val = 0 & num = 5 we get 5 new nodes
Number_of_nodeV2 = 0;
if (num_of_Nodes < 1)
{
cout << "error, please enter correct numbers" << endl;
}
else
{
start = new node(value); //this is pointing to node that has value in it.
//start == NULL;
node* tracker = start;
for (int i = 0; i < num_of_Nodes - 1; i++)
{
tracker->next_node = new node(value); //this track each node //-> de-renecen
tracker = tracker->next_node;
}
}
}
void link_list::Add(int store_node)
{
node* tracker = start;
node* newVal = new node(store_node);
while (tracker->next_node != NULL)
{
tracker = tracker->next_node;
}
tracker->next_node = newVal;
}
void link_list::Print()
{
node* tracker = start;
while (tracker != NULL)
{
cout << tracker->info << endl;
tracker = tracker->next_node;
cout << size;
}
}
void link_list::delete_at_middle(int delete_node)
{
//int center = 0;
node* tracker = start;
node* tracker2 = end;
node* temp;
node* temp1;
temp1 = temp = start;
if (start == NULL)
{
cout << "the list is empy" << endl;
}
else //this is where I cant seem to answer, thanks
{
while (temp != end)
{
temp = temp1->next_node;
if (temp->info = delete_node)
{
delete temp;
temp1->next_node = NULL; //ffffffffffff
}
}
tracker = tracker->next_node;
for (size_t i = 0; i < length; i++)
{
pre = start;
pre
}
//iltertae with tracker until the tracker has hit the center
}
}
int main() {
int Nodes_store = 0;
int delete_node = 0;
cout << "please enter the number of nodes" << endl;
cin >> Nodes_store;
cout << "please enter the number of to delete nodes" << endl;
cin >> delete_node;
link_list list = link_list(0, Nodes_store);
list.Print();
//list.delete_at_middle();
//list.Print();
//
//list.insert_at_middle(7);
//list.Print();
}AS'
;'
I have tried looking at videos and older posts but it is still very difficult to understand the concept of copy constructors. Would someone clear it up for me? My class did not really cover this part 100% my professor focused mainly on constructors and destructors.
Main CPP
#include <iostream>
#include "Header.h"
using namespace std;
int main()
{
node access;
access.getData();
access.outData();
system("pause");
return 0;
}
Header File
#include <iostream>
using namespace std;
class node
{
public:
node(); // Had to create my own default constructor because of my copy constructor.
node(const node &n); // This is a copy constructor.
~node();
void getData();
void outData();
private:
int num;
int lCount = 0; // Counts the number of nodes, increments after each user input.
int *ptr; // Where the linked list will be copied into
node *next;
node *first;
node *temp;
node *point;
};
node::node()
{
num = 0;
}
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
node::~node() // Deletes the linked list.
{
while (first != NULL)
{
node *delP = first; // Creates a pointer delP pointing to the first node.
first = first->next; // "Removes first node from the list and declares new first.
delete delP; // Deletes the node that was just removed.
}
cout << "List deleted" << endl;
}
void node::getData() // Simple function that creates a linked list with user input.
{
int input = 0;
point = new node;
first = point;
temp = point;
while (input != -1)
{
cout << "Enter any integer, -1 to end." << endl;
cin >> input;
if (input == -1)
{
point->next = NULL;
break;
}
else
{
lCount++;
point->num = input;
temp = new node;
point->next = temp;
point = temp;
}
}
}
void node::outData()
{
temp = first;
cout << "Original" << endl;
while (temp->next != NULL)
{
cout << temp->num << endl;
temp = temp->next;
}
cout << "Copied" << endl;
for (int i = 0; i < lCount; i++)
{
cout << ptr[i] << endl;
}
}
This little snippet is what I am having trouble with in particular:
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
I figured it out! I was tinkering with a much simpler copy constructor. I was having trouble understanding syntax, everything was very complicated and it was overwhelming to look at.
#include <iostream>
using namespace std;
class node
{
public:
node(int x); // Normal Construtor
node(const node &cpy); // Copy Constructor
void change(); // Changes data value
void outData();
private:
int data;
};
int main()
{
node var1(123);
var1.outData();
node var2 = var1;
var2.outData();
var2.change();
var1.outData();
var2.outData();
system("pause");
return 0;
}
node::node(int x)
{
data = x;
}
node::node(const node &cpy)
{
data = cpy.data;
}
void node::outData()
{
cout << data << endl;
}
void node::change()
{
int userIn;
cin >> userIn;
data = userIn;
}
Output:
123
123
(input: 4444)
Output:
123
4444
I'm trying to implement a stack using a doubly linked list. I know that the functions for my stack class (push, pop) should contain calls to member functions of my doubly linked list class, but I'm having trouble actually implementing that.
dlist.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "dlist.hpp"
using namespace std;
void dlist::appendNodeFront(int shares, float pps){
Node *n = new Node(shares, pps);
if(front == NULL){
front = n;
back = n;
}
else {
front->prev = n;
n->next = front;
front = n;
}
}
void dlist::appendNodeBack(int shares, float pps){
Node *n = new Node(shares, pps);
if(back == NULL){
front = n;
back = n;
}
else {
back->next = n;
n->prev = back;
back = n;
}
}
void dlist::display(){
Node *temp = front;
cout << "List contents: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
void dlist::display_reverse(){
Node *temp = back;
cout << "List contents in reverse: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->prev;
}
cout << endl;
}
void dlist::destroyList(){
Node *T = back;
while(T != NULL){
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
stack.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "stack.hpp"
using namespace std;
stack::stack(){
int i;
for(i = 0; i < 1500; i++){
shares[i] = 0;
pps[i] = 0;
}
first = 0;
}
void stack::push(int num, float price){
if(first ==(1500-1)){
cout << "Stack is full" << endl;
return;
}
first++;
shares[first] = num;
pps[first] = price;
return;
}
void stack::pop(int *num, float *price){
if(first == -1){
cout << "Stack is empty" << endl;
return;
}
num = &shares[first];
price = &pps[first];
cout << shares[first] << endl;
cout << pps[first] << endl;
shares[first] = 0;
pps[first] = 0;
first--;
return;
}
Should the push function in stack basically be a call to appendNodeFront() or appendNodeback()? Any help or advice is greatly appreciated!
You can create a stack class, then use linked list class as its container. In a linked list class there is virtually no limit to the number of items, so you add artificial limit to make it work like a stack. In a linked list, items can be added/removed anywhere in the list, you can limit add/remove the tail node only to make it work like stack. The example below demonstrate the usage.
Node that this is purely a programming exercise. Stack is relatively primitive compared to Doubly-linked list. Encapsulating a linked-list inside stack has no advantage. Also note, I declared all members as public for the sake of simplifying the problem, you may want to change some members to protected/private
#include <iostream>
#include <fstream>
#include <string>
using std::cout;
class Node
{
public:
Node *prev;
Node *next;
int shares;
float pps;
Node(int vshares, float vpps)
{
shares = vshares;
pps = vpps;
prev = next = nullptr;
}
};
class dlist
{
public:
Node *head;
Node *tail;
dlist()
{
head = tail = nullptr;
}
~dlist()
{
destroy();
}
void push_back(int shares, float pps)
{
Node *node = new Node(shares, pps);
if (head == NULL)
{
head = tail = node;
}
else
{
tail->next = node;
node->prev = tail;
tail = node;
}
}
void destroy()
{
Node *walk = head;
while (walk)
{
Node *node = walk;
walk = walk->next;
delete node;
}
head = tail = nullptr;
}
};
class stack
{
public:
int maxsize;
int count;
dlist list;
stack(int size)
{
count = 0;
maxsize = size;
}
void push(int num, float price)
{
if (count < maxsize)
{
list.push_back(num, price);
count++;
}
}
void pop()
{
Node *tail = list.tail;
if (!tail)
{
//already empty
return;
}
if (tail == list.head)
{
//only one element in the list
delete tail;
list.head = list.tail = nullptr;
count--;
}
else
{
Node *temp = list.tail->prev;
delete list.tail;
list.tail = temp;
list.tail->next = nullptr;
count--;
}
}
void display()
{
Node *walk = list.head;
while (walk)
{
cout << "(" << walk->shares << "," << walk->pps << ") ";
walk = walk->next;
}
cout << "\n";
}
};
int main()
{
stack s(3);
s.push(101, 0.25f);
s.push(102, 0.25f);
s.push(103, 0.25f);
s.push(104, 0.25f);
s.display();
s.pop();
s.display();
return 0;
}