fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <array>
  4. #include <queue>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. struct MarketData
  10. {
  11. std::string _symbol;
  12. double _price;
  13. long long _qty;
  14. MarketData() {}
  15. MarketData(std::string symbol, double price, long long qty) {
  16. _symbol = symbol;
  17. _price = price;
  18. _qty = qty;
  19. }
  20. MarketData *next;
  21. };
  22.  
  23. class Processor;
  24.  
  25. template<typename T>
  26. class CustomQueue
  27. {
  28. friend class Processor;
  29. public:
  30. CustomQueue() : top(0){
  31. prcessingNode = head = tail = nullptr;
  32. }
  33. void Display()
  34. {
  35. MarketData *curr = tail;
  36. while(curr != nullptr /* || top > 0*/) {
  37. cout << curr->_symbol << "," << curr->_price << ", " << curr->_qty; //If I use templateT here, it will not work for generic data types.
  38. curr = curr->next; //OR top--;
  39. cout << "\n";
  40. }
  41. }
  42. void push(const T& value) {
  43. T *tempNode = new T(); //creates new memory
  44.  
  45. tempNode->_symbol = value._symbol; //copy the data
  46. tempNode->_price = value._price;
  47. tempNode->_qty = value._qty;
  48. if(top == 0) {
  49. tempNode->next = nullptr;
  50. head = tail = tempNode;
  51. ++top;
  52. }
  53. else {
  54. T *curr = tail;
  55. bool flag = false;
  56.  
  57. //Check if the element is duplicate
  58. while(curr != nullptr || curr != prcessingNode/* || top > 0*/) { //We have to checck till the processedNode
  59. if(curr->_symbol == tempNode->_symbol) {
  60. //Uppdate the price and quantity when element is found.
  61. curr->_price = tempNode->_price;
  62. curr->_qty = tempNode->_qty;
  63. flag = true;
  64. break;
  65. }
  66. curr = curr->next; //OR top--;
  67. }
  68. //If element is unique, then push it at the end
  69. if ( !flag ) {
  70. tempNode->next = tail;
  71. tail = tempNode;
  72. ++top;
  73. }
  74. }
  75. }
  76.  
  77. void push(T && value) {
  78. T *tempNode;
  79. if(top == 0) {
  80. tempNode = std::move(value); //Move the ownership as we are using rvalue reference
  81. tempNode->next = nullptr;
  82. head = tail = tempNode;
  83. ++top;
  84. }
  85. else {
  86. T *curr = tail;
  87. bool flag = false;
  88.  
  89. //Check if the element is duplicate
  90. while(curr->next != nullptr /* || top > 0*/) {
  91. if(curr->_symbol == tempNode->_symbol) {
  92. //Uppdate the price and quantity when element is found.
  93. curr->_price = tempNode->_price;
  94. curr->_qty = tempNode->_qty;
  95. flag = true;
  96. break;
  97. }
  98. curr = curr->next; //OR top--;
  99. }
  100. //If element is unique, then push it at the end
  101. if ( !flag ) {
  102. tempNode->next = tail;
  103. tail = tempNode;
  104. ++top;
  105. }
  106. }
  107. }
  108.  
  109. const T& front() {
  110. return *head;
  111. }
  112. void pop() {
  113. T *temp = tail;
  114. tail = tail->next;
  115. delete temp;
  116. --top;
  117. }
  118.  
  119. private:
  120. // feel free to add any number of member variables.
  121. T data;
  122. T *prcessingNode;
  123. T *head;
  124. T *tail;
  125. int top; //To keep track of max elements in queue
  126. };
  127.  
  128. class Processor //is a frined of CustomQueue
  129. {
  130. public:
  131. void process(const MarketData& queueElement, CustomQueue<MarketData> &other) {
  132. //Do the required processing
  133. MarketData *curr = other.tail;
  134.  
  135. //Make the prcessingNode to head, so it will check duplicates till prcessingNode while pushing elements.
  136. while(curr != nullptr/* || top > 0*/) { //We have to checck till the prcessingNode.
  137. if(curr->_symbol == queueElement._symbol) {
  138. //Make this node as prcessingNode.
  139. other.prcessingNode = curr;
  140. break;
  141. }
  142. curr = curr->next; //OR top--;
  143. }
  144. }
  145.  
  146. void getTop10Symbols(CustomQueue<MarketData> &other) {
  147. std::vector<MarketData*> vec(10);
  148. std::vector<MarketData*>::iterator itrmin;
  149. std::vector<MarketData*>::iterator itrmax;
  150.  
  151. //Accumulate the quantity in the queue
  152. MarketData *curr = other.tail;
  153. int count = 0;
  154. //Logic: first put the 10 elements and then check the new element's qty with min and max range.
  155. //If yes, put is inside the vector, else leave it.
  156. while(curr != nullptr/* || top > 0*/) { //We have to checck till the prcessingNode.
  157. if (count < 10) {
  158. vec[count++] = curr;
  159. }
  160. itrmin = min_element(vec.begin(), vec.end(), [](MarketData *node1, MarketData *node2) {return node1->_symbol < node2->_symbol;});
  161. itrmax = max_element(vec.begin(), vec.end(), [](MarketData *node1, MarketData *node2) {return node1->_symbol > node2->_symbol;});
  162.  
  163. if ((curr->_qty) > (*itrmax)->_qty) { //TC 1 : If next qty is more than max, update max element
  164. (*itrmax)->_qty = curr->_qty;
  165. }
  166. else if ( ((curr->_qty) > (*itrmin)->_qty) || ((curr->_qty) < (*itrmax)->_qty) ){ //TC 2 : If next qty is in the range, update min element
  167. (*itrmin)->_qty = curr->_qty;
  168. }
  169. else {
  170. //TC 3 : If next qty is beyond (OR equal to) the range, no need to update.
  171. }
  172.  
  173. curr = curr->next; //OR top--;
  174. }
  175. }
  176.  
  177. private:
  178. // feel free to add any number of member variables.
  179. };
  180.  
  181. int main() {
  182. // your code goes here
  183. CustomQueue<MarketData> obj;
  184. MarketData d1("Hi", 3, 4);
  185. MarketData d2("Hey", 4, 5);
  186. MarketData d3("Hello", 5, 6);
  187. MarketData d4("Hi", 5, 6);
  188. MarketData d5("Hello", 7, 8);
  189. obj.push(d1);
  190. obj.push(d2);
  191. obj.push(d3);
  192. obj.push(d4);
  193. obj.push(d5);
  194. obj.Display();
  195. return 0;
  196. }
  197.  
Success #stdin #stdout 0.01s 5512KB
stdin
Standard input is empty
stdout
Hello,7, 8
Hey,4, 5
Hi,5, 6