#include <iostream>
#include <memory>
#include <array>
#include <queue>
#include <algorithm>
using namespace std;
struct MarketData
{
std::string _symbol;
double _price;
long long _qty;
MarketData() {}
MarketData(std::string symbol, double price, long long qty) {
_symbol = symbol;
_price = price;
_qty = qty;
}
MarketData *next;
};
class Processor;
template<typename T>
class CustomQueue
{
friend class Processor;
public:
CustomQueue() : top(0){
prcessingNode = head = tail = nullptr;
}
void Display()
{
MarketData *curr = tail;
while(curr != nullptr /* || top > 0*/) {
cout << curr->_symbol << "," << curr->_price << ", " << curr->_qty; //If I use templateT here, it will not work for generic data types.
curr = curr->next; //OR top--;
cout << "\n";
}
}
void push(const T& value) {
T *tempNode = new T(); //creates new memory
tempNode->_symbol = value._symbol; //copy the data
tempNode->_price = value._price;
tempNode->_qty = value._qty;
if(top == 0) {
tempNode->next = nullptr;
head = tail = tempNode;
++top;
}
else {
T *curr = tail;
bool flag = false;
//Check if the element is duplicate
while(curr != nullptr || curr != prcessingNode/* || top > 0*/) { //We have to checck till the processedNode
if(curr->_symbol == tempNode->_symbol) {
//Uppdate the price and quantity when element is found.
curr->_price = tempNode->_price;
curr->_qty = tempNode->_qty;
flag = true;
break;
}
curr = curr->next; //OR top--;
}
//If element is unique, then push it at the end
if ( !flag ) {
tempNode->next = tail;
tail = tempNode;
++top;
}
}
}
void push(T && value) {
T *tempNode;
if(top == 0) {
tempNode = std::move(value); //Move the ownership as we are using rvalue reference
tempNode->next = nullptr;
head = tail = tempNode;
++top;
}
else {
T *curr = tail;
bool flag = false;
//Check if the element is duplicate
while(curr->next != nullptr /* || top > 0*/) {
if(curr->_symbol == tempNode->_symbol) {
//Uppdate the price and quantity when element is found.
curr->_price = tempNode->_price;
curr->_qty = tempNode->_qty;
flag = true;
break;
}
curr = curr->next; //OR top--;
}
//If element is unique, then push it at the end
if ( !flag ) {
tempNode->next = tail;
tail = tempNode;
++top;
}
}
}
const T& front() {
return *head;
}
void pop() {
T *temp = tail;
tail = tail->next;
delete temp;
--top;
}
private:
// feel free to add any number of member variables.
T data;
T *prcessingNode;
T *head;
T *tail;
int top; //To keep track of max elements in queue
};
class Processor //is a frined of CustomQueue
{
public:
void process(const MarketData& queueElement, CustomQueue<MarketData> &other) {
//Do the required processing
MarketData *curr = other.tail;
//Make the prcessingNode to head, so it will check duplicates till prcessingNode while pushing elements.
while(curr != nullptr/* || top > 0*/) { //We have to checck till the prcessingNode.
if(curr->_symbol == queueElement._symbol) {
//Make this node as prcessingNode.
other.prcessingNode = curr;
break;
}
curr = curr->next; //OR top--;
}
}
void getTop10Symbols(CustomQueue<MarketData> &other) {
std::vector<MarketData*> vec(10);
std::vector<MarketData*>::iterator itrmin;
std::vector<MarketData*>::iterator itrmax;
//Accumulate the quantity in the queue
MarketData *curr = other.tail;
int count = 0;
//Logic: first put the 10 elements and then check the new element's qty with min and max range.
//If yes, put is inside the vector, else leave it.
while(curr != nullptr/* || top > 0*/) { //We have to checck till the prcessingNode.
if (count < 10) {
vec[count++] = curr;
}
itrmin = min_element(vec.begin(), vec.end(), [](MarketData *node1, MarketData *node2) {return node1->_symbol < node2->_symbol;});
itrmax = max_element(vec.begin(), vec.end(), [](MarketData *node1, MarketData *node2) {return node1->_symbol > node2->_symbol;});
if ((curr->_qty) > (*itrmax)->_qty) { //TC 1 : If next qty is more than max, update max element
(*itrmax)->_qty = curr->_qty;
}
else if ( ((curr->_qty) > (*itrmin)->_qty) || ((curr->_qty) < (*itrmax)->_qty) ){ //TC 2 : If next qty is in the range, update min element
(*itrmin)->_qty = curr->_qty;
}
else {
//TC 3 : If next qty is beyond (OR equal to) the range, no need to update.
}
curr = curr->next; //OR top--;
}
}
private:
// feel free to add any number of member variables.
};
int main() {
// your code goes here
CustomQueue<MarketData> obj;
MarketData d1("Hi", 3, 4);
MarketData d2("Hey", 4, 5);
MarketData d3("Hello", 5, 6);
MarketData d4("Hi", 5, 6);
MarketData d5("Hello", 7, 8);
obj.push(d1);
obj.push(d2);
obj.push(d3);
obj.push(d4);
obj.push(d5);
obj.Display();
return 0;
}